学完能做什么
你会把 Agent 从“会聊天的模型”拆成可控制的运行循环,明确模型、工具、状态、策略和日志各自负责什么,并画出一个可以开始编码的最小架构。
Agent 不是一个更长的提示词
模型的一次调用只有输入和输出。Agent 则是在程序控制下重复执行“观察、判断、行动、校验”,直到任务完成、失败或触发停止条件。
text
接收任务 → 整理上下文 → 调用模型 → 校验决定
↑ ↓
记录状态 ← 返回结果或继续 ← 执行允许的工具模型负责理解和提出下一步,程序负责权限、执行和停止。不要把数据库写入、文件删除或消息发送直接交给模型。
最小架构的五个部件
| 部件 | 主要职责 | 不应该负责 |
|---|---|---|
| 运行器 | 推进循环、超时、重试、停止 | 猜测业务规则 |
| 模型适配层 | 统一请求与响应格式 | 直接执行工具 |
| 工具注册表 | 声明、查找和调用工具 | 接受未校验参数 |
| 状态存储 | 保存步骤、结果和任务状态 | 无限保存全部对话 |
| 策略层 | 权限、预算、确认和风险边界 | 生成自然语言答案 |
第一版可以把它们写在一个文件里,但接口要分开。之后更换模型、工具或存储时,核心循环不用重写。
用状态机看清一次运行
建议至少定义以下状态:
text
CREATED 已创建任务
PLANNING 模型正在判断下一步
VALIDATING 程序正在校验模型输出
WAITING 等待用户确认或补充材料
EXECUTING 正在执行工具
RESPONDING 正在生成最终回答
SUCCEEDED 成功结束
FAILED 明确失败
CANCELLED 被用户或系统取消状态转换必须由程序决定。模型可以建议“任务已完成”,但运行器仍要检查完成条件。
一个不依赖具体 SDK 的循环
python
MAX_STEPS = 8
def run(task, context, model, tools, policy):
state = {
"status": "CREATED",
"step": 0,
"messages": build_initial_messages(task, context),
"events": [],
}
while state["step"] < MAX_STEPS:
state["step"] += 1
state["status"] = "PLANNING"
decision = model.decide(state["messages"], tools.schemas())
state["status"] = "VALIDATING"
checked = policy.validate(decision, state)
if checked.kind == "final":
state["status"] = "SUCCEEDED"
return checked.answer, state
if checked.kind == "need_confirmation":
state["status"] = "WAITING"
return checked.prompt, state
state["status"] = "EXECUTING"
result = tools.call(checked.tool_name, checked.arguments)
state["messages"].append(as_tool_result(checked.call_id, result))
state["events"].append(safe_event(checked, result))
state["status"] = "FAILED"
raise RuntimeError("达到最大步骤数,任务未完成")这段伪代码最重要的不是语法,而是三个边界:每一步都校验、循环有上限、有副作用的动作可以暂停确认。
停止条件必须写在代码里
至少设置:
- 最大步骤数,避免模型反复调用同一工具;
- 单次和整次任务超时;
- 请求与工具调用预算;
- 连续重复动作检测;
- 用户取消信号;
- 已满足的业务完成条件;
- 无法恢复的错误类型。
“让模型自己判断什么时候停”不够可靠。模型输出只是证据之一。
事件日志比完整思维过程更有用
记录可审计事件,不要求模型展示隐藏推理:
json
{
"task_id": "task_123",
"step": 3,
"event": "tool_completed",
"tool": "search_documents",
"argument_summary": {"query_length": 18},
"result_summary": {"documents": 4},
"duration_ms": 426,
"status": "ok"
}日志中不要保存密钥、完整个人资料和不必要的原文。为输入、提示词、工具定义和结果保留版本号,复现问题时才知道当时运行的是什么。
先从只读 Agent 开始
第一版工具优先选择搜索、读取、计算和格式转换。写入、发送、删除和支付类工具需要更严格的身份、授权、参数预览、幂等和人工确认。
推荐演进顺序:
- 单轮模型调用;
- 一个只读工具;
- 多轮工具循环;
- 可暂停与恢复;
- 有条件的写入工具;
- 评测、监控和发布。
架构练习
为“根据内部材料生成每周项目摘要”画一张架构图,并回答:
- 哪些材料允许读取,哪些字段必须脱敏?
- “完成”的判断条件是什么?
- 最多允许多少次检索和模型调用?
- 哪些错误可重试,哪些应立即停止?
- 摘要只生成草稿,还是允许直接发送?
- 需要记录哪些事件才能复现一次运行?
完成检查清单
- 模型只提出决定,程序掌握执行权。
- 状态、完成条件和失败状态都有明确定义。
- 步骤、时间、预算和重复动作都有上限。
- 高风险动作可以暂停并向用户展示参数。
- 日志能复现过程,但不泄露密钥和敏感数据。
下一步
下一篇将完成第一次模型 API 请求,把密钥、超时、错误处理和最小日志都落到可运行代码里。