OhBrian commited on
Commit
6b261f5
·
1 Parent(s): e7e1e90

更新了直接回答情况下的文本返回格式

Browse files
Files changed (2) hide show
  1. agent.py +5 -1
  2. tools/llm_client.py +64 -9
agent.py CHANGED
@@ -23,6 +23,8 @@ Rules:
23
  7. To finish, output:
24
  {"thought":"...","action":"final_answer","answer":"...","confidence":"high|medium|low"}
25
  8. Final answers must obey the requested format exactly. Do not include explanations.
 
 
26
  """.strip()
27
 
28
 
@@ -157,7 +159,9 @@ class GaiaAgent:
157
  + tool_prompt()
158
  + "\n\nTask:\n"
159
  + json.dumps(task_payload, ensure_ascii=False)
160
- + "\n\nChoose the first tool call or return final_answer. Output JSON only."
 
 
161
  )
162
  return [
163
  {"role": "system", "content": SYSTEM_PROMPT},
 
23
  7. To finish, output:
24
  {"thought":"...","action":"final_answer","answer":"...","confidence":"high|medium|low"}
25
  8. Final answers must obey the requested format exactly. Do not include explanations.
26
+ 9. Never answer in plain text. Even if the answer is obvious, return JSON.
27
+ 10. For self-contained text/table/regex/list questions, call direct_answer_tool first.
28
  """.strip()
29
 
30
 
 
159
  + tool_prompt()
160
  + "\n\nTask:\n"
161
  + json.dumps(task_payload, ensure_ascii=False)
162
+ + "\n\nChoose the first tool call or return final_answer. Output JSON only.\n"
163
+ + "Example tool call: {\"thought\":\"self-contained rule question\",\"action\":\"direct_answer_tool\",\"args\":{}}\n"
164
+ + "Example final answer: {\"thought\":\"tool returned the answer\",\"action\":\"final_answer\",\"answer\":\"right\",\"confidence\":\"high\"}"
165
  )
166
  return [
167
  {"role": "system", "content": SYSTEM_PROMPT},
tools/llm_client.py CHANGED
@@ -27,23 +27,28 @@ def call_hf_chat(
27
  model: str = HF_TEXT_MODEL,
28
  max_tokens: int = 512,
29
  temperature: float = 0.1,
 
30
  ) -> str:
31
  token = get_hf_token()
32
  if not token:
33
  raise RuntimeError("未配置 HF_TOKEN。")
34
 
 
 
 
 
 
 
 
 
 
35
  response = requests.post(
36
  HF_ROUTER_URL,
37
  headers={
38
  "Authorization": f"Bearer {token}",
39
  "Content-Type": "application/json",
40
  },
41
- json={
42
- "model": model,
43
- "messages": messages,
44
- "temperature": temperature,
45
- "max_tokens": max_tokens,
46
- },
47
  timeout=180,
48
  )
49
  if not response.ok:
@@ -51,7 +56,10 @@ def call_hf_chat(
51
  f"HF chat 请求失败:status={response.status_code}, body={response.text[:500]}"
52
  )
53
  data = response.json()
54
- return data["choices"][0]["message"]["content"]
 
 
 
55
 
56
 
57
  def extract_json_object(text: str) -> dict[str, Any]:
@@ -94,9 +102,56 @@ def parse_agent_action(text: str) -> AgentAction:
94
  )
95
 
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  def plan_next_action(messages: list[dict[str, Any]]) -> AgentAction:
98
- raw = call_hf_chat(messages, max_tokens=700, temperature=0.0)
99
- return parse_agent_action(raw)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
 
102
  def answer_with_light_model(question: str, evidence: str) -> str:
 
27
  model: str = HF_TEXT_MODEL,
28
  max_tokens: int = 512,
29
  temperature: float = 0.1,
30
+ response_format: dict[str, Any] | None = None,
31
  ) -> str:
32
  token = get_hf_token()
33
  if not token:
34
  raise RuntimeError("未配置 HF_TOKEN。")
35
 
36
+ payload: dict[str, Any] = {
37
+ "model": model,
38
+ "messages": messages,
39
+ "temperature": temperature,
40
+ "max_tokens": max_tokens,
41
+ }
42
+ if response_format:
43
+ payload["response_format"] = response_format
44
+
45
  response = requests.post(
46
  HF_ROUTER_URL,
47
  headers={
48
  "Authorization": f"Bearer {token}",
49
  "Content-Type": "application/json",
50
  },
51
+ json=payload,
 
 
 
 
 
52
  timeout=180,
53
  )
54
  if not response.ok:
 
56
  f"HF chat 请求失败:status={response.status_code}, body={response.text[:500]}"
57
  )
58
  data = response.json()
59
+ content = data["choices"][0]["message"].get("content")
60
+ if content is None:
61
+ return ""
62
+ return content
63
 
64
 
65
  def extract_json_object(text: str) -> dict[str, Any]:
 
102
  )
103
 
104
 
105
+ def call_planner_model(messages: list[dict[str, Any]]) -> str:
106
+ try:
107
+ return call_hf_chat(
108
+ messages,
109
+ max_tokens=700,
110
+ temperature=0.0,
111
+ response_format={"type": "json_object"},
112
+ )
113
+ except RuntimeError as exc:
114
+ error_text = str(exc).lower()
115
+ if "response_format" not in error_text and "json_object" not in error_text:
116
+ raise
117
+ return call_hf_chat(
118
+ messages,
119
+ max_tokens=700,
120
+ temperature=0.0,
121
+ )
122
+
123
+
124
  def plan_next_action(messages: list[dict[str, Any]]) -> AgentAction:
125
+ raw = call_planner_model(messages)
126
+ try:
127
+ return parse_agent_action(raw)
128
+ except Exception as first_error:
129
+ repair_messages = messages + [
130
+ {
131
+ "role": "assistant",
132
+ "content": raw or "<empty response>",
133
+ },
134
+ {
135
+ "role": "user",
136
+ "content": (
137
+ "Your previous response was invalid because it was not one JSON object. "
138
+ "Return exactly one JSON object now, with no markdown and no prose. "
139
+ "Valid tool-call schema: "
140
+ "{\"thought\":\"...\",\"action\":\"tool_name\",\"args\":{}}. "
141
+ "Valid final-answer schema: "
142
+ "{\"thought\":\"...\",\"action\":\"final_answer\",\"answer\":\"...\",\"confidence\":\"high|medium|low\"}."
143
+ ),
144
+ },
145
+ ]
146
+ repaired_raw = call_planner_model(repair_messages)
147
+ try:
148
+ return parse_agent_action(repaired_raw)
149
+ except Exception as second_error:
150
+ raise ValueError(
151
+ "planner 连续两次没有输出合法 JSON。"
152
+ f" first_error={first_error}; first_raw={raw[:300]!r};"
153
+ f" second_error={second_error}; second_raw={repaired_raw[:300]!r}"
154
+ ) from second_error
155
 
156
 
157
  def answer_with_light_model(question: str, evidence: str) -> str: