Skip to content

Agent 设计基础

本节介绍构建 Agent 的三大核心组件:模型(Model)、工具(Tools)、指令(Instructions)。

核心组件

在最基本的形式中,Agent 由三个核心组件构成:

组件说明
模型(Model)为 Agent 推理和决策提供支持的 LLM
工具(Tools)Agent 可以用来执行操作的外部函数或 API
指令(Instructions)定义 Agent 行为的明确指南和护栏
python
weather_agent = Agent(
    name="Weather agent",
    instructions="You are a helpful agent who can talk to users about the weather",
    tools=[get_weather],
)

关于代码示例

本系列的代码示例基于 OpenAI Agents SDK。其他框架(如 LangChain、CrewAI、AutoGen)在概念层面相通,API 和配置方式有所不同。

选择模型

基本原则

不同的模型在任务复杂度、延迟和成本方面有不同的优势和权衡。

任务类型推荐模型原因
简单检索、意图分类较小、快速的模型(如 Haiku)任务简单,不需要最智能的模型
复杂推理、多步决策能力更强的模型(如 Sonnet、GPT-4)需要更强的推理能力

模型选择策略

推荐方法

  1. 建立基准:先用最胜任的模型构建原型,建立性能基准
  2. 逐步替换:尝试换用较小的模型,看是否仍能达到可接受的结果
  3. 确保质量:不要过早限制 Agent 的能力,确保准确率目标能达成

选择模型的原则

  • 设置评估以建立性能基准
  • 使用可用的最佳模型专注于满足准确率目标
  • 在可能的情况下,通过用较小的模型替换较大的模型来优化成本和延迟

定义工具

工具的作用

工具通过使用底层应用程序或系统的 API 来扩展 Agent 的能力。对于没有 API 的遗留系统,Agent 可以依赖计算机使用模型通过 Web 和应用程序 UI 直接与这些系统交互——就像人类一样。

工具设计原则

每个工具都应该有一个标准化定义,使工具和 Agent 之间能够灵活地建立多对多关系。

良好工具的特征

  • 良好文档化
  • 经过充分测试
  • 可重用
  • 清晰的名称和参数
  • 详细的描述

三种工具类型

类型描述示例
数据检索上下文和信息,管理短期/长期记忆查询数据库、读取 PDF、搜索网络、读取向量库
操作与系统交互执行操作发送邮件、更新 CRM、添加记录
编排Agent 作为其他 Agent 的工具(详见第 5 篇:Agent 编排模式退款 Agent、研究 Agent

工具格式建议

有几种方法可以指定同一个操作。例如,你可以通过编写 diff 或重写整个文件来指定文件编辑。在 JSON 或 Markdown 中返回代码。

工具格式最佳实践

建议说明
给模型足够的 token 来"思考"避免模型陷入困境
保持格式接近模型自然看到的文本形式减少理解成本
确保没有格式化"开销"不需要精确计数、不需要字符串转义

经验法则:思考在人机交互(HCI)上投入了多少精力,并计划在创建良好的 Agent-计算机接口(ACI)上投入同样多的精力。

工具定义示例

python
@function_tool
def save_results(output):
    db.insert({
        "output": output,
        "timestamp": datetime.datetime.now(),
    })
    return "File saved"

search_agent = Agent(
    name="Search agent",
    instructions="Help the user search the internet and save results if asked.",
    tools=[WebSearchTool(), save_results],
)

工具工程最佳实践

实践说明
设身处地为模型着想根据描述和参数,使用这个工具是否显而易见?
清晰的参数名称想象为团队中的初级开发人员编写文档字符串
测试模型如何使用工具运行许多示例输入,查看模型犯的错误,并迭代改进
防错设计更改参数使其更难犯错

示例:防错设计

在为 SWE-bench 构建 Agent 时,发现 Agent 在移出根目录后使用相对文件路径会犯错。解决方案:更改工具,始终要求使用绝对文件路径——模型可以完美地使用这个方法。

工具集成标准

模型上下文协议(MCP) 是连接 Agent 与外部工具的开放标准。你只需实现一个 MCP 客户端即可接入不断增长的第三方工具生态(如数据库、云服务、代码仓库等),无需为每个工具编写自定义集成。参见 modelcontextprotocol.io

错误处理模式

工具调用必然会遇到失败。Agent 需要能够从错误中恢复:

模式说明示例
重试网络错误时自动重试(带退避)get_order_status 超时 → 等待 1 秒重试
降级主工具失败时用替代方案数据库查询失败 → 改用缓存数据
上报Agent 无法自行解决时请求人工"系统暂时无法访问,我帮你转接人工客服"
验证检查工具输出合理性API 返回空列表 → 确认查询条件后再决定

重试示例

python
@function_tool
async def get_order_status(order_id: str) -> str:
    """查询订单状态,失败时会自动重试"""
    max_retries = 3
    for attempt in range(max_retries):
        try:
            result = await api.get_order(order_id)
            return f"订单状态: {result.status}"
        except ConnectionError:
            if attempt < max_retries - 1:
                await asyncio.sleep(1 * (attempt + 1))  # 退避等待
                continue
            return "系统暂时无法查询,请稍后再试或联系人工客服。"

配置指令

高质量的指令对于任何 LLM 驱动的应用都是必不可少的,但对于 Agent 尤为关键。清晰的指令可以减少歧义并改善 Agent 决策,从而实现更顺畅的工作流执行和更少的错误。

指令最佳实践

实践说明
使用现有文档使用现有的操作程序、支持脚本或策略文档来创建 LLM 友好的例程
分解任务从密集资源中提供更小、更清晰的步骤,有助于减少歧义
定义明确的动作确保每个步骤对应一个特定的动作或输出
处理边缘情况预见常见变化,包含条件步骤或分支处理

指令结构建议

  • 使用现有文档:在客户服务中,例程大致可以映射到知识库中的各个文章
  • 分解任务:提供更小、更清晰的步骤,帮助模型更好地遵循指令
  • 明确动作:例如,一个步骤可能指示 Agent 询问用户的订单号或调用 API 检索账户详情
  • 捕获边缘情况:例如当用户提供不完整信息或提出意外问题时如何处理

自动生成指令

可以使用高级模型(如 o1 或 o3‑mini)从现有文档自动生成指令:

"You are an expert in writing instructions for an LLM agent.
Convert the following help center document into a clear set of instructions,
written in a numbered list.
Ensure that there is no ambiguity, and that the instructions are written as
directions for an agent."

记忆架构

Agent 在循环运行中需要"记住"信息,这涉及两个层面的记忆:

层面机制说明
短期记忆LLM 上下文窗口会话历史、当前轮次的 Observe/Think/Act 记录,受 token 限制
长期记忆外部存储(向量数据库/文件/数据库)跨会话持久信息,如用户偏好、历史订单、知识库

短期记忆管理

上下文窗口是有限的。常见策略:

  1. 滑动窗口:只保留最近的 N 轮对话,丢弃较早的历史
  2. 摘要压缩:当上下文接近上限时,用 LLM 将历史摘要成一段话
  3. 结构化剪枝:丢弃低价值信息(如确认消息、中间思考步骤),保留关键决策

长期记忆的实现

python
async def retrieve_user_context(user_id: str) -> str:
    """从向量数据库检索用户历史信息"""
    query = f"用户 {user_id} 的历史偏好和订单信息"
    results = await vector_db.search(query, top_k=5)
    return "\n".join(r.content for r in results)

async def remember(agent, user_id: str):
    """Agent 工具:检索用户长期记忆并注入上下文"""
    context = await retrieve_user_context(user_id)
    return f"用户的已知信息:\n{context}"

总结

构建可靠 Agent 的核心原则:

  1. 从坚实的基础开始:将有能力模型与定义明确的工具和清晰、结构化的指令配对
  2. 谨慎增加复杂性:只有当简单方案不足时才添加多步 Agent
  3. 注重工具设计:好的工具设计可以显著提升 Agent 的可靠性
  4. 清晰的结构化指令:指令应该明确、无歧义、可操作

一句话总结:Agent 的质量取决于其组件的质量——选择合适的模型、设计良好的工具、编写清晰的指令。