AlexTrinityBlock commited on
Commit
da8c40b
·
1 Parent(s): b70637a

feat(agent): add answer extraction module and integrate into run function

Browse files

Add new answer_extractor module that processes agent responses to extract clean answers.
Refactor main entry point to use the simplified run() function instead of interactive loop.

Files changed (2) hide show
  1. agent/agent.py +19 -15
  2. agent/agents/answer_extractor.py +84 -0
agent/agent.py CHANGED
@@ -7,6 +7,7 @@ from agent.tools.math_solver import math_solver
7
 
8
  from agent.agents.websearchagents import web_search_agents
9
  from agent.agents.websearchagent import websearch_agent
 
10
 
11
  load_dotenv()
12
 
@@ -35,21 +36,24 @@ def run(query: str) -> str:
35
  result = agent.invoke({"messages": [HumanMessage(content=query)]})
36
  content = result["messages"][-1].content
37
  if isinstance(content, list):
38
- return content[0].get("text", "")
39
- return str(content)
 
 
40
 
41
 
42
  if __name__ == "__main__":
43
- agent = supervisor_agent()
44
- chat_history: list = []
45
- while True:
46
- query = input("\nYou: ")
47
- if query.lower() in ("exit", "quit"):
48
- break
49
- chat_history.append(HumanMessage(content=query))
50
- result = agent.invoke({"messages": chat_history})
51
- chat_history = result["messages"]
52
- content = chat_history[-1].content
53
- if isinstance(content, list):
54
- content = content[0].get("text", "")
55
- print(f"Agent: {content}")
 
 
7
 
8
  from agent.agents.websearchagents import web_search_agents
9
  from agent.agents.websearchagent import websearch_agent
10
+ from agent.agents.answer_extractor import extract_answer
11
 
12
  load_dotenv()
13
 
 
36
  result = agent.invoke({"messages": [HumanMessage(content=query)]})
37
  content = result["messages"][-1].content
38
  if isinstance(content, list):
39
+ content = content[0].get("text", "")
40
+ else:
41
+ content = str(content)
42
+ return extract_answer(content, query)
43
 
44
 
45
  if __name__ == "__main__":
46
+ run(input("Query:"))
47
+ # agent = supervisor_agent()
48
+ # chat_history: list = []
49
+ # while True:
50
+ # query = input("\nYou: ")
51
+ # if query.lower() in ("exit", "quit"):
52
+ # break
53
+ # chat_history.append(HumanMessage(content=query))
54
+ # result = agent.invoke({"messages": chat_history})
55
+ # chat_history = result["messages"]
56
+ # content = chat_history[-1].content
57
+ # if isinstance(content, list):
58
+ # content = content[0].get("text", "")
59
+ # print(f"Agent: {content}")
agent/agents/answer_extractor.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from colorama import Fore, Style # type: ignore[import]
2
+ from langchain.agents import create_agent
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class ExtractedAnswer(BaseModel):
7
+ """Structured output for answer extraction."""
8
+
9
+ extract_process_description: str = Field(
10
+ description="Description of the extraction process and reasoning."
11
+ )
12
+ answer: str = Field(
13
+ description="The pure, concise answer without any extra text or spaces."
14
+ )
15
+
16
+
17
+ def extract_answer(raw_answer: str, question: str) -> str:
18
+ """Extract a concise, plain-text answer from a verbose agent response."""
19
+ print(f"{Fore.CYAN}[AnswerExtractor] Extracting...{Style.RESET_ALL}")
20
+
21
+ agent = create_agent(
22
+ model="google_genai:gemini-3-flash-preview",
23
+ response_format=ExtractedAnswer,
24
+ system_prompt="""\
25
+ You are part of a system that demands extreme precision.
26
+ Your job is to extract the pure answer from a verbose agent response.
27
+ The answer field must contain ONLY the answer itself —
28
+ no extra description, no explanation, no units unless explicitly required,
29
+ no leading or trailing whitespace, no punctuation beyond what is part of the answer.
30
+ Do NOT add any surrounding text. Do NOT pad with spaces.
31
+
32
+ ```example
33
+ Input:
34
+ '... the answer is 114. Thank.'
35
+
36
+ Output:
37
+ '114'
38
+ ```
39
+
40
+ ```example
41
+ Input:
42
+ '... Serial number is BC34ACD2 and ...'
43
+
44
+ Output:
45
+ 'BC34ACD2'
46
+ ```
47
+
48
+ ```example
49
+ Input:
50
+ 'Result is 6, 7, 1, 10'
51
+
52
+ Output:
53
+ '6, 7, 1, 10'
54
+ ```
55
+
56
+ ```example
57
+ Input:
58
+ 'Answer is 73!'
59
+
60
+ Output:
61
+ '73'
62
+ ```
63
+
64
+ """,
65
+ )
66
+
67
+ result = agent.invoke(
68
+ {
69
+ "messages": [
70
+ {
71
+ "role": "user",
72
+ "content": (
73
+ f"Question: {question}\n\nAgent's verbose answer:\n{raw_answer}"
74
+ ),
75
+ }
76
+ ]
77
+ }
78
+ )
79
+ extracted: ExtractedAnswer = result["structured_response"]
80
+ print(
81
+ f"{Fore.CYAN}[AnswerExtractor] Process: {extracted.extract_process_description}{Style.RESET_ALL}"
82
+ )
83
+ print(f"{Fore.CYAN}[AnswerExtractor] Answer: {extracted.answer}{Style.RESET_ALL}")
84
+ return extracted.answer