datawhalechina/hello-agents · error · AgentException

工具 '{tool_name}' 执行失败: {str(e)}

Error message

工具 '{tool_name}' 执行失败: {str(e)}

What it means

Generic AgentException wrapper from BaseAgent.call_tool: any exception escaping the tool body other than asyncio.TimeoutError (which is caught first as error 44) is re-raised with the tool name and the original message appended. This is a lossy re-wrap — it chains no __cause__, so tracebacks of the original failure are harder to read, and known error types (ExternalAPIException from hunter tools) surface through it.

Source

Thrown at Co-creation-projects/Apricity-InnocoreAI/agents/base.py:84

                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 result
            
        except asyncio.TimeoutError:
            raise TimeoutException(f"工具 '{tool_name}' 执行超时")
        except Exception as e:
            raise AgentException(f"工具 '{tool_name}' 执行失败: {str(e)}")
    
    async def think(self, prompt: str, context: Dict = None) -> str:
        """调用LLM进行思考"""
        try:
            # 构建完整的提示词
            full_prompt = prompt
            
            # 添加上下文信息
            if context:
                context_str = json.dumps(context, ensure_ascii=False, indent=2)
                full_prompt = f"上下文信息:\n{context_str}\n\n任务:\n{prompt}"
            
            # 添加历史记录
            if self.history:
                history_str = "\n".join(self.history[-10:])  # 只保留最近10条
                full_prompt += f"\n\n历史记录:\n{history_str}"
            
            # 调用 HelloAgent LLM

View on GitHub (pinned to 606a07d341)

Solutions

  1. Read the suffix after '执行失败:' — it carries the original exception text, which is the real diagnosis.
  2. Fix the root cause in the tool (schema-validate tool_input, guard entry.get(...) instead of attribute access).
  3. Re-raise with raise ... from e in call_tool to preserve the traceback chain for debugging.
  4. Add targeted excepts above the generic one (ExternalAPIException, ValueError) to keep typed errors typed end-to-end.
  5. Cover tools with unit tests passing minimal valid input to catch schema mismatches early.

Example fix

# before
except Exception as e:
    raise AgentException(f"工具 '{tool_name}' 执行失败: {str(e)}")

# after — preserve cause and re-raise already-typed exceptions untouched
except (AgentException, ExternalAPIException):
    raise
except Exception as e:
    raise AgentException(f"工具 '{tool_name}' 执行失败: {e}") from e
Defensive patterns

Strategy: try-catch

Try / catch

try:
    result = await agent.call_tool(name, tool_input)
except AgentException as e:
    # suffix after '执行失败:' is the root cause
    root = str(e).split('执行失败:', 1)[-1].strip()
    logger.error("tool %s failed: %s", name, root, exc_info=True)
    raise

Prevention

When it happens

Trigger: A registered tool raising KeyError on malformed input (e.g. tool_input missing keys), aiohttp.ClientError on connection reset, feedparser returning entries lacking attributes (AttributeError), or an ExternalAPIException from a non-200 HTTP status inside the tool — all emerge as "工具 'X' 执行失败: <original>".

Common situations: LLM emitting tool arguments that don't match the tool's expected schema; upstream APIs (arXiv/IEEE) changing response shape; missing optional-dependency imports inside tool modules; encoding errors parsing PDFs.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/510f82c61bbe3102. Report an issue: GitHub.