很多团队已经把 LLM 接进业务,但一到“多步任务 + 调工具 + 失败重试”就开始失控:日志看不懂、状态回不去、成本还飙升。
这篇给你一个能直接落地到 Go 服务里的最小可用方案:工具调用闭环、会话记忆分层、错误恢复可回放。
1) 架构先定死:三层解耦,别让 Agent 直接碰数据库
推荐把链路拆成 3 层:
- Orchestrator:接收用户请求,推进步骤状态机
- Agent Runtime:和 OpenAI Agents SDK 交互,只负责推理与 tool call
- Tool Adapter:真正执行业务动作(查单、写库、发通知),并返回结构化结果
关键原则:
- Agent 只拿“工具契约”,不拿底层资源权限
- 工具返回必须是可序列化 JSON(便于重放/审计)
- 每一步都带
trace_id+idempotency_key
2) Tool Calling:先把 Schema 设计好,成功率直接翻倍
常见失败不是模型笨,而是 Schema 含糊。
建议:
- 参数都标注类型和枚举范围
- 时间统一 ISO8601
- 金额统一最小货币单位(分)
- 每个工具都返回
ok/data/error_code/error_message/retryable
Go 侧工具返回示例:
{
"ok": false,
"error_code": "ORDER_LOCKED",
"error_message": "order is locked by settlement process",
"retryable": true,
"data": null
}
这样模型就能判断是“改参数重试”还是“升级人工处理”。
3) 会话记忆:短期上下文 + 长期摘要,不要无脑塞历史
生产环境里,记忆建议分两层:
- 短期窗口(最近 N 轮):保证当前任务连续性
- 长期摘要(任务级):保存关键信息,不保存冗余对话
实操策略:
- 每轮后做一次摘要更新(限制 300~500 tokens)
- 命中敏感字段前先脱敏
- 只把“与当前目标相关”的记忆回注给模型
否则你会遇到三连击:慢、贵、偏题。
4) 错误恢复:用状态机,不要靠 if-else 地狱
把一次请求定义成可恢复状态机:
RECEIVEDPLANNEDTOOL_RUNNINGTOOL_FAILED_RETRYABLETOOL_FAILED_FATALCOMPLETED
恢复规则:
retryable=true:指数退避 + 最大重试次数- 连续失败超阈值:降级到人工队列
- 任一步骤超时:回滚到最近可重放 checkpoint
Go 伪代码:
if step.Retryable && step.RetryCount < 3 {
backoff := time.Second * time.Duration(1<<step.RetryCount)
scheduleRetry(step, backoff)
} else if step.Retryable {
moveToManualQueue(step)
} else {
markFatal(step)
}
5) 观测与成本:上线第一天就该有的 6 个指标
最少要打这 6 个指标:
- tool_call_success_rate
- tool_call_p95_latency
- agent_step_retry_rate
- token_input/output_per_request
- cost_per_successful_task
- manual_handoff_ratio
再加 2 个告警:
- 5 分钟内
retry_rate突增 - 单任务 token 消耗超过阈值
6) 最小上线清单(可直接抄)
- 所有工具有 JSON Schema 与错误码字典
- 每步状态持久化(含输入输出快照)
- 幂等键贯穿请求与工具层
- 重试/熔断/人工降级路径已演练
- 关键指标接入 Prometheus/Grafana
- 灰度发布(10% 流量)+ 回滚开关
总结
OpenAI Agents SDK + Go 真正难点不在“调通一次”,而在失败时还能稳定恢复。
按本文这套分层 + 状态机 + 观测方案,你可以先把成功率和可维护性拉起来,再逐步优化效果与成本。别追求一步到位,先保证系统不会在凌晨 3 点把你叫醒。