{"record":{"id":"377c3a720eac5510","repo":"datawhalechina/hello-agents","slug":"tool-name-377c3a","errorCode":null,"errorMessage":"工具未定义: {tool_name}.","messagePattern":"工具未定义: (.+?)\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"warning","filePath":"Co-creation-projects/BitSecret-GPSAgent/src/gps/agent_loop.py","lineNumber":189,"sourceCode":"                try:  # tool calls\n                    tool_name, args = parse_response(response)\n                    if tool_name == 'apply':\n                        tool_call = '工具执行结果：\\n' + solver.apply(args)\n                    elif tool_name == 'decompose':\n                        tool_call = '工具执行结果：\\n' + solver.decompose(args)\n                    elif tool_name == 'find_fact':\n                        tool_call = '工具执行结果：\\n' + solver.find_fact(args)\n                    elif tool_name == 'find_goal':\n                        tool_call = '工具执行结果：\\n' + solver.find_goal(args)\n                    elif tool_name == 'check':\n                        tool_call = '工具执行结果：\\n' + solver.check()\n                    elif tool_name == 'summarize':\n                        agent.summarize(solver.state(), args)\n                        continue\n                    elif tool_name == 'finish':\n                        break\n                    else:\n                        raise Exception(f'工具未定义: {tool_name}.')\n                except Exception as e:\n                    tool_call = f\"调用工具时发生错误：{repr(e)}\"\n\n                agent.add_memory(role='user', content=tool_call)\n\n                if solver.status_of_goal[0] == 1:\n                    agent.add_memory(role='user', content='检测到问题已求解，自动结束。')\n                    break\n\n                if agent.context_length > max_context:\n                    agent.add_memory(role='user', content=get_summarize_prompt())\n\n        except KeyboardInterrupt:\n            agent.add_memory(role='user', content=\"用户主动介入中断（KeyboardInterrupt）。\")\n\n        if solver.status_of_goal[0] == 1:\n            result = 'solved'\n            agent.add_memory(role='user', content=\"求解结束：成功✅\")","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/BitSecret-GPSAgent/src/gps/agent_loop.py#L171-L207","documentation":"A generic Exception raised in the GPSAgent agent loop (src/gps/agent_loop.py) when the LLM's tool call names a tool outside the dispatch table. The loop explicitly matches tool_name against 'find_fact', 'find_goal', 'check', 'summarize', and 'finish'; anything else hits the else branch. Importantly, the loop immediately catches this exception and converts it to the string '调用工具时发生错误：...' added to conversation memory, so the agent usually self-corrects on the next turn rather than crashing.","triggerScenarios":"The model outputs a function/tool name such as 'search', 'find_fact(' with a typo, or a hallucinated tool like 'solve' in its tool-call response. Causes: system prompt not listing the exact tool names, model not adhering to the schema, or the temperature/prompt causing creative tool invention. The error is swallowed into memory, so it manifests as a corrective user-role message in the transcript.","commonSituations":"Switching to a weaker model that invents tool names; renaming a tool in the solver without updating the prompt's tool list; few-shot examples referencing removed tools; locale/tokenization quirks producing tool names with trailing whitespace or parentheses.","solutions":["Make the system prompt enumerate the exact allowed tool names ('find_fact', 'find_goal', 'check', 'summarize', 'finish') and state that other names are invalid","Normalize tool_name before dispatch: strip whitespace and parentheses (tool_name.strip())","Lower temperature or use a model with reliable function-calling to reduce hallucinated names","Log unknown tool names with the raw model output to identify prompt gaps","If a new tool is intended, add an elif branch for it in the dispatch chain"],"exampleFix":"# before\nelse:\n    raise Exception(f'工具未定义: {tool_name}.')\n\n# after\ntool_name = tool_name.strip()\nif tool_name not in {'find_fact', 'find_goal', 'check', 'summarize', 'finish'}:\n    agent.add_memory(role='user', content=f'未知工具 {tool_name}，可用工具: find_fact, find_goal, check, summarize, finish')\n    continue","handlingStrategy":"validation","validationCode":"ALLOWED_TOOLS = {'find_fact', 'find_goal', 'check', 'summarize', 'finish'}\ntool_name = raw_tool_name.strip().strip('()')\nif tool_name not in ALLOWED_TOOLS:\n    # do not dispatch; feed corrective feedback to the model instead\n    feedback = f'未知工具 {tool_name}。可用工具: {sorted(ALLOWED_TOOLS)}'","typeGuard":"def is_known_tool(name: str) -> bool:\n    return isinstance(name, str) and name.strip() in {\n        'find_fact', 'find_goal', 'check', 'summarize', 'finish'\n    }","tryCatchPattern":"try:\n    dispatch(tool_name, args)\nexcept Exception as e:\n    # the loop already converts this to a memory message; keep that pattern:\n    agent.add_memory(role='user', content=f'调用工具时发生错误：{repr(e)}，请仅使用: {ALLOWED_TOOLS}')\n    continue","preventionTips":["List exact tool names in the system prompt and forbid invention","Strip whitespace/parens from parsed tool names before matching","Log every unknown-tool event with the raw model output to find prompt gaps","Prefer models with native function calling over free-text tool emission"],"tags":["agent","llm","tool-calling","validation","prompt-engineering"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}