Agent 状态机、记忆和工具权限
🤖 Agent 不是“会调用工具的聊天机器人”,而是一个由 LLM 决策器 + 状态机 + 工具执行器 + 权限策略 + 可观测性组成的分布式工作流。生产可靠性主要来自模型之外的工程约束。
Agent 运行时心智模型
每个状态都应有明确输入、输出、超时和重试规则,而不是让模型靠自然语言维持流程。
**确定性外壳,概率性内核:**让 LLM 负责理解与候选决策,让代码负责状态迁移、预算、鉴权、重试、幂等和终止。
状态设计
class AgentState(TypedDict):
run_id: str
objective: str
status: Literal["planning", "running", "waiting", "done", "failed"]
plan: list[Step]
current_step: int
observations: list[Observation]
artifacts: list[ArtifactRef]
budget: Budget
pending_approval: Approval | None
error: ErrorInfo | None
状态应满足
- 可恢复:进程重启后能从 checkpoint 继续。
- 可重放:相同输入与工具结果可重建决策轨迹。
- 幂等:写操作使用 idempotency key,重试不重复发信或扣款。
- 有界:限制最大轮数、上下文、费用和时间。
记忆不是一个向量库
| 类型 | 内容 | 典型存储 | 生命周期 |
|---|---|---|---|
| 工作记忆 | 当前计划、工具结果、临时变量 | 状态存储 | 单次运行 |
| 情景记忆 | 过去任务、时间线、结果 | 事件日志/数据库 | 跨运行 |
| 语义记忆 | 稳定事实、用户偏好 | 结构化库 + 检索 | 长期 |
| 程序记忆 | 可复用流程、代码和技能 | 版本化工具/仓库 | 长期 |
写入长期记忆前应判断:来源是否可信、是否稳定、是否敏感、是否获得授权、何时过期。不要把模型推测当成用户事实。
上下文管理
- 原始工具结果保存到外部存储,Prompt 中只放必要摘要和引用。
- 摘要必须可追溯到原始 observation。
- 关键约束、当前目标和未完成步骤不要被摘要丢失。
- 长任务使用 checkpoint,而不是无限追加消息。
工具设计
一个好工具应该:
- 单一职责,名称和描述无歧义。
- 参数 Schema 严格,枚举优于自由文本。
- 返回结构稳定且精简。
- 明确只读/写入、是否幂等、超时和错误类型。
- 在执行层鉴权,而不是信任模型参数。
错误分类
- 可重试:超时、限流、暂时性 5xx,采用退避与抖动。
- 需修正参数:Schema 或业务校验错误,反馈可操作信息。
- 需人工介入:权限、冲突、高风险决策。
- 不可恢复:资源不存在、目标已取消,及时终止。
权限与审批
- 默认只开放完成当前任务所需工具。
- 工具权限绑定用户与资源,而不是绑定“Agent 身份”后全局通用。
- 删除、付款、发布、修改权限和对外通信采用审批。
- 审批后若参数变化,应重新确认,不能复用旧批准。
多 Agent 何时值得使用
只有当任务确实可以按职责、权限或上下文隔离时再拆分。多 Agent 会增加通信损失、成本、死锁和调试难度。优先考虑“一个编排器 + 确定性工作流 + 少量专用执行器”,而不是让多个 Agent 自由聊天。
可观测性与评测
至少记录:run/trace ID、状态迁移、模型与 Prompt 版本、工具参数/结果摘要、重试、审批、token、成本、延迟和最终验证结果。
核心指标:
- 端到端任务成功率
- 首次计划成功率与平均重规划次数
- 工具选择/参数正确率
- 人工接管率
- 重复副作用次数
- 单任务成本、P95 时长
生产检查清单
- 状态可持久化、恢复和重放
- 所有写操作幂等
- 有终止条件和资源预算
- 长期记忆可审计、可过期、可删除
- 工具执行层有真实鉴权
- 高风险操作需要审批
- 最终结果经过独立验证
- 失败案例进入回归集