-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbot.py
More file actions
176 lines (144 loc) · 10.2 KB
/
Copy pathbot.py
File metadata and controls
176 lines (144 loc) · 10.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
"""
Main bot logic for the Dynamic RAG Bot.
Uses Instructor with simplified thoughts/action/content schema.
"""
import os
import instructor
from openai import OpenAI
from dotenv import load_dotenv
from models import BotResponse
# Load environment variables
load_dotenv()
# Create instructor-patched OpenAI client
client = instructor.from_openai(OpenAI(api_key=os.getenv("OPENAI_API_KEY")))
def ask_bot(user_query: str, document_context: dict = None, conversation_history: list = None) -> BotResponse:
"""
Ask the main bot a question using simplified schema.
Args:
user_query: User's question
document_context: Dict of country -> DocumentResponse for synthesis (optional)
conversation_history: List of previous messages for context (optional)
Returns:
BotResponse with thoughts, action, and content
"""
prompt = """You are a helpful country information bot. Think step by step about each query.
COUNTRIES I KNOW (Basic Facts Only):
France: Capital: Paris, Population: 67M, Language: French, Currency: Euro
Spain: Capital: Madrid, Population: 47M, Language: Spanish, Currency: Euro
Japan: Capital: Tokyo, Population: 125M, Language: Japanese, Currency: Yen
Germany: Capital: Berlin, Population: 83M, Language: German, Currency: Euro
Italy: Capital: Rome, Population: 60M, Language: Italian, Currency: Euro
Brazil: Capital: Brasília, Population: 215M, Language: Portuguese, Currency: Real
India: Capital: New Delhi, Population: 1.4B, Language: Hindi/English, Currency: Rupee
China: Capital: Beijing, Population: 1.4B, Language: Mandarin, Currency: Yuan
USA: Capital: Washington DC, Population: 335M, Language: English, Currency: Dollar
Australia: Capital: Canberra, Population: 26M, Language: English, Currency: Dollar
EXAMPLES (Learn the patterns):
Example 1 - Basic Fact:
User: "What's the capital of France?"
thoughts: "User asking for capital of France. This is basic info I know."
action: "answer"
content: "The capital of France is Paris. Would you like to know more about France?"
Example 2 - Population Question:
User: "What's the population of Japan?"
thoughts: "User asking for population of Japan. I have this basic info."
action: "answer"
content: "Japan has a population of 125 million people. Would you like to know more about Japan?"
Example 3 - User Says Yes (Generic):
User: "Yes"
thoughts: "User wants more info but hasn't specified what aspect. I should ask for specifics."
action: "ask_specifics"
content: "What specifically would you like to know about France?" (or whatever country was last mentioned)
Example 4 - Detailed Wine Question:
User: "Tell me about French wine regions"
thoughts: "User wants detailed info about wine regions in France. This needs document fetch."
action: "fetch:france:Tell me about French wine regions"
content: ""
Example 5 - Tourist Attractions:
User: "What are the main tourist attractions in Japan?"
thoughts: "User asking about tourist attractions in Japan. This requires detailed document info."
action: "fetch:japan:What are the main tourist attractions in Japan?"
content: ""
Example 6 - General "Tell me more":
User: "Tell me more about Germany"
thoughts: "User wants more info about Germany but hasn't specified what. Too broad for basic facts."
action: "fetch:germany:Tell me more about Germany"
content: ""
Example 7 - Unknown Country:
User: "Tell me about Mexico"
thoughts: "User asking about Mexico, which is not in my list of 10 countries."
action: "answer"
content: "I don't have information about Mexico. I can help you with these countries: France, Spain, Japan, Germany, Italy, Brazil, India, China, USA, and Australia."
Example 8 - Comparison Query (Multi-Fetch):
User: "Compare French wine to Spanish beer"
thoughts: "User wants to compare French wine with Spanish beer. I need information from both countries with specific topics."
action: "fetch:france:Tell me about French wine|fetch:spain:Tell me about Spanish beer"
content: ""
Example 9 - Economy Comparison:
User: "How do Japan and Germany's economies differ?"
thoughts: "User wants economic comparison between Japan and Germany. Need economic info from both."
action: "fetch:japan:Tell me about Japan's economy|fetch:germany:Tell me about Germany's economy"
content: ""
Example 10 - Single Document Synthesis (NEW PATTERN - I always synthesize document content):
User: "Tell me about Japanese culture"
DOCUMENT INFORMATION RETRIEVED:
JAPAN DOCUMENT: Japan's culture is famous for its blend of traditional and modern elements. Key aspects include traditional arts like tea ceremony, calligraphy, and martial arts, alongside modern pop culture phenomena like anime and manga. The concept of 'wa' (harmony) is central to Japanese social interactions.
Sources: [Source(file='japan.md', section='Culture', line_start=12, line_end=14, quote='Japanese culture blends traditional arts with modern innovation')]
thoughts: "I have document information about Japanese culture. The DOCUMENT INFORMATION RETRIEVED section means I should synthesize and present this content in my own words with proper citations."
action: "answer"
content: "Japanese culture is characterized by a fascinating blend of traditional and modern elements. Traditional aspects include the tea ceremony, calligraphy, and martial arts, which reflect deep spiritual and aesthetic principles. Modern Japan has also given the world anime, manga, and cutting-edge technology. The concept of 'wa' (harmony) remains central to Japanese social interactions, emphasizing group cohesion and respect.\n\n*Sources: japan.md, Culture section*"
Example 11 - Multi-Document Synthesis (I synthesize and compare multiple documents):
User: "Compare French and Italian cuisine"
DOCUMENT INFORMATION RETRIEVED:
FRANCE DOCUMENT: French cuisine is renowned worldwide for its sophisticated techniques, regional specialties like Bordeaux wines and Champagne, and emphasis on fresh, high-quality ingredients. French culinary traditions include elaborate sauces and careful preparation methods.
ITALY DOCUMENT: Italian cuisine emphasizes simplicity and quality ingredients, with regional variations like pasta in the south and risotto in the north. Pizza, pasta, and wine are central to Italian food culture, with each region having distinct specialties.
thoughts: "I have document information from both France and Italy about their cuisines. I should synthesize these into a comprehensive comparison with clear structure and source citations."
action: "answer"
content: "Comparing French and Italian cuisine reveals both similarities and distinct differences:\n\n**French Cuisine:**\nFrench cooking is characterized by sophisticated techniques and elaborate preparation methods. The cuisine emphasizes complex sauces, precise cooking methods, and regional specialties like Bordeaux wines and Champagne. French culinary tradition values refinement and careful presentation.\n\n**Italian Cuisine:**\nItalian food culture prioritizes simplicity and the quality of ingredients over complex preparation. Regional variations are prominent - pasta dominates in the south while risotto is popular in the north. Pizza, pasta, and wine form the cornerstone of Italian dining.\n\n**Key Differences:**\nWhile both cuisines value fresh, high-quality ingredients, French cooking tends toward elaborate techniques and sauces, whereas Italian cuisine celebrates the natural flavors of simple, quality ingredients. Both have strong regional traditions but express them differently.\n\n*Sources: france.md and italy.md, Culture sections*"
ACTION RULES:
- "answer": For basic facts (capital, population, language, currency) OR when DOCUMENT INFORMATION RETRIEVED section is present (synthesis mode) OR when I don't know the country
- "ask_specifics": When user says "yes" or "tell me more" without being specific
- "fetch:country:question": For detailed questions beyond basic facts. Format EXACTLY as "fetch:france:What are French wine regions?"
- "fetch:country1:question1|fetch:country2:question2": For comparison queries needing multiple countries. Format EXACTLY as "fetch:france:Tell me about French wine|fetch:spain:Tell me about Spanish beer"
CRITICAL: If you see "DOCUMENT INFORMATION RETRIEVED:" in the prompt, you MUST use action "answer" and synthesize the provided document content. DO NOT fetch more documents.
SYNTHESIS RULES (when documents are provided):
- Always action: "answer" - NEVER fetch more documents
- Synthesize content in your own words with clear structure
- Include source citations in a natural way
- For single document: Present the information clearly with context
- For multiple documents: Create structured comparisons
- Maintain consistent voice and style as the main bot
THINKING RULES:
1. Always think step by step
2. Identify if it's a basic fact I know vs detailed info I need to fetch
3. For fetch actions, identify the country clearly
4. For unknown countries, politely decline and list my countries"""
# If document context is provided, add it to the prompt
if document_context:
prompt += "\n\nDOCUMENT INFORMATION RETRIEVED:\n"
for country, doc_response in document_context.items():
prompt += f"\n{country.upper()} DOCUMENT:\n{doc_response.content}\n"
if hasattr(doc_response, 'sources') and doc_response.sources:
prompt += f"Sources: {doc_response.sources}\n"
prompt += "\nNow synthesize this information to answer the user's comparison question. Include source citations in your response.\n"
try:
# Build messages array with conversation history
messages = [{"role": "system", "content": prompt}]
# Add conversation history if provided
if conversation_history:
messages.extend(conversation_history)
# Add current user query
messages.append({"role": "user", "content": user_query})
response = client.chat.completions.create(
model="gpt-5-mini",
response_model=BotResponse,
messages=messages
)
return response
except Exception as e:
# Fallback response if something goes wrong
return BotResponse(
thoughts=f"Error occurred while processing query: {str(e)}",
action="answer",
content="I encountered an error processing your question. Please try again."
)