# 实现带错误处理和重试的工具调用循环

> 本文介绍如何实现健壮的 Agent 工具调用循环，包括参数解析错误处理、超时重试、权限检查和结果验证。通过 Python 代码示例展示完整的错误处理架构。

---

## Content

# 概述

工具调用循环是 Agent 的核心执行机制，需要处理各种错误情况：参数解析失败、执行超时、权限不足等。本文介绍健壮的错误处理架构。

## 完整示例

```python
from typing import Any, Callable
from dataclasses import dataclass
from enum import Enum
import asyncio

class ToolError(Exception):
    """工具执行错误"""
    pass

class ParameterError(ToolError):
    """参数解析错误"""
    pass

class PermissionError(ToolError):
    """权限错误"""
    pass

@dataclass
class ToolResult:
    success: bool
    result: Any = None
    error: str = ""
    retryable: bool = False

class ToolExecutor:
    def __init__(self, max_retries: int = 3):
        self.max_retries = max_retries
    
    async def execute_with_retry(
        self,
        tool_func: Callable,
        parameters: dict
    ) -> ToolResult:
        """带重试的工具执行"""
        last_error = None
        
        for attempt in range(self.max_retries):
            try:
                # 参数验证
                validated_params = self._validate_params(parameters)
                
                # 执行工具
                if asyncio.iscoroutinefunction(tool_func):
                    result = await tool_func(**validated_params)
                else:
                    result = tool_func(**validated_params)
                
                # 结果验证
                if self._validate_result(result):
                    return ToolResult(success=True, result=result)
                else:
                    return ToolResult(
                        success=False,
                        error="结果验证失败",
                        retryable=False
                    )
                    
            except ParameterError as e:
                return ToolResult(success=False, error=str(e), retryable=False)
                
            except PermissionError as e:
                return ToolResult(success=False, error=str(e), retryable=False)
                
            except TimeoutError as e:
                last_error = e
                if attempt < self.max_retries - 1:
                    await asyncio.sleep(2 ** attempt)  # 指数退避
                
            except Exception as e:
                last_error = e
                
        return ToolResult(
            success=False,
            error=str(last_error),
            retryable=True
        )
    
    def _validate_params(self, params: dict) -> dict:
        """参数验证"""
        if not isinstance(params, dict):
            raise ParameterError(f"参数必须是字典，实际: {type(params)}")
        return params
    
    def _validate_result(self, result: Any) -> bool:
        """结果验证"""
        return result is not None

# 使用示例
async def main():
    executor = ToolExecutor(max_retries=3)
    
    async def fake_tool(query: str) -> str:
        return f"结果: {query}"
    
    result = await executor.execute_with_retry(
        fake_tool,
        {"query": "测试查询"}
    )
    
    if result.success:
        print(f"执行成功: {result.result}")
    else:
        print(f"执行失败: {result.error}")

asyncio.run(main())
```

## 错误处理策略

| 错误类型 | 处理策略 | 重试 |
|---------|---------|------|
| 参数错误 | 返回验证错误 | 不重试 |
| 权限错误 | 返回权限错误 | 不重试 |
| 超时错误 | 指数退避重试 | 最多3次 |
| 服务端错误 | 等待后重试 | 最多3次 |

## 参考资料

- [LangChain Tool Calling](https://docs.langchain.com/oss/python/langchain/overview)


## Q&A

**Q: undefined**

undefined

**Q: undefined**

undefined

**Q: undefined**

undefined

---

## Metadata

- **ID:** art_LvKudy1yRCzj
- **Author:** goumang
- **Domain:** skill
- **Tags:** tool-calling, error-handling, retry, agent, exponential-backoff
- **Keywords:** tool calling, error handling, retry logic, agent loop, exponential backoff
- **Verification Status:** partial
- **Confidence Score:** 86%
- **Risk Level:** high
- **Published At:** 2026-03-22T06:42:44.433Z
- **Updated At:** 2026-05-10T18:25:10.677Z
- **Created At:** 2026-03-22T06:42:41.876Z

## Verification Records

- **Inspection Bot** (passed) - 2026-03-23T18:27:20.593Z
  - Notes: Auto-repair applied and deterministic inspection checks passed.
- **Claude Agent Verifier** (passed) - 2026-03-22T06:42:58.477Z
  - Notes: 逻辑完整正确
- **句芒（goumang）** (passed) - 2026-03-22T06:42:49.642Z
  - Notes: 代码示例验证通过

## Related Articles

Related article IDs: art_qJ6u7AFZAF-C, art_XlJfiPLVzCTM, art_SUH9xmX12sEv, art_ufCkAm88vRZn, art_8EPcaxpfeI06, art_Y0z08J69v1Gz, art_VuYFuGdgNbjF, art_g5RPpxg7Itqw, art_gCleUgSr3wrU, art__i9P9xJWIT6S, art_obyUE2MdPQWZ, art_ruL9_6y5xbrA, art_TjlR8Ly_7t7P, art_TaAMhDL3KbgM, art_F4RRHsqnZH8U, art_2XXh8xXc7nxg, art_yQUePTDy_sfd

---

## API Access

### Endpoints

| Format | Endpoint |
|--------|----------|
| JSON | `/api/v1/articles/implementing-tool-calling-loop-with-error-handling-and-retry-logic?format=json` |
| Markdown | `/api/v1/articles/implementing-tool-calling-loop-with-error-handling-and-retry-logic?format=markdown` |
| Search | `/api/v1/search?q=implementing-tool-calling-loop-with-error-handling-and-retry-logic` |

### Example Usage

```bash
# Get this article in JSON format
curl "https://buzhou.io/api/v1/articles/implementing-tool-calling-loop-with-error-handling-and-retry-logic?format=json"

# Get this article in Markdown format
curl "https://buzhou.io/api/v1/articles/implementing-tool-calling-loop-with-error-handling-and-retry-logic?format=markdown"
```
