AI小栈AI小栈
首页
  • 模块概览
  • Transformer 与注意力机制
  • 主流大模型对比
  • Prompt Engineering
  • Token 与成本核算
  • Function Calling
  • 模块概览
  • Agent 范式
  • 多 Agent 协作
  • 记忆系统
  • 规划与推理
  • 安全与可控性
  • 模块概览
  • LangChain / LangGraph
  • Claude Agent SDK
  • OpenAI Agents SDK
  • AutoGen / CrewAI
  • Dify / Coze
  • MCP 协议
  • 模块概览
  • RAG 工程化
  • 工具设计与封装
  • 流式输出与 UX
  • 可观测性
  • 部署与成本优化
  • 测试与评估
  • 模块概览
  • 智能编程助手
  • 知识库问答 Agent
  • 数据分析 Agent
  • 多模态 Agent
  • 运维 Agent
  • 从0到1构建
  • 模块概览
  • 论文解读
  • 开源项目追踪
  • MCP 生态
  • Agent 商业化
  • 职业路径
  • 模块概览
  • 技术面试实战
  • Agent 面试题解析
  • 项目经验包装
  • 流程与心态准备
首页
  • 模块概览
  • Transformer 与注意力机制
  • 主流大模型对比
  • Prompt Engineering
  • Token 与成本核算
  • Function Calling
  • 模块概览
  • Agent 范式
  • 多 Agent 协作
  • 记忆系统
  • 规划与推理
  • 安全与可控性
  • 模块概览
  • LangChain / LangGraph
  • Claude Agent SDK
  • OpenAI Agents SDK
  • AutoGen / CrewAI
  • Dify / Coze
  • MCP 协议
  • 模块概览
  • RAG 工程化
  • 工具设计与封装
  • 流式输出与 UX
  • 可观测性
  • 部署与成本优化
  • 测试与评估
  • 模块概览
  • 智能编程助手
  • 知识库问答 Agent
  • 数据分析 Agent
  • 多模态 Agent
  • 运维 Agent
  • 从0到1构建
  • 模块概览
  • 论文解读
  • 开源项目追踪
  • MCP 生态
  • Agent 商业化
  • 职业路径
  • 模块概览
  • 技术面试实战
  • Agent 面试题解析
  • 项目经验包装
  • 流程与心态准备
  • Agent 工程实践

    • 模块概览
    • RAG 工程化
    • 工具设计与封装
    • 流式输出与用户体验
    • 可观测性
    • 部署与成本优化
    • 测试与评估框架

工具设计与封装

Agent 的能力边界取决于它能调用什么工具。一个设计良好的工具能让 Agent 精准完成任务,而设计不当的工具不仅帮不上忙,还可能误导模型决策、引发安全事故。本章从 API 接入规范、沙箱执行、错误处理、工具描述四个维度,讲解如何为 Agent 打造可靠、高效的工具体系。

API 接入规范

统一的工具接口定义

无论底层是 HTTP API、数据库查询还是本地脚本,Agent 看到的工具接口应统一为 JSON Schema 描述 + JSON 输入输出。这种统一性让模型不必为每种工具学习不同的调用方式。

{
  "name": "query_order_status",
  "description": "查询订单的当前状态,包括物流进度和预计送达时间",
  "parameters": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "订单编号,格式为 ORD-XXXXXX"
      },
      "include_logistics": {
        "type": "boolean",
        "description": "是否包含物流详情,默认为 true",
        "default": true
      }
    },
    "required": ["order_id"]
  }
}

输入校验与类型约束

JSON Schema 不仅告诉模型参数是什么,更是 输入校验的防线。在工具执行前必须校验:

  • 类型校验:order_id 是 string 而非 number,防止模型传错类型。
  • 格式校验:order_id 格式为 ORD-XXXXXX,可用正则约束。
  • 枚举约束:status 字段只能是 ["active", "cancelled", "completed"],用 enum 限制。

模型有时会"创造"参数值(如生成一个不存在的 order_id)。校验层应在执行前拦截这类无效输入,返回明确的错误信息而非让错误传播到后端 API。

超时与重试策略

工具调用可能因网络波动、API 限流等原因失败。每个工具应配置:

  • 超时时间:根据工具类型设定合理超时。数据库查询 5 秒、外部 API 15 秒、文件操作 30 秒。
  • 重试策略:对可恢复错误(网络超时、429 限流)做最多 3 次重试,每次间隔递增(指数退避)。对不可恢复错误(404、参数错误)不重试,直接返回错误。
  • 降级方案:关键工具应有降级路径。例如实时查询失败时,返回最近一次缓存的近似结果并标注"数据可能非最新"。

沙箱执行环境

为什么需要沙箱?

Agent 可能执行用户请求中隐含的代码(如数据分析场景下的 Python 代码),或调用涉及系统资源的工具(文件读写、网络请求)。如果直接在宿主环境执行:

  • 安全风险:恶意指令可能删除文件、访问敏感数据、发起网络攻击。
  • 资源风险:失控的计算任务可能耗尽 CPU/内存,影响宿主服务稳定性。
  • 隔离风险:不同用户的执行环境可能互相干扰。

沙箱方案选择

方案隔离级别启动延迟适用场景
Docker 容器进程+文件+网络隔离500ms-2s通用执行、代码运行
gVisor / Firecracker内核级隔离1-3s高安全要求的代码执行
WebAssembly(Wasm)模块级隔离<100ms轻量计算、函数执行
子进程 + 资源限制进程级隔离<50ms简单脚本、受限操作

推荐组合:对代码执行类工具使用 Docker+资源限制(CPU 1核/内存 512MB/磁盘 100MB/无网络),对函数级轻量工具使用 Wasm。

资源限制配置

# Docker 沙箱配置示例
sandbox_config = {
    "cpu_limit": 1,          # 最多 1 个 CPU 核心
    "memory_limit": "512m",  # 最大内存 512MB
    "timeout": 30,           # 执行超时 30 秒
    "network": "none",       # 禁止网络访问
    "disk_limit": "100m",    # 最大磁盘写入 100MB
    "read_only_paths": ["/data"],  # 只读挂载
    "writable_paths": ["/tmp/output"]  # 可写挂载
}

错误处理

错误分类与分级

工具错误不是简单的"成功/失败"二分,应按严重程度分类:

  • Level 0 - 可忽略:工具返回了部分数据而非完整数据(如物流信息缺一项),Agent 可以继续推理并告知用户数据不完整。
  • Level 1 - 可重试:网络超时、API 限流等暂时性错误,Agent 应自动重试后继续。
  • Level 2 - 需要替代:工具本身不可用,Agent 应选择替代工具或策略(如用缓存数据代替实时查询)。
  • Level 3 - 需要人工介入:权限不足、数据冲突等需要用户决策的错误,Agent 应清晰说明问题并请求用户指示。

错误信息设计原则

错误信息同时服务于两个受众:LLM(需要理解错误原因以调整策略)和用户(需要知道发生了什么)。因此:

  1. 结构化返回:不要只返回一个字符串,返回 {success: false, error_type: "timeout", message: "...", suggestion: "..."}。
  2. 给模型可操作的 suggestion:如 "请尝试缩短查询范围或使用更具体的订单编号",而非 "请求超时"。
  3. 避免暴露内部细节:对用户展示的错误信息不应包含 API 地址、数据库表名等内部信息,但对模型可以传递更多上下文以辅助推理。

工具描述最佳实践

工具的 description 是模型决定何时、如何调用工具的唯一依据。描述质量直接决定工具调用成功率。

好的描述长什么样

{
  "name": "search_product_inventory",
  "description": "根据产品名称或类别搜索库存信息。返回每个匹配产品的当前库存数量、仓库位置和预计补货日期。当用户询问产品是否有货、库存数量、何时补货时使用此工具。不支持模糊匹配,产品名称需精确或使用类别筛选。"
}

关键要素:

  • 功能说明:工具做什么、返回什么。
  • 触发条件:什么时候该用——"当用户询问..."。
  • 局限说明:什么时候不该用或有什么限制——"不支持模糊匹配"。

常见问题

  • 描述过于简短:"搜索库存"——模型不知道什么时候该调用它,可能在不相关的场景误触发。
  • 描述过于宽泛:"查询所有信息"——模型可能用它替代所有其他工具,导致不该用的场景也调了。
  • 缺少边界说明:没告诉模型工具的输入限制,导致模型传了格式错误的参数。
  • 名称歧义:工具名 get_data 太通用,模型无法区分它与其他类似工具——用 search_product_inventory 而非 get_data。

多工具场景的描述策略

当 Agent 有 10+ 工具时,模型面临"选择哪个工具"的决策压力。此时:

  1. 工具名要自解释:calculate_mortgage 比 calc 好 10 倍。
  2. 描述中明确分工:query_current_stock 描述"查询实时库存",query_stock_history 描述"查询历史库存变化趋势"——让模型能精确选择。
  3. 合并过于碎片化的工具:3 个参数几乎相同、功能只是返回字段略有差异的工具,合并为 1 个带 include_fields 参数的工具更高效。

本章小结

设计维度最佳实践
API 标准化JSON Schema 定义参数,名称语义清晰,描述包含边界条件
沙箱隔离Docker 容器化运行,网络隔离,资源限制
错误处理四层错误体系:参数错误 → 执行错误 → 超时错误 → 系统错误
安全性最小权限原则,操作审计,输入校验,敏感数据脱敏

核心原则:工具是 Agent 的"手脚"——设计不好,Agent 再聪明也走不稳。


📖 延伸阅读

  1. JSON Schema —— 工具参数定义标准
  2. OpenAPI Specification —— REST API 设计规范
  3. gVisor Documentation —— 容器安全沙箱
  4. OWASP API Security Top 10 —— API 安全最佳实践
Prev
RAG 工程化
Next
流式输出与用户体验