福生无量摸鱼天尊

agent系列(一):实用的agent架构、应用、评估和未来

2026/01/19
37
0

0. 数模

最基础的抽象是:环境有状态s_{t}​,你能看到的是观测o_{t},你做动作a_{t}​,环境给反馈(比如奖励/成功信号)并转移到新状态。用 (PO)MDP 写就是:

s_{t+1}\sim P(\cdot\mid s_t,a_t),\quad o_t\sim O(\cdot\mid s_t),\quad a_t\sim\pi(\cdot\mid h_t)

其中 h_t=(o_{1:t},a_{1:t-1})是历史。一条运行轨迹(trajectory)就是:

\tau=(o_1,a_1,o_2,a_2,\ldots,o_T,a_T)

那么ReAct(Reason + Act)我们可以用一个很干净的建模方式理解:策略不只是直接输出动作 a_{t}​​,而是先产生一个内部推理/中间状态(可以记为z_{t}​,对应文本里的 reasoning),再基于它选动作:

z_t\sim\pi_\theta^\mathrm{reason}(\cdot\mid h_t),\quad a_t\sim\pi_\theta^\mathrm{act}(\cdot\mid h_t,z_t)

执行动作后环境回传新观测 o_{t+1},再进入下一轮。这种“显式把决策拆成可记录的推理 + 可执行的动作”会直接带来 可审计的轨迹:每一步为什么这么做、做了什么、结果如何都在日志里,因此更容易做可复现评估与调试。

1. 架构

agent架构无非是内外之分,内是单agent还是多agent,外就是sys的memory,context,tools之类的。

而单智能体 vs 多智能体,本质上是在回答:把“任务分解/验证/执行”的边界放在一个闭环里做,还是拆成多个角色协作做。在两篇综述[1,2]里,一个很清晰的切口是”作用域/协调/记忆/失败模式/评估指标”的差异:单智能体倾向于端到端闭环、几乎无协调成本;多智能体通过角色划分与调度,把复杂任务拆解到多个专职 agent 上,但引入新的协作与级联失效风险。

那我们如何考虑呢:

任务结构(可分解性 + 子任务异质性)看:当问题是“强耦合、需要共享同一份上下文、步骤不多且反馈回路短”的(比如一个可控工具集内的 ReAct 式推理-调用-检查),单agent更直接——上下文一致、控制流简单,端到端成功率更依赖一个 loop 的质量。反过来,当任务天然是“多阶段流水线”且子任务技能差异大(规划/检索/写作/审阅、或不同工具域的操作),多agent的优势来自模块化与可并行化:拆角色能提升覆盖度、可扩展性与对复杂多阶段问题的鲁棒性。

可靠性与错误形态看:单agent的主要风险是“单点失败”(模型一次偏航会把后续步骤都带歪),但它少了“协调错误”。多agent往往通过“交叉检查/审稿/辩论”来提高发现错误的概率,但综述也明确提醒:多agent会带来协调复杂度、激励与一致性问题,甚至在“共享盲点 + 聚合机制不稳”时放大错误;因此需要证据协议(引用工具输出、基于 trace 的批评、结构化投票/验证)与治理/可观测性来压住风险。

成本/延迟/可控性(系统 trade-off)看:多智能体几乎必然带来更多模型调用与上下文增长,隐性成本包括 retries、context growth,且评估更难(非确定性、长链 credit assignment、工具/环境波动)。所以如果你有明确 SLA(低延迟、低成本、交互要快),优先单智能体;如果你更在意“准确性/稳定性/审计性”,且愿意为此付出额外推理与协调开销,多智能体更划算

综上所述:

  • 任务耦合强、步骤少、需要快速交互 ⇒ 单智能体(端到端闭环,少协调)。

  • 预算紧/延迟敏感 ⇒ 单智能体起步,必要时再“按需升级”为多智能体(把 extra compute 留给难例/高风险)。

  • 任务可拆分、子任务异质强、要“规划-检索-产出-校验”流水线 ⇒ 多智能体(角色化带来模块化与覆盖)。

  • 更看重审计/可解释/可复现 ⇒ 多智能体 + 证据协议/trace/投票或 verifier;否则容易“协调复杂度换来不稳定”。

1.1. 系统模块

当前的agentic系统可以用五个变量模块来进行观测:

  • env/tools:智能体所交互的外部系统,例如:API、搜索引擎、计算器、机器人、数据库、软件工具或模拟环境。这些组件提供基于现实的信息,影响智能体的决策过程并决定智能体的最终结果。

  • 感知:将原始观测结果(工具输出、传感器数据、检索到的文档)转换为大语言模型结构化输入的机制。这可能包括文本解析、多模态解释或结果摘要。

  • agent(Reasoning与Plan):负责思维链推理、目标分解、工具选择和动作规划的核心认知引擎。在此阶段,大模型根据上下文和先前步骤决定下一步该做什么。

  • Memory:情景记忆或长期记忆可实现跨步骤或会话的持续性。示例包括向量数据库、草稿板和领域特定的知识库。近期关于检索增强生成(RAG)的研究表明,向量存储中的超参数优化、分块策略以及重排序机制对检索质量与系统效率均有显著影响,这对记忆增强型智能体系统具有重要意义。记忆支持长时程任务、身份一致性以及迭代优化。

  • Action:通过 API 调用、工具调用、代码执行、机器人控制或其他操作来执行计划。动作将结果反馈回环境,完成反馈环。这些智能体人工智能架构的组成部分在循环反馈环中运行,通过反复的感知-推理-动作循环实现持续学习和适应。

1.2. 抽象和自动化

把一个“看起来很业务”的需求抽象成 agent 问题,核心不是先想模型,而是先把它变成一个可交互、可验证的任务:

  • 任务目标(Goal)要写成可判定的终态,例如“工单创建成功并返回 ID”“代码修复后所有测试通过”“报告包含 X 个要点且每个要点都能指向证据来源”。目标越可验证,后面的评估和回归越容易。

  • 同时明确约束(Constraints)预算(Budget):比如“不得执行写入操作”“最多调用工具 20 次”“必须引用来源”“遇到权限不足必须停并上报”。这决定了 agent 能走的策略空间,也是后续安全治理的边界。

接着定义 agent 的“交互接口”,也就是你文章里要写清楚的三件事:

  • 状态/观测(State/Observation):真实状态 sts_tst​ 通常不可见(系统内部、网页 DOM、repo 状态等),agent 能看到的是观测 oto_tot​(页面信息、检索结果、日志、工具返回)。很多真实应用都是“部分可观测”的,所以你要强调:agent 的决策依赖“历史轨迹 + 当前观测”(比如最近的工具调用结果、已发现的证据片段、上一步失败原因)。

  • 动作(Action):动作不是“继续说话”,而是结构化的工具调用(search、open、click、run_tests、patch_file…),以及少量“对用户的澄清/确认”动作。动作空间最好通过 schema 固定下来(参数类型、权限级别、可 dry-run),这样工程上可校验、可审计、可评估。

  • 成功判据(Success / Verifier):不要用“LLM 觉得完成了”当成功。你需要一个 verifier:要么是环境硬判定(测试是否通过、表单是否提交成功),要么是可复核的规则(输出结构完整、每条 claim 都有证据 span),要么在不得已时才用 judge(并配合一致性检查/多次采样)。

把“需求”变成 (可交互的工具环境 + 可执行的动作空间 + 可验证的成功条件 + 明确约束与预算),这才是 agentic 系统能工程化的前提。

2. 最小落地

2.1. 最小伪代码

(a) 单智能体 ReAct(最小闭环)

def react(task, tools, budget):
    trace = []
    obs = tools.reset(task)

    while not budget.exceeded(trace):
        thought = LLM("reason", task=task, obs=obs, trace=trace)
        action  = LLM("act",    task=task, obs=obs, trace=trace, thought=thought)  # structured tool call

        ok, err = tools.validator.check(action)   # schema/permission/risk gate
        if not ok:
            trace.append({"obs": obs, "thought": thought, "action": action, "error": err})
            obs = {"type": "action_error", "msg": err}
            continue

        result = tools.execute(action)
        trace.append({"obs": obs, "thought": thought, "action": action, "result": result})

        if tools.verifier.is_success(task, trace, result):
            return {"success": True, "trace": trace}

        obs = result

    return {"success": False, "trace": trace}

这段伪代码在论文里要强调的点

  • ReAct 的“Reason/Act”不是装饰,而是为了让轨迹可审计、可调试;

  • validator/verifier/budget 是“实用系统”的三件套(没有它们就很难谈可靠与评估)。


(b) Planner–Executor(计划显式化 + 执行可回滚/可重规划)

def planner_executor(task, tools, budget):
    plan = LLM("plan", task=task)     # list of steps / subgoals
    state = {"task": task, "plan": plan, "mem": {}}
    trace = []

    for step in plan:
        if budget.exceeded(trace): break

        action = LLM("to_action", step=step, state=state)  # map step -> concrete tool call
        ok, err = tools.validator.check(action)
        if not ok:
            trace.append({"step": step, "action": action, "error": err})
            state["mem"]["last_error"] = err
            continue

        result = tools.execute(action)
        trace.append({"step": step, "action": action, "result": result})
        state["mem"][step] = result

        # hard verifier gate (e.g., tests pass / form submitted / artifact exists)
        if tools.verifier.should_replan(task, state, trace):
            plan = LLM("replan", task=task, state=state, trace=trace)
            state["plan"] = plan
            return planner_executor(task, tools, budget)  # simplest form of replan loop

        if tools.verifier.is_success(task, trace, result):
            return {"success": True, "trace": trace, "plan": state["plan"]}

    return {"success": False, "trace": trace, "plan": state["plan"]}

写作要点:Planner-Executor 的价值不是“先写个计划”,而是把系统变成:

  • 可插入强 verifier(硬门);

  • 可重规划(局部失败不至于全盘崩);

  • 更适合高风险工具(把“计划”和“执行权限”隔离)。


(c) 多智能体(分工协作 + 仲裁 + 审计)

def multi_agent(task, agents, tools, budget):
    plan = agents.planner.plan(task)
    workspace = {"task": task, "plan": plan, "evidence": [], "artifacts": []}

    partials = []
    for subtask in plan:
        if budget.exceeded(partials): break
        out = agents.worker.solve(subtask, tools=tools, workspace=workspace, budget=budget.slice())
        partials.append(out)
        workspace["evidence"] += out.get("evidence", [])
        workspace["artifacts"].append(out)

    review = agents.reviewer.critique(task, partials, workspace)  # find missing evidence / contradictions / risks
    if not review["ok"]:
        repaired = agents.worker.repair(plan, partials, review, tools=tools, workspace=workspace)
        partials = repaired

    final = agents.aggregator.summarize(task, partials, review, workspace)
    return {"final": final, "plan": plan, "review": review, "partials": partials}

写作要点:多智能体的收益来自“异质任务分工”和“治理边界显式化”(reviewer/aggregator),但也要承认它引入协调成本与级联错误,因此必须配:共享 workspace(证据包)、仲裁规则、预算、可观测性。

3.2. 系统 Pipeline 设计

(a) 数据面(离线)

离线数据面的目标是把异构知识变成可检索、可治理、可引用的统一节点层,为在线 agent 提供稳定证据接口。实用 agent 的知识与上下文来源往往高度异构(文档、代码、表格、网页、日志),因此需要离线 ingestion 将数据标准化为“节点(nodes)”及其元数据(来源、时间、权限、主题、哈希),并构建多类型索引(向量、关键词、结构化字段)。该方式与 LlamaIndex 的“ingestion—node 化—index—retriever—synthesizer”范式一致:在线请求不直接读取原始世界,而通过被治理过的检索层获得证据,从而保证可引用性、权限隔离与可追溯性。

(b) 在线推理面:Router → Context Builder → Plan/Act → Verify → Answer → Memory Writeback

在线 pipeline 的关键是“可升级但稳定”:低风险走轻链路,高风险自动升级并通过验证器贯穿执行与产出。

  1. Task Router(路由):先判断这是“纯问答 / 检索增强 / 需要工具执行 / 高风险动作”。低风险走轻链路,高风险自动升级到 Planner-Executor 或多智能体(带 Reviewer)。

  2. Context Builder(上下文构建):按任务类型拼上下文:检索证据(LlamaIndex QueryEngine/RouterQueryEngine 的风格),拉取用户偏好与历史,附上工具说明与约束。

  3. Core Loop(ReAct 或 Planner-Executor)

    • ReAct 更像“通用交互控制器”;

    • Planner-Executor 更像“可治理的流程引擎”;

    • 多智能体用于“异质子任务 + 需要审计/辩论/交叉验证”的情况。

  4. Verifier & Risk Gate(验证与风险门控):每一步工具调用前做 schema/权限/risk gate;每个阶段产物都能被 verifier 检查(测试/规则/证据对齐)。

  5. Answer Synthesis(回答合成):把证据包(evidence packets)转换成结构化输出;对关键结论强制带引用或可复核依据。

  6. Memory Writeback(记忆写回):不是把所有对话都存,而是只把“可复用且正确”的产物写回:例如成功轨迹摘要、可复用的 plan 模板、已验证的工具参数、稳定的知识节点链接。

(c) 评估与治理面:

可落地的 agentic 系统必须把端到端回归与安全治理产品化,否则性能与风险都不可控:

  • 每次迭代都跑一套端到端基准:成功率 + 成本/延迟 + 轨迹质量(有效动作、循环、连贯性代理)+ 安全事件(越权/泄露/不当工具调用)。

  • 关键不是“跑一次”,而是做成回归:提示词/策略版本化、工具 schema 版本化、环境快照或模拟器,保证结果可对比。

  • 对高风险工具,引入分级权限与人类确认点,把治理写进 pipeline,而不是写在“注意事项”。

3. 评估体系

一套最基础的 ReAct 评估可以这样搭起来:

先定义轨迹与动作有效性标注:对任务i的第j步动作 a_{i,j},环境/工具可以判定它是否合法,记w_{i,j}\in\{0,1\}。则全局动作有效率:

\text{ValidActRate}=\frac{\sum_{i=1}^N\sum_{j=1}^{T_i}w_{i,j}}{\sum_{i=1}^NT_i}

它直接衡量 ReAct的“Act”部分是不是在正确地调用工具/执行 UI 动作(少犯非法调用、参数错误、越权等)。

再量化是否在“兜圈子”:令\mathrm{uniq}(\tau_{i})为轨迹中访问过的独特动作/状态数,综述给出:

\mathrm{LoopRate}_i=1-\frac{\mathrm{uniq}(\tau_i)}{T_i},\quad\mathrm{LoopRate}=\frac{1}{N}\sum_{i=1}^N\mathrm{LoopRate}_i

这在数学上就是用“重复率”刻画规划/控制是否陷入循环(反复试同一个工具、在两个状态间振荡等)。

  • 最后量化“计划遵循/连贯性”:如果你有参考计划的P_i=(p_{i,1},\ldots,p_{i,M_i}),就能定义逐步匹配的计划遵循度:

\mathrm{PlanAdh}_i=\frac{1}{\min(T_i,M_i)}\sum_{j=1}^{\min(T_i,M_i)}\mathbf{1}\{a_{i,j}=p_{i,j}\}

这给了一个最直接的“轨迹像不像一条合理计划”的度量(当然更高级的做法会用编辑距离、图匹配或 LLM judge,但这个公式已经是一个可落地的基线)。

3.1. 约束 + 进度 + 结构代替标准agent plan

在当前的agentic评估体系中,现实里很多任务(网页操作、开放域研究、复杂代码修复)并没有唯一正确的步骤,所以基准往往不给或者没有参考planP_i,这就是“没有 reference plan”的含义。所以没有P_i 时,工程上通常把 coherence 拆成三种可计算的代理量(proxy):

(a) 约束一致性(constraint satisfaction)

把“任务规则/安全边界/工具 schema/业务约束”写成一组谓词c_{k}(\cdot)。对每一步动作或整个轨迹判断是否违反:

v_{i,j}=\mathbf{1}\{\exists k:c_k(a_{i,j},o_{i,j})\mathrm{violated}\}

给一个最基础的约束违规率

\text{ConstViolRate}=\frac{\sum_{i=1}^N\sum_{j=1}^{T_i}v_{i,j}}{\sum_{i=1}^NT_i}

直觉:如果 agent 频繁“做了不该做的事”(越权工具、参数越界、违背用户硬约束),那谈不上 coherent plan。

(b) 目标进度单调性(progress / monotonicity)

如果环境能定义“离目标有多远”的度量d(s_{t},g)(比如网页任务离终态的步骤数、代码任务离测试通过的失败数等),就能评估是否在有效推进

\Delta_{i,j}=d(s_{i,j},g_i)-d(s_{i,j+1},g_i)

然后统计正进度比例与平均进度:

\text{ProgPosRate}=\frac{\sum_{i,j}\mathbf{1}\{\Delta_{i,j}>0\}}{\sum_iT_i},\quad\mathrm{AvgProg}=\frac{\sum_{i,j}\Delta_{i,j}}{\sum_iT_i}

直觉:coherent 的计划应该在多数步骤带来非负进展,而不是“瞎试”。

(c) 结构连贯性(structure consistency):把轨迹压成“子目标段落”

把轨迹按“子目标”切成若干段\tau_{i}=\tau_{i}^{(1)}\|\ldots\|\tau_{i}^{(M)}。你可以用非常朴素的规则切分(例如每次工具类型变化、或每次关键状态断点),然后用两类指标描述结构是否合理:

  • 段内一致性:同一段里动作类型/工具类型不要乱跳(可用熵或切换次数)

  • 段间有序性:段序列不要反复回到已经完成的子目标(与 loop 强相关)

这其实是在没有P_{i}时,用“轨迹自身的低复杂度结构”替代外部计划。

3.2. 端到端评估

端到端(end-to-end)的 agent 任务性能评估是把 agent 当成一个带工具与环境交互的控制器:它需要在执行循环里观察→规划→调用工具→更新状态/记忆→验证结果,最后以任务是否真正完成作为主要信号(例如网页任务是否真的提交成功、代码修复是否真的通过测试),因为在这类场景里“成功”被定义为端到端结果而不是文本可信度。

因此评估数据通常是:N个任务,每个任务跑出一条轨迹\tau_{i}(长度T_{i}),记录最终成功s_{i}\in\{0,1\}、每步动作、工具返回、异常等。甚至连“发生工具失败后是否恢复成功”都单独量化:令F_{i}=1表示任务i至少经历一次工具失败,则恢复率被定义为

\text{RecoveryRate}=\frac{\sum_{i=1}^N\mathbf{1}\{F_i=1\}\mathbf{1}\{s_i=1\}}{\sum_{i=1}^N\mathbf{1}\{F_i=1\}}

这就是“端到端”的典型味道:把系统在真实干扰下的闭环行为当作评测对象。

之所以强调端到端,是因为 agent 的失效往往发生在“长链路执行”里:多步动作会放大早期小错误,外部 API/网页/工具本身也有波动,再叠加解码随机性,导致同样输入可能走出不同轨迹、复现困难。因此评估会被非确定性、长时序归因(credit assignment)、工具/环境变化、以及隐藏成本(重试与上下文膨胀)显著复杂化。

怎么评估?这类综述普遍把它当作多维度测量问题

  • end-to-end 成功率,

  • 效率/成本(时间、token、工具调用)

  • 工具使用正确性

  • 轨迹/过程质量与鲁棒性(在扰动、不同 seed、预算上限下的表现)

  • 安全与合规(例如违规工具动作、隐私泄露、人类介入率等)

它们还会给出更“系统化”的做法:同一任务跑多次 seed 统计方差/稳定性、在多种扰动下算 RobustSucc/WorstSucc 之类指标,并用 WebArena、ToolBench、SWE-bench、GAIA、AgentBench 等套件做压力测试以覆盖不同能力面。

现在工作里的核心是把评估做成“可回放的系统测试”:

  • 标准化工具 schema

  • 统一 trace/日志格式

  • 一个 evaluation harness 去驱动环境

  • 收集每一步工具调用与中间状态

  • 支持审计与复现

同时把提示词/策略当成可版本化工件配回归测试,保证迭代不会悄悄退化。为了控制风险与成本,常见策略是“快路径 + 验证路径”:低风险/常见请求走低开销链路,高风险动作触发更强校验、明确预算(时间/token/工具次数)与权限门控

所有优化都要求在端到端层面重新评估(成功率 + 安全 + 成本/延迟),而不是只刷某个组件指标。

参考文献:

[1] The Path Ahead for Agentic AI: Challenges and Opportunities 智能体人工智能的未来发展之路:挑战与机遇

[2] AI Agent Systems: Architectures, Applications, and Evaluation 人工智能代理系统:架构、应用和评估