前两篇我分别讲了两个问题。第一篇讲Agent 不是多个 AI 角色互相聊天而是让大模型在边界内完成任务。第二篇讲ReAct、Tool Calling、State、Memory、Guardrails、Tracing 这些术语在 Agent 的任务执行循环里分别负责什么。这篇文章只拆一件事一次 Agent Run 是怎么从“用户问题”一步步走到“工具调用、状态更新、风险拦截和最终回答”的。真实的一次 Agent Run 更像这样用户目标 → 当前状态 → 模型判断下一步 → 请求调用工具 → 权限检查 → 执行工具 → 返回观察结果 → 更新状态 → 风险拦截 → 最终回答 / 人工确认 / 继续执行 → 记录运行轨迹如果再压缩一点就是看目标 → 看状态 → 决定下一步 → 调工具 → 看结果 → 更新状态 → 判断风险 → 继续或停止一次 Agent Run 不是“模型调用了一个工具”而是模型、工具、状态、权限、反馈和日志共同完成的一次任务执行过程。我更愿意把一次 Agent Run 理解成从用户提出目标开始到系统完成任务、失败停止、进入人工确认或者输出最终结果为止的一次完整执行过程。一、Step 1把用户问题变成任务目标链路位置用户目标用户原话是我的订单签收三天了商品破损可以退吗Agent 首先要做的不是回答而是识别目标。这个问题背后的任务目标是判断当前订单是否可以申请售后 / 退货并给出下一步处理建议。同时系统还要识别几个关键信号问题类型售后 / 退款 / 商品破损 用户声称签收三天 已知信息商品破损 未知信息订单状态、商品类目、售后政策、凭证要求 潜在风险不能直接承诺退款不能直接提交退款申请这一步看起来简单但非常重要。如果目标识别错了后面的工具调用都会错。用户问退款系统却误判成物流查询就会去查物流用户问售后政策系统却误判成投诉处理就会进入工单流程。ReAct 论文的核心思想也是让模型在任务过程中交替进行 reasoning 和 acting先判断下一步再采取动作通过外部知识源或环境获得反馈然后继续调整后续动作。放到工程里就是 Agent 不能一次性拍脑袋给答案而要根据目标和反馈持续推进任务。二、Step 2初始化 State记录已知信息和缺失信息链路位置用户目标 → 当前状态识别目标之后系统要初始化 Agent State。State 不是普通聊天记录。它更像这次任务的运行上下文。比如Run IDrun_001 Goal 判断订单是否可以退货。 Known Facts - 用户说订单已签收三天 - 用户说商品破损 Missing Info - 真实订单状态 - 订单是否属于当前用户 - 商品类目 - 售后政策 - 是否需要图片凭证 Risk Flags - 不能直接承诺退款 - 不能自动提交退款申请它把“用户已经说了什么”“系统还不知道什么”“当前有哪些风险”先记录下来。为什么不能跳过因为 Agent 不是单轮问答。它后面会查订单、查政策、更新事实、判断风险。如果没有 State模型下一轮可能忘记刚刚查到的信息也可能重复调用同一个工具。从LangGraph 文档中可以理解 Agent 里的 State 和 MemoryState 管当前任务Memory 管长期上下文。所以一次 Agent Run 的第一层工程基础是先有状态再谈行动。三、Step 3模型第一次判断当前信息不足先查订单链路位置用户目标 → 当前状态 → 模型判断下一步现在 Agent 已经知道用户想判断是否能退货。但真实订单状态未知。商品类目未知。售后政策未知。这时模型不应该直接回答而应该做第一次判断当前信息不足需要先查询订单。这一步可以叫 Reasoning也可以叫 Planning。但这里要注意工程系统不需要把模型完整思维链展示给用户。真正需要记录的是可审计的决策摘要。比如Decision #1需要查询订单因为当前无法确认订单状态、签收时间和商品类目。然后模型提出工具调用请求{ type: tool_call, name: get_order, arguments: { orderId: A1001 } }注意这一步还没有真正查数据库。它只是一个 Tool Call Request。四、Step 4Tool Call 不是执行结果只是动作请求链路位置用户目标 → 当前状态 → 模型判断下一步 → 请求调用工具这是 Tool Calling 最容易被误解的地方。很多人会说模型调用了工具。更准确的说法是模型请求调用工具应用程序决定是否执行。Spring AI 官方文档对这个边界说得很清楚虽然通常说 Tool Calling 是模型能力但工具调用逻辑由客户端应用提供模型只能请求工具调用并提供输入参数应用负责执行工具调用并返回结果模型不会直接访问工具背后的 API。所以刚才这个 JSON{ type: tool_call, name: get_order, arguments: { orderId: A1001 } }不是订单结果。不是数据库查询。不是系统操作。它只是模型在说我认为现在应该调用 get_order。真正的执行要交给应用程序。这一步的工程边界非常重要模型提出动作意图→ 应用验证动作是否合法→ 应用执行工具→ 工具结果返回给模型如果把这一步理解错就会误以为“模型拥有了系统权限”。实际上权限应该始终掌握在应用层。五、Step 5Policy Gate 先检查权限再执行工具链路位置用户目标 → 当前状态 → 模型判断下一步 → 请求调用工具 → 权限检查收到 tool call 后应用不能马上执行。它至少要检查几个问题这个工具是否存在 这个工具是否允许当前场景调用 当前用户是否有权限 orderId 是否属于当前用户 参数格式是否正确 这个工具是只读、写操作还是高风险动作比如get_order是一个只读工具但它仍然不能随便执行。如果用户传入了别人的订单号系统必须拦截。可以把这一层叫做 Policy GateTool Call get_order(orderIdA1001) Policy Gate - get_order 是否存在是 - 是否只读工具是 - 当前用户是否能访问 A1001需要校验 - 校验通过后才执行工具这就是为什么 Agent 安全不能只靠 prompt。不能只写不要越权查询。不要查别人的订单。不要直接退款。真正可靠的做法是让系统层做拦截。所以工具调用前必须有系统层边界。六、Step 6工具返回 ObservationState 更新链路位置权限检查 → 执行工具 → 返回观察结果 → 更新状态权限检查通过后应用执行get_order。工具返回{ orderId: A1001, status: SIGNED, signedDaysAgo: 3, productCategory: electronics }这就是 Observation。Observation 不是最终答案而是外部系统给 Agent 的反馈。收到 Observation 后系统要更新 StateKnown Facts 新增 - 订单存在 - 订单属于当前用户 - 订单状态SIGNED - 签收时间3 天前 - 商品类目electronics Missing Info 更新 - 还缺 electronics 类目的售后政策 - 还缺破损凭证要求 Risk Flags - 仍不能直接承诺退款这一步决定了 Agent 能否连续推进。如果工具结果没有写回 State模型后面可能会忘记刚才查到的信息。如果 Observation 没有结构化模型可能会误读工具返回。如果 Observation 没有记录后面就无法复盘。所以一次 Agent Run 里Observation 和 State Update 是成对出现的。工具返回结果 → 写入当前状态 → 变成下一轮判断的依据七、Step 7模型第二次判断继续查售后政策链路位置更新状态 → 模型继续判断下一步现在 State 已经更新。Agent 知道订单已签收 3 天也知道商品类目是 electronics。但它仍然不能回答“可以退”。因为还缺售后政策。所以模型做第二次判断Decision #2已确认订单状态和商品类目但还需要查询 electronics 类目的售后政策。然后提出第二个工具调用{ type: tool_call, name: get_refund_policy, arguments: { category: electronics } }应用再次检查工具是否允许、参数是否有效、返回结果是否可信。工具返回{ category: electronics, returnWindowDays: 7, needDamagePhoto: true, autoRefundAllowed: false }State 继续更新Known Facts 新增 - electronics 类目售后窗口7 天 - 破损需要上传图片凭证 - 不允许自动退款 Risk Flags 新增 - 可以生成申请说明 - 不能自动提交退款 - 如果用户要提交需要人工确认到这里Agent 才有足够信息生成一个相对靠谱的回答。八、Step 8Guardrails 判断是否允许自动退款链路位置更新状态 → 风险拦截这时有一个关键分叉。用户问的是可以退吗如果模型直接说可以我帮你提交退款。这就是风险。因为工具返回里已经明确autoRefundAllowed false而且退款提交是写操作会改变系统状态。这时 Guardrails 应该介入。Guardrails 不是 prompt 里一句“请谨慎”。它应该包括工具权限分类 参数校验 输出检查 敏感信息过滤 高风险动作拦截 人工确认 审计日志在这个退款场景里Guardrails 可以这样判断submit_refund 属于 WRITE_REVIEW。 当前政策不允许自动退款。 需要图片凭证。 所以不能自动提交退款。 只能生成退款申请说明等待用户确认或人工客服审核。OpenAI Agents SDK 的 tracing 文档也说明agent run 中会收集 LLM generations、tool calls、handoffs、guardrails 和自定义事件方便调试、可视化和监控 agentic workflows。这说明生产级 Agent 不只是“能调工具”还要知道每一步有没有触发风险边界。Agent 的价值不是它能不能自己做更多事而是它能不能在该停下来的地方停下来。九、Step 9需要 Human Review 的动作必须暂停链路位置风险拦截 → 人工确认 / 继续执行 / 停止如果用户继续说那你帮我直接提交吧。系统不能直接提交。因为这是高风险写操作。这时 Agent Run 应该进入 Human ReviewAction 准备提交退款申请 Risk 写操作会改变订单售后状态 Decision 暂停等待用户确认或人工客服审核LangGraph 的 interrupts 文档描述了类似机制interrupt 可以在指定点暂停 graph execution等待外部输入后再继续触发中断时LangGraph 会通过 persistence layer 保存当前 graph state直到恢复执行。LangChain 的 Human-in-the-loop 文档也提到当模型提出可能需要审查的动作比如写文件或执行 SQLmiddleware 可以暂停执行并等待人类决策图状态会被保存之后可以 approve、edit、reject 或 respond。这说明 Human Review 不是“弹窗确认”那么简单。它背后需要暂停当前 Run 保存当前 State 展示待执行动作 展示风险原因 等待用户或人工审核 根据审核结果继续、修改或终止没有状态保存就无法安全暂停。没有状态恢复就无法从人工确认后继续执行。十、Step 10生成最终回答但保留证据和限制条件链路位置最终回答 / 人工确认 / 继续执行在信息足够、风险判断完成后Agent 才能生成最终回答。一个更合理的回答是你的订单已签收 3 天仍在 7 天售后窗口内。 但因为商品破损需要上传图片凭证。当前政策不支持自动退款我可以先帮你生成退款申请说明提交前需要你确认或者转人工客服审核。这个回答和普通模型回答的区别是它没有凭常识直接说“可以退”。 它基于订单状态和售后政策。 它说明了限制条件。 它没有越权执行退款。 它把高风险动作交给用户确认或人工审核。这就是 Agent Run 的结果。不是“模型答得更像客服”而是系统在边界内完成了任务推进。十一、Step 11Trace Log 记录整次执行过程链路位置记录运行轨迹最后一次 Agent Run 必须被记录。你至少要能复盘这些信息Run ID 是什么 用户原始问题是什么 识别出的 Goal 是什么 初始 State 是什么 模型做了哪些决策 调用了哪些工具 工具参数是什么 工具返回了什么 State 如何更新 Guardrails 是否触发 是否进入 Human Review 最终回答用了哪些证据 整个过程花了多少 token、成本和时间如果没有 Trace LogAgent 出错后你只能看到最终回答。有了 Trace Log你才能判断错在目标识别 错在工具选择 错在工具参数 错在权限检查 错在工具返回 错在 State Update 错在 Guardrails 错在最终生成真实业务不只关心“这次回答对不对”。更重要的是如果错了我能不能知道错在哪里。十二、一次 Agent Run 最容易断在哪些地方第一目标识别错误。用户问的是退款系统误判成物流查询后面所有步骤都会偏。第二工具选择错误。明明应该先查订单却先查售后政策导致回答缺少订单上下文。第三权限检查缺失。模型请求查询订单应用没有检查订单是否属于当前用户这是典型越权风险。第四Observation 不可信。工具返回字段不完整、错误不明确、结果未脱敏都会影响后续判断。第五State 没有更新。工具结果没有进入状态模型下一轮可能重复调用工具或者忘记刚刚查到的信息。第六Guardrails 太弱。系统只靠 prompt 限制模型没有在工具权限和业务规则层做硬拦截。第七高风险动作没有人工确认。提交退款、发邮件、修改用户资料、执行 SQL这些都不应该被模型自动完成。第八没有 Trace Log。一旦出错无法复盘也无法改进。这些问题不是“模型不够聪明”导致的而是 Agent Run 的工程链路没有设计好。十三、最后总结一次 Agent Run 不是一次模型调用。也不是一次 Tool Calling。它是一条完整的任务执行链路用户目标 → 当前状态 → 模型判断下一步 → 请求调用工具 → 权限检查 → 执行工具 → 返回观察结果 → 更新状态 → 风险拦截 → 最终回答 / 人工确认 / 继续执行 → 记录运行轨迹这条链路里每一层都有自己的职责。模型负责判断下一步。工具负责连接外部系统。State 负责记录当前任务。Observation 负责反馈真实结果。Guardrails 负责限制风险。Human Review 负责接管高风险动作。Tracing 负责让过程可复盘。所以Agent 的价值不是“会调用工具”。真正的价值是它能在状态、工具、反馈和权限边界内把一个多步骤任务稳定推进到可交付结果。参考资料[1] OpenAI, Running agents - OpenAI Agents SDK.[2] Spring AI Reference, Tool Calling.[3] Yao et al., ReAct: Synergizing Reasoning and Acting in Language Models.[4] LangGraph Docs, Interrupts.[5] LangGraph Docs, Persistence.[6] LangChain Docs, Human-in-the-loop.[7] OpenAI Agents SDK, Tracing.[8] OWASP, LLM06:2025 Excessive Agency.我是Ryan一个专注于可信AI应用工程的开发者我的个人技术博客研究如何让AI生成从“外观”走向“有证据、可追溯、可验证”。
一次 Agent Run 是怎么发生的:从用户目标到工具调用、状态更新和风险拦截
前两篇我分别讲了两个问题。第一篇讲Agent 不是多个 AI 角色互相聊天而是让大模型在边界内完成任务。第二篇讲ReAct、Tool Calling、State、Memory、Guardrails、Tracing 这些术语在 Agent 的任务执行循环里分别负责什么。这篇文章只拆一件事一次 Agent Run 是怎么从“用户问题”一步步走到“工具调用、状态更新、风险拦截和最终回答”的。真实的一次 Agent Run 更像这样用户目标 → 当前状态 → 模型判断下一步 → 请求调用工具 → 权限检查 → 执行工具 → 返回观察结果 → 更新状态 → 风险拦截 → 最终回答 / 人工确认 / 继续执行 → 记录运行轨迹如果再压缩一点就是看目标 → 看状态 → 决定下一步 → 调工具 → 看结果 → 更新状态 → 判断风险 → 继续或停止一次 Agent Run 不是“模型调用了一个工具”而是模型、工具、状态、权限、反馈和日志共同完成的一次任务执行过程。我更愿意把一次 Agent Run 理解成从用户提出目标开始到系统完成任务、失败停止、进入人工确认或者输出最终结果为止的一次完整执行过程。一、Step 1把用户问题变成任务目标链路位置用户目标用户原话是我的订单签收三天了商品破损可以退吗Agent 首先要做的不是回答而是识别目标。这个问题背后的任务目标是判断当前订单是否可以申请售后 / 退货并给出下一步处理建议。同时系统还要识别几个关键信号问题类型售后 / 退款 / 商品破损 用户声称签收三天 已知信息商品破损 未知信息订单状态、商品类目、售后政策、凭证要求 潜在风险不能直接承诺退款不能直接提交退款申请这一步看起来简单但非常重要。如果目标识别错了后面的工具调用都会错。用户问退款系统却误判成物流查询就会去查物流用户问售后政策系统却误判成投诉处理就会进入工单流程。ReAct 论文的核心思想也是让模型在任务过程中交替进行 reasoning 和 acting先判断下一步再采取动作通过外部知识源或环境获得反馈然后继续调整后续动作。放到工程里就是 Agent 不能一次性拍脑袋给答案而要根据目标和反馈持续推进任务。二、Step 2初始化 State记录已知信息和缺失信息链路位置用户目标 → 当前状态识别目标之后系统要初始化 Agent State。State 不是普通聊天记录。它更像这次任务的运行上下文。比如Run IDrun_001 Goal 判断订单是否可以退货。 Known Facts - 用户说订单已签收三天 - 用户说商品破损 Missing Info - 真实订单状态 - 订单是否属于当前用户 - 商品类目 - 售后政策 - 是否需要图片凭证 Risk Flags - 不能直接承诺退款 - 不能自动提交退款申请它把“用户已经说了什么”“系统还不知道什么”“当前有哪些风险”先记录下来。为什么不能跳过因为 Agent 不是单轮问答。它后面会查订单、查政策、更新事实、判断风险。如果没有 State模型下一轮可能忘记刚刚查到的信息也可能重复调用同一个工具。从LangGraph 文档中可以理解 Agent 里的 State 和 MemoryState 管当前任务Memory 管长期上下文。所以一次 Agent Run 的第一层工程基础是先有状态再谈行动。三、Step 3模型第一次判断当前信息不足先查订单链路位置用户目标 → 当前状态 → 模型判断下一步现在 Agent 已经知道用户想判断是否能退货。但真实订单状态未知。商品类目未知。售后政策未知。这时模型不应该直接回答而应该做第一次判断当前信息不足需要先查询订单。这一步可以叫 Reasoning也可以叫 Planning。但这里要注意工程系统不需要把模型完整思维链展示给用户。真正需要记录的是可审计的决策摘要。比如Decision #1需要查询订单因为当前无法确认订单状态、签收时间和商品类目。然后模型提出工具调用请求{ type: tool_call, name: get_order, arguments: { orderId: A1001 } }注意这一步还没有真正查数据库。它只是一个 Tool Call Request。四、Step 4Tool Call 不是执行结果只是动作请求链路位置用户目标 → 当前状态 → 模型判断下一步 → 请求调用工具这是 Tool Calling 最容易被误解的地方。很多人会说模型调用了工具。更准确的说法是模型请求调用工具应用程序决定是否执行。Spring AI 官方文档对这个边界说得很清楚虽然通常说 Tool Calling 是模型能力但工具调用逻辑由客户端应用提供模型只能请求工具调用并提供输入参数应用负责执行工具调用并返回结果模型不会直接访问工具背后的 API。所以刚才这个 JSON{ type: tool_call, name: get_order, arguments: { orderId: A1001 } }不是订单结果。不是数据库查询。不是系统操作。它只是模型在说我认为现在应该调用 get_order。真正的执行要交给应用程序。这一步的工程边界非常重要模型提出动作意图→ 应用验证动作是否合法→ 应用执行工具→ 工具结果返回给模型如果把这一步理解错就会误以为“模型拥有了系统权限”。实际上权限应该始终掌握在应用层。五、Step 5Policy Gate 先检查权限再执行工具链路位置用户目标 → 当前状态 → 模型判断下一步 → 请求调用工具 → 权限检查收到 tool call 后应用不能马上执行。它至少要检查几个问题这个工具是否存在 这个工具是否允许当前场景调用 当前用户是否有权限 orderId 是否属于当前用户 参数格式是否正确 这个工具是只读、写操作还是高风险动作比如get_order是一个只读工具但它仍然不能随便执行。如果用户传入了别人的订单号系统必须拦截。可以把这一层叫做 Policy GateTool Call get_order(orderIdA1001) Policy Gate - get_order 是否存在是 - 是否只读工具是 - 当前用户是否能访问 A1001需要校验 - 校验通过后才执行工具这就是为什么 Agent 安全不能只靠 prompt。不能只写不要越权查询。不要查别人的订单。不要直接退款。真正可靠的做法是让系统层做拦截。所以工具调用前必须有系统层边界。六、Step 6工具返回 ObservationState 更新链路位置权限检查 → 执行工具 → 返回观察结果 → 更新状态权限检查通过后应用执行get_order。工具返回{ orderId: A1001, status: SIGNED, signedDaysAgo: 3, productCategory: electronics }这就是 Observation。Observation 不是最终答案而是外部系统给 Agent 的反馈。收到 Observation 后系统要更新 StateKnown Facts 新增 - 订单存在 - 订单属于当前用户 - 订单状态SIGNED - 签收时间3 天前 - 商品类目electronics Missing Info 更新 - 还缺 electronics 类目的售后政策 - 还缺破损凭证要求 Risk Flags - 仍不能直接承诺退款这一步决定了 Agent 能否连续推进。如果工具结果没有写回 State模型后面可能会忘记刚才查到的信息。如果 Observation 没有结构化模型可能会误读工具返回。如果 Observation 没有记录后面就无法复盘。所以一次 Agent Run 里Observation 和 State Update 是成对出现的。工具返回结果 → 写入当前状态 → 变成下一轮判断的依据七、Step 7模型第二次判断继续查售后政策链路位置更新状态 → 模型继续判断下一步现在 State 已经更新。Agent 知道订单已签收 3 天也知道商品类目是 electronics。但它仍然不能回答“可以退”。因为还缺售后政策。所以模型做第二次判断Decision #2已确认订单状态和商品类目但还需要查询 electronics 类目的售后政策。然后提出第二个工具调用{ type: tool_call, name: get_refund_policy, arguments: { category: electronics } }应用再次检查工具是否允许、参数是否有效、返回结果是否可信。工具返回{ category: electronics, returnWindowDays: 7, needDamagePhoto: true, autoRefundAllowed: false }State 继续更新Known Facts 新增 - electronics 类目售后窗口7 天 - 破损需要上传图片凭证 - 不允许自动退款 Risk Flags 新增 - 可以生成申请说明 - 不能自动提交退款 - 如果用户要提交需要人工确认到这里Agent 才有足够信息生成一个相对靠谱的回答。八、Step 8Guardrails 判断是否允许自动退款链路位置更新状态 → 风险拦截这时有一个关键分叉。用户问的是可以退吗如果模型直接说可以我帮你提交退款。这就是风险。因为工具返回里已经明确autoRefundAllowed false而且退款提交是写操作会改变系统状态。这时 Guardrails 应该介入。Guardrails 不是 prompt 里一句“请谨慎”。它应该包括工具权限分类 参数校验 输出检查 敏感信息过滤 高风险动作拦截 人工确认 审计日志在这个退款场景里Guardrails 可以这样判断submit_refund 属于 WRITE_REVIEW。 当前政策不允许自动退款。 需要图片凭证。 所以不能自动提交退款。 只能生成退款申请说明等待用户确认或人工客服审核。OpenAI Agents SDK 的 tracing 文档也说明agent run 中会收集 LLM generations、tool calls、handoffs、guardrails 和自定义事件方便调试、可视化和监控 agentic workflows。这说明生产级 Agent 不只是“能调工具”还要知道每一步有没有触发风险边界。Agent 的价值不是它能不能自己做更多事而是它能不能在该停下来的地方停下来。九、Step 9需要 Human Review 的动作必须暂停链路位置风险拦截 → 人工确认 / 继续执行 / 停止如果用户继续说那你帮我直接提交吧。系统不能直接提交。因为这是高风险写操作。这时 Agent Run 应该进入 Human ReviewAction 准备提交退款申请 Risk 写操作会改变订单售后状态 Decision 暂停等待用户确认或人工客服审核LangGraph 的 interrupts 文档描述了类似机制interrupt 可以在指定点暂停 graph execution等待外部输入后再继续触发中断时LangGraph 会通过 persistence layer 保存当前 graph state直到恢复执行。LangChain 的 Human-in-the-loop 文档也提到当模型提出可能需要审查的动作比如写文件或执行 SQLmiddleware 可以暂停执行并等待人类决策图状态会被保存之后可以 approve、edit、reject 或 respond。这说明 Human Review 不是“弹窗确认”那么简单。它背后需要暂停当前 Run 保存当前 State 展示待执行动作 展示风险原因 等待用户或人工审核 根据审核结果继续、修改或终止没有状态保存就无法安全暂停。没有状态恢复就无法从人工确认后继续执行。十、Step 10生成最终回答但保留证据和限制条件链路位置最终回答 / 人工确认 / 继续执行在信息足够、风险判断完成后Agent 才能生成最终回答。一个更合理的回答是你的订单已签收 3 天仍在 7 天售后窗口内。 但因为商品破损需要上传图片凭证。当前政策不支持自动退款我可以先帮你生成退款申请说明提交前需要你确认或者转人工客服审核。这个回答和普通模型回答的区别是它没有凭常识直接说“可以退”。 它基于订单状态和售后政策。 它说明了限制条件。 它没有越权执行退款。 它把高风险动作交给用户确认或人工审核。这就是 Agent Run 的结果。不是“模型答得更像客服”而是系统在边界内完成了任务推进。十一、Step 11Trace Log 记录整次执行过程链路位置记录运行轨迹最后一次 Agent Run 必须被记录。你至少要能复盘这些信息Run ID 是什么 用户原始问题是什么 识别出的 Goal 是什么 初始 State 是什么 模型做了哪些决策 调用了哪些工具 工具参数是什么 工具返回了什么 State 如何更新 Guardrails 是否触发 是否进入 Human Review 最终回答用了哪些证据 整个过程花了多少 token、成本和时间如果没有 Trace LogAgent 出错后你只能看到最终回答。有了 Trace Log你才能判断错在目标识别 错在工具选择 错在工具参数 错在权限检查 错在工具返回 错在 State Update 错在 Guardrails 错在最终生成真实业务不只关心“这次回答对不对”。更重要的是如果错了我能不能知道错在哪里。十二、一次 Agent Run 最容易断在哪些地方第一目标识别错误。用户问的是退款系统误判成物流查询后面所有步骤都会偏。第二工具选择错误。明明应该先查订单却先查售后政策导致回答缺少订单上下文。第三权限检查缺失。模型请求查询订单应用没有检查订单是否属于当前用户这是典型越权风险。第四Observation 不可信。工具返回字段不完整、错误不明确、结果未脱敏都会影响后续判断。第五State 没有更新。工具结果没有进入状态模型下一轮可能重复调用工具或者忘记刚刚查到的信息。第六Guardrails 太弱。系统只靠 prompt 限制模型没有在工具权限和业务规则层做硬拦截。第七高风险动作没有人工确认。提交退款、发邮件、修改用户资料、执行 SQL这些都不应该被模型自动完成。第八没有 Trace Log。一旦出错无法复盘也无法改进。这些问题不是“模型不够聪明”导致的而是 Agent Run 的工程链路没有设计好。十三、最后总结一次 Agent Run 不是一次模型调用。也不是一次 Tool Calling。它是一条完整的任务执行链路用户目标 → 当前状态 → 模型判断下一步 → 请求调用工具 → 权限检查 → 执行工具 → 返回观察结果 → 更新状态 → 风险拦截 → 最终回答 / 人工确认 / 继续执行 → 记录运行轨迹这条链路里每一层都有自己的职责。模型负责判断下一步。工具负责连接外部系统。State 负责记录当前任务。Observation 负责反馈真实结果。Guardrails 负责限制风险。Human Review 负责接管高风险动作。Tracing 负责让过程可复盘。所以Agent 的价值不是“会调用工具”。真正的价值是它能在状态、工具、反馈和权限边界内把一个多步骤任务稳定推进到可交付结果。参考资料[1] OpenAI, Running agents - OpenAI Agents SDK.[2] Spring AI Reference, Tool Calling.[3] Yao et al., ReAct: Synergizing Reasoning and Acting in Language Models.[4] LangGraph Docs, Interrupts.[5] LangGraph Docs, Persistence.[6] LangChain Docs, Human-in-the-loop.[7] OpenAI Agents SDK, Tracing.[8] OWASP, LLM06:2025 Excessive Agency.我是Ryan一个专注于可信AI应用工程的开发者我的个人技术博客研究如何让AI生成从“外观”走向“有证据、可追溯、可验证”。