datawhalechina/hello-agents · error · AgentException
工具 '{tool_name}' 不存在
Error message
工具 '{tool_name}' 不存在 What it means
BaseAgent.call_tool looks up tool_name in self.tools (populated via add_tool); an unknown name raises AgentException('工具 ... 不存在'). It is a registry lookup failure — the agent attempted to invoke a tool that was never registered on this instance.
Source
Thrown at Co-creation-projects/Shawnxyxy-HealthRecordAgent/backend/agents/base.py:168
"function": tool_func,
"description": description
}
def get_tools_description(self) -> str:
"""获取工具描述"""
if not self.tools:
return "暂无可用工具"
descriptions = []
for name, tool_info in self.tools.items():
descriptions.append(f"- {name}: {tool_info['description']}")
return "\n".join(descriptions)
async def call_tool(self, tool_name: str, tool_input: Any) -> Any:
"""调用工具"""
if tool_name not in self.tools:
raise AgentException(f"工具 '{tool_name}' 不存在")
try:
tool_func = self.tools[tool_name]["function"]
if asyncio.iscoroutinefunction(tool_func):
result = await asyncio.wait_for(
tool_func(tool_input),
timeout=self.timeout
)
else:
result = await asyncio.wait_for(
asyncio.to_thread(tool_func, tool_input),
timeout=self.timeout
)
self._add_to_history(f"Tool {tool_name} called with input: {tool_input}")
self._add_to_history(f"Tool {tool_name} result: {result}")
return resultView on GitHub (pinned to 606a07d341)
Solutions
- Register the tool before use: agent.add_tool('name', func, description).
- Constrain the model to the registered list — feed it get_tools_description() output verbatim.
- On AgentException with '不存在', re-prompt the model with the available tool list instead of crashing.
Example fix
# before
result = await agent.call_tool('search_drugs', q) # never registered
# after
agent.add_tool('search_drugs', search_drugs, '查询药品信息')
result = await agent.call_tool('search_drugs', q)
# defensive: allowed = set(agent.tools) Defensive patterns
Strategy: validation
Validate before calling
def tool_exists(agent, name):
return name in agent.tools
if not tool_exists(agent, tool_name):
raise KeyError(f'{tool_name} not registered; have: {sorted(agent.tools)}') Try / catch
try:
r = await agent.call_tool(name, tool_input)
except AgentException as e:
if '不存在' in str(e):
r = f'tool {name} not available; valid: {sorted(agent.tools)}' # feed back to LLM Prevention
- Register all tools in the agent's __init__ so the registry is complete before any LLM turn.
- Give the model get_tools_description() output verbatim in the system prompt.
- On lookup failure, reply to the LLM with the valid tool list so it self-corrects.
When it happens
Trigger: LLM emitting a tool name that is not in get_tools_description(); calling agent.call_tool('search_drug', ...) when only 'drug_search' was registered via add_tool; instantiating a fresh agent and calling a tool its subclass never registers.
Common situations: Hallucinated or renamed tool names from the model; tools registered conditionally (only if an API key exists) so the name disappears in some environments; prompt tool lists drifting out of sync with registrations.
Related errors
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/934ef38188f79b03.
Report an issue: GitHub.