datawhalechina/hello-agents · error · TimeoutException
工具 '{tool_name}' 执行超时
Error message
工具 '{tool_name}' 执行超时 What it means
TimeoutException from BaseAgent.call_tool: asyncio.wait_for wrapped the tool coroutine (or asyncio.to_thread for sync tools) with self.timeout seconds, the deadline elapsed, and wait_for cancelled the task. The message names the tool that hung. Important caveat: for to_thread tools the underlying thread cannot be force-killed, so it may keep running after the exception.
Source
Thrown at Co-creation-projects/Apricity-InnocoreAI/agents/base.py:82
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 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}"View on GitHub (pinned to 606a07d341)
Solutions
- Raise self.timeout for network tools or make it per-tool configurable (e.g. timeout=120 for download-heavy tools).
- Set aiohttp.ClientTimeout(total=..., sock_read=30) inside the tool so it fails fast with its own clear error before the agent deadline.
- Replace blocking requests with async clients so wait_for's cancellation actually stops the work.
- Retry transient network hangs with a bounded retry loop inside the tool (backoff on the API call, not the whole agent step).
- For CPU-bound sync tools, move heavy parsing into a subprocess if cancellation must actually stop it.
Example fix
# before
async with session.get(self.arxiv_base_url, params=params) as response:
... # no inner timeout; agent-level wait_for fires
# after — tool owns its timeout so it fails (and retries) before the agent deadline
timeout = aiohttp.ClientTimeout(total=30, sock_read=10)
async with aiohttp.ClientSession(timeout=timeout) as session:
for attempt in range(3):
try:
async with session.get(self.arxiv_base_url, params=params) as response:
...
break
except aiohttp.ClientError:
if attempt == 2:
raise Defensive patterns
Strategy: retry
Validate before calling
# Verify tool timeouts are sane before running the agent
assert agent.timeout >= 30, f"timeout={agent.timeout}s too low for network tools"
for name, info in agent.tools.items():
if asyncio.iscoroutinefunction(info['function']):
continue # async tools can be cancelled cleanly
log.warning(f"sync tool '{name}' blocks the loop thread if it hangs") Try / catch
from agents.exceptions import TimeoutException
try:
result = await agent.call_tool('search_arxiv', q)
except TimeoutException as e:
result = await with_backoff(lambda: agent.call_tool('search_arxiv', q), retries=2) Prevention
- Give each tool its own timeout sized to its latency profile instead of one agent-wide value.
- Set client-level timeouts inside network tools so they fail before the agent deadline.
- Prefer async I/O in tools so wait_for cancellation actually stops the work.
When it happens
Trigger: Calling a network-bound tool (ArXiv/IEEE search, PDF download) against a slow or stalled endpoint with the default agent timeout; a sync tool doing blocking I/O inside to_thread while the event loop waits; tool deadlocking on a lock or unbounded feedparser parse of a huge response.
Common situations: Default timeout too low for arXiv's occasionally slow API; aiohttp session without its own sock_read timeout so the coroutine never progresses; tools doing requests.get (blocking) instead of aiohttp; thread-pool saturation making even fast tools exceed the budget.
Related errors
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/ac956ea94b544472.
Report an issue: GitHub.