Assume these are correctly implemented and available:
llm(prompt, system) -> str # calls an LLM, returns text
parse_action(text) -> (name, input) | None
parse_final_answer(text) -> str | None
build_system_prompt() -> str
TOOLS: dict[str, Callable] # {"calculator": fn, "lookup": fn}
Implement the following class:
class ReactAgent:
def __init__(self, max_iterations: int = 10):
self.max_iterations = max_iterations
self.scratchpad: list[str] = []
def _build_prompt(self, question: str) -> str:
history = "\n".join(self.scratchpad)
return f"Question: {question}\n\n{history}"
def run(self, question: str) -> str:
system = build_system_prompt()
for step in range(self.max_iterations):
prompt = self._build_prompt(question)
response = llm(prompt, system=system)
self.scratchpad.append(response)
action = parse_action(response)
if action is not None:
tool_name, tool_input = action
observation = TOOLS[tool_name](tool_input)
continue
final = parse_final_answer(response)
if final:
return final
self.scratchpad.append("Observation: Could not parse an action or final answer. Please try again.")
return "Agent stopped: max iterations reached."
if __name__ == "__main__":
agent = ReactAgent()
answer = agent.run("What year was Python created, and what is 123 * 456?")
Your task is to complete the agent logic so it can iteratively call tools, maintain a scratchpad, detect a final answer, and stop gracefully when the maximum number of iterations is reached.
这道题考察的是 ReAct 风格智能体的核心执行流程:每轮先把问题和历史 scratchpad 组装成 prompt,交给 LLM 生成响应;如果响应中能解析出工具调用,就从 TOOLS 字典里找到对应函数并执行,然后继续下一轮;如果能解析出最终答案,就立即返回;如果两者都不是,则把“无法解析”的观察信息写回 scratchpad,让模型重新尝试。题目重点在于状态管理、工具路由、循环控制和失败兜底,适合用字符串解析、字典映射与迭代循环来实现。