Agent 的问题求解过程

The Agentic Problem-Solving Process

(Agent 的问题求解过程)

大模型要变成「Agent」,核心不是多了几个 API,而是多了一个循环: 它不再是「问一次 → 回答一次」,而是「不断思考、行动、观察,再思考」。

这套循环在文档里被拆成五步:

  1. Get the Mission
  2. Scan the Scene
  3. Think It Through
  4. Take Action
  5. Observe and Iterate

听上去很简单,但真正的难点在于: 每一步都涉及「信息怎么组织、谁来做决策、状态放哪、什么时候停」。下面按「工程视角」把这五步拆开。


3.1 Get the Mission:把“模糊的想法”收敛成“可执行目标”

一个 Agent 的生命周期,从「接到一个 Mission」开始:

“帮我搞定 X 这件事。”

这个 Mission 不一定是结构化的。可能是自然语言、一个事件触发、一个系统消息、甚至另一个 Agent 发来的委托。文档的例子是「帮我安排出差」或「有一条新的高优先级工单进来了」。

从工程上看,这一步至少要做三件事:

  1. 边界收缩:

    • 这件事的输入是什么?(用户提供了什么)
    • 这件事的输出期望是什么?(需要返回什么形式的结果)
    • 这件事的边界在哪里?(可以做到哪一步,就算「任务完成」)
  2. 规格化(Normalization): 最终你通常会把 Mission 变成一个结构化对象:

    {
      "goal": "track_order",
      "params": { "order_id": "12345" },
      "constraints": { "max_latency_ms": 5000 },
      "priority": "high"
    }
    

    上层看起来是自然语言,底层必须有一个统一 schema,否则多 Agent 协作时所有任务都变成“含糊其辞的聊天”。

  3. idempotency(幂等性): 真正的生产系统里,Mission 不一定只被执行一次,有可能:

    • 任务重试
    • 上游重复触发
    • Agent 崩溃后恢复 所以 Mission 通常要带一个全局 ID,并且后续的 Action 要保证「多次执行结果等价」。

在这一步,LLM 的作用更多是「理解用户意图 → 填好结构化任务」,而不是解决问题本身。


3.2 Scan the Scene:Agent 的“感知阶段”

拿到 Mission 之后,Agent 不应该立刻行动,而是先「看清楚现场」。文档里的描述是:

这个阶段会问:现在用户说了什么?我之前有没有做过类似的事?我的工具和数据里,有哪些可以用?

本质上,这一步是在做环境建模(building the situation model),包括:

  1. 短期上下文(Short-term state)

    • 当前对话历史
    • 本轮任务的临时变量(例如:已经查到的中间结果)
    • 已执行的 Action 与 Observation 列表
  2. 长期记忆(Long-term memory / history)

    • 以往同一用户的偏好、历史成功案例
    • 以往处理相似 Mission 的经验
    • 与任务相关的知识文档、配置、策略
  3. 可用资源(Capabilities)

    • 当前 Agent 拥有哪些工具(工具列表 + 参数约束)
    • 有哪些外部系统可访问
    • 当前权限、配额、成本预算

工程上,你通常会在这一步完成以下事情:

  • 跑一轮 RAG / 向量检索,把和当前 Mission 相关的文档、历史任务找出来;
  • 从状态存储(session store)中恢复之前的任务上下文;
  • 基于 Mission + 上下文,构建一个「场景描述」放进 LLM 的 context 里。

最终给模型的提示,大概会包含:

  • 任务描述(Mission)
  • 当前状态(State)
  • 已有信息(Facts)
  • 可用工具(Tools spec)

这一步做好,决定了后面「Think It Through」能不能站在正确的信息基础上思考;做不好,就会让模型在错误前提上发挥。


3.3 Think It Through:从“我要干什么”到“先干什么,再干什么”

这是整个循环中最关键的一步: Agent 要在这里完成任务规划(Task Planning)。

文档里强调,这不是一次性的“想一下”,而是一个「推理链条」,例如:

“要回答订单状态,我得:

  1. 先确认订单是否存在 → 查内部数据库
  2. 找到物流信息 → 再调物流 API
  3. 把结果整理成人能看懂的回答。”

几个重要点:

(1)大模型不是在“执行”,而是在“写计划”

这一步通常不会直接调用工具,而是让模型做两件事:

  • 构造一个高层计划(High-level Plan): 例如:

    [
      { "step": 1, "action": "lookup_order", "input": "12345" },
      { "step": 2, "action": "query_carrier", "input_from": 1 },
      { "step": 3, "action": "compose_answer", "input_from": [1, 2] }
    ]
    
  • 评估自己计划是否合理: 例如检查:是否遗漏必要的信息?是否有潜在风险(权限、费用、用户体验)?

很多现代框架会把这种「先想步骤,再执行」作为强制模式(类似 CoT / ReAct): 不允许模型直接“想到就调 API”,而是必须先输出计划,再由 orchestrator 决定真正要执行什么。

(2)粒度控制:一步多粗,一步多细?

规划有两个极端:

  • 规划得太粗:

    • “查一下信息 → 回答用户” 导致每一步都很模糊,工具调用难以落地。
  • 规划得太细:

    • “先 trim 字符串 → 再 lowerCase → 再匹配正则 → …” 导致每一步都像写代码,完全丧失了 LLM 的抽象优势。

工程上,通常会约定一个「任务级粒度」:

  • 每一步对应“一次工具调用”或者“一段连贯的文本处理”;
  • 不在计划里掰扯实现细节,而是描述「要完成的子目标」。

(3)局部最优 vs 全局最优

在这一步,Agent 其实是在做「局部最优的阶段性规划」: 它不会对整个任务做完美规划(那太贵,太难),而是规划下一小段路径,足够执行、足够安全即可。

你可以理解成:

计划是「滚动更新」的:每观察一次结果,就有机会重写后半段计划。


3.4 Take Action:从“文本里的计划”变成“外部世界的一次调用”

当计划确定后,下一步是「真正去做事」。

文档里的描述很简单:

Orchestrator 选择合适工具,发起调用,等待结果。

实现上,这一步其实是纯工程问题,但坑不少:

  1. 责任分离:谁来发起工具调用?

    • 一种做法:LLM 直接输出 JSON,包含要调用的函数名和参数,然后框架按这个调用。
    • 另一种做法:LLM 只输出“意图”,由 orchestrator 进行二次校验与映射(例如把自然语言转参数)。

    生产环境里通常会倾向第二种:

    • 安全
    • 可加额外校验
    • 工具接口升级时不必重训 prompt
  2. 工具调用不是“黑箱”,而是“可观测事件”

    每一次 Action 都应该被记录为一种标准事件,例如:

    {
      "mission_id": "M-001",
      "step": 2,
      "tool": "find_order",
      "input": { "order_id": "12345" },
      "timestamp": 1731560000
    }
    

    这样在后面的 Agent Ops / Tracing 中,你能回溯:

    • 这个 Agent 当时为什么调用了这个工具?
    • 输入是什么?
    • 花了多长时间?
    • 失败率如何?
  3. 失败是常态,重试是必需

    在真实世界里,Action 常常会失败:

    • 外部 API 超时
    • 参数不合法
    • 返回结构变化 这时候不能以「失败就结束」,而是要引导 Agent 进入“观察 + 反思”路径:
    • 识别失败类型(系统故障 / 业务限制 / 权限问题)
    • 决定是否重试、换工具、还是向用户求助。

3.5 Observe and Iterate:从“流水线”变成“闭环控制”

这是 Agent 与传统「工作流引擎」的关键差别所在: 工作流只会照既定流程走下去; Agent 会「看到自己造成的结果」,然后改变后续行为。

文档里的例子是:查完订单列表,拿到 tracking number,再去查物流状态,最后综合成一句话告诉用户。

从工程角度看,「观察 + 迭代」包含三个层次:


(1)把 Observation 真正写回 Context

调用工具的结果,如果只是打印日志,而没有回灌回大模型的 context,那就完全谈不上“智能”。

典型做法是:

  • 把每一轮的 (Action, Observation) 以结构化形式记录在「对话历史 / 任务状态」里;
  • 下一次调用 LLM 时,把最近几轮的 (Action, Observation) 拼进 prompt;
  • LLM 据此推断:下一步还需要什么信息,计划是否要修改。

观察不是简单的「给模型看看结果」,而是让模型能理解整个轨迹:

「我做了什么 → 得到了什么 → 这说明了什么 → 接下来要怎么改。」


(2)判断“是否已经足够好,可以收尾”

纯粹的“永远迭代”是没意义的,Agent 必须有一个「停机条件」:

  • 目标已经达到(例如查到了订单状态,并已向用户返回);
  • 继续行动收益有限(多一次确认,只是浪费);
  • 成本或风险超出上限(调更多 API 太贵或太危险)。

这件事情可以:

  • 由 LLM 在 prompt 中显式地判断:

    “根据当前信息,你认为任务是否已经完成?如果是,请生成 final_answer;否则,请继续规划下一步 Action。”

  • 也可以由 orchestrator 根据规则强制终止:

    • 最大步数
    • 最大时间
    • 最大成本

这两者常常是结合使用的: LLM 负责“主观判断任务是否完成”, Orchestrator 负责“客观兜底”。


(3)从一次任务的闭环,走向系统级持续改进

在单个任务层面,Observe & Iterate 是“局部闭环”; 在系统层面,它又是:未来优化的训练数据。

  • 每一条任务轨迹,都形成一条「问题 → 决策过程 → 行动 → 结果」的完整记录;
  • 失败案例可以喂给「评估集」和「LM Judge」,用于改 prompt、选模型、改工具设计;
  • 某些常见失败模式可以直接被抽象成规则:
    • 比如:某类错误要立即转人工;
    • 某类 API 如果常出错,应该在规划阶段就避免作为首选。

这部分在后面的 Agent Ops / 自进化章节会展开,但核心逻辑其实从现在就已经埋好:

每一次 Observation,都不是结束,而是未来优化的素材。


3.6 这五步,如何映射到具体系统组件?

如果用系统架构的视角看,五步循环大致可以这样对齐:

  • Get the Mission

    • 上层入口(API / Chat UI / 事件驱动)
    • Mission 解析与标准化模块
  • Scan the Scene

    • Session / State Store
    • Memory / RAG / Knowledge Store
    • 权限 / 配额 / 工具可用性检查
  • Think It Through

    • 大模型推理(带有规划模板的 prompt)
    • Plan representation(JSON / DSL / graph)
    • (可选)自我审查 / 规划评估
  • Take Action

    • Tool / Function 调度器
    • 安全沙箱
    • API / DB / 外部系统适配层
    • 调用日志 & 指标采集
  • Observe and Iterate

    • 状态更新(Action + Observation 序列)
    • 下一轮 LLM 调用的 prompt 组装
    • 终止条件检测(自动 + 规则)
    • 轨迹存储,用于后续评估和训练

你如果把自己的框架设计成「这五步各有清晰边界」,未来无论模型升级、工具变动、多 Agent 接入,都会比较可控;否则所有逻辑都塞在一个「大 prompt + 一堆 if/else」里,很快不可维护。


3.7 小结:Agent 的“智能”到底藏在哪一步?

如果非要一句话总结这一节:

Agent 的“智能”,并不在单次回答有多聪明,而在「如何管理自己的循环」。

  • Mission 解析决定「问题本身」对不对;
  • Scene 构建决定「站的起点」正不正确;
  • Think It Through 决定「路径选择」好不好;
  • Take Action 决定「手够不够长」;
  • Observe and Iterate 决定「能不能修正自己」。

LLM 是引擎,但真正决定系统上限的,是这个循环的设计。


如果你愿意,下一节可以继续 Part 4:A Taxonomy of Agentic Systems(Level 0–4),我们把不同「等级的 Agent」逐一拆开: 从「纯模型」→「连工具的 Agent」→「会规划的 Agent」→「多 Agent 团队」→「自进化系统」。