给 AI 的 Agent 实现指南,可控 Agent 的关键

发布时间:2026/7/29 23:47:40
给 AI 的 Agent 实现指南,可控 Agent 的关键 好久没聊 Agent 了今天继续聊聊 Agent 的关键实现要点事实上一个 Agent 在日常生产里最主要的问题就是可控和可靠所以虽然理论上 Agent 就是 LLM Tools RAG 的简单组合但是实际上不同场景有很多基础细节需要处理比如能不能正确理解了用户目标为什么选择这个工具 A 而不是 B 参数缺失时会追问还是重试工具失败后会修复和降级吗删除、退款、发邮件、改配置之类的动作可不可以被权限和确认机制拦住长任务中断后怎么从检查点恢复记忆会不会过期、冲突和被污染系统出了问题怎么定位是检索、规划、参数、工具还是模型生成的问题这个些问题其实我们也聊过很多次基本就是一个完整的 Agent 至少包含六类能力目标理解、任务规划、工具使用、状态与记忆、执行反馈、安全与评测。AI 模型确实是 Agent 里关键的决策组件但是决定系统是否可控和可靠的基本都是外部的工程边界。举个例子比如现在要做一个「合同助手」 的 AI Agent 那么这时候用户可能提出找出上周老板发来的合同查看付款条款整理成一段话准备发给财务。这种场景需要的就是一整条任务链比如理解“上周”“老板”“那个合同”这些上下文实体搜索邮件和识别候选附件读取和解析对应合同检索付款条款对条款进行完整和贴合原始内容的总结生成发给财务的草稿在真正发送前请求用户确认然后进入邮件和发送那你觉得这个任务里应该怎么做合适一般来说整个「合同助手」 的 Agent flow 应该类似这样有动态规划的 Agent 也有固定流程 workflow 进行组合实际上这样是生产环境最常见的混合实现Workflow 决定可执行的轨道Agent 负责轨道内的语义判断和动态选择。然后前面的图我们从外部看从内部看它可以被拆成个多个层级入口层身份、租户、会话、请求标准化路由层识别意图、风险和任务类型编排层维护状态、预算、检查点和下一步规划层拆任务、选择工具、判断缺失参数上下文层装配当前状态、知识、记忆和工具说执行层校验、授权、确认、幂等、调用与熔断验证层判断工具结果是否可信、任务是否完成输出层生成带证据、可解释、符合格式的最终结果横切能力安全、审计、评测、可观测、成本治理基本上一个最普通的 Agent 也都会具备这样的层级能力因为要生产可靠和可控Agent Loop 就不能只是「思考—行动—观察」这样简单的 Loop 业务上肯定是需要理解目标 → 读取状态和上下文 → 生成候选计划 → 选择受限工具 → 参数与权限校验 → 必要时请求确认 → 执行工具 → 归一化结果 → 验证是否满足完成条件 → 未完成则重新规划完成则输出然后在这条链路里每一步都可能出现失败所以你需要把错误当成正常分支处理保证每一次至少有结果反馈。一、意图识别这个其实一直是老生常谈的东西用户问的问题比如前面的 「找出上周老板发来的合同查看付款条款整理成一段话准备发给财务和。」 你肯定是不能直接就发给模型处理。Agent 要做的是先进行意图识别意图识别的目标是在准确率、延迟、成本和风险之间做取舍和分类比如下面就是一个常见的意图识别分类场景也就是你需要根据你的业务看是需要怎么分成而「合同助手」 这种 Agent 就很明显存在确定性规则第一层可以做确定性规则用来适合处理一些高频、明确、低歧义的指令比如例如退出登录转人工重新生成取消当前步骤打开设置规则层必须明确并且精简主要目的是可以快速拦截最确定的一批请求如果规太多反而会导致变成屎山后面可能演化成更难维护的关键词和 if-else 集合。第二层可以做上下文路由因为很多真实表达脱离上下文会很难理解比如“就这个吧”“还是不行”“改成 300”“再试一次”所以这一层需要结合比如上一轮对话、当前页面和选中对象、当前任务节点之类的场景做路由也就是可以用一些轻量化本地文本小模型配合历史信息快速做语义的意图判断。第三层就是复杂任务理解和工具规划也就是复杂度太高或者匹配不上的最后才会进入大模型处理而就算到了这一层模型输出的也不能只是一个意图标签我们需要的应该是一个结构化路由结果例如{ intent: review_contract_and_prepare_email, entities: { sender_role: manager, time_range: last_week, document_type: contract, target_audience: finance }, missing_fields: [], risk_level: medium, confidence: 0.87, next_action: search_mail }而实际上在意图这里一直有个置信度的存在它的作用就是用来决定下一步怎么走一般来说置信度至少能触发三种不同策略高置信度/低风险直接路由中等置信度进入更强模型或补充上下文低置信度/高风险歧义向用户澄清比如“取消订单”和“取消预约”这种意图我们肯定不能靠模型去赌一个答案成功率是不是 90%高风险操作肯定需要 human on loop 操作就算匹配上了也需要进入澄清阶段。二、编排和状态机Agent 知道用户意图之后还必须知道自己做到哪一步这个状态你不可能说直接就用历史会话来判断因为聊天记录只有输入历史不存在完整的任务状态所以一个可靠的 Agent State 至少需要包含类似from typing import Any, Literal, TypedDict ​ class AgentState(TypedDict): task_id: str user_goal: str current_step: str status: Literal[running, waiting_user, completed, failed] collected_slots: dict[str, Any] selected_tools: list[str] observations: list[dict[str, Any]] evidence: list[dict[str, Any]] retry_count: dict[str, int] token_budget: int time_budget_ms: int pending_approval: dict[str, Any] | None在这里我们需要在状态里尽可能保存原始数据和结构化结果这样才能可控如果是一份 markdown 输出肯定是不行的需要一份结构化的数据才可以在不同节点复用同一份事实和状态。比如状态最大的作用就是明确和定义完成条件每个任务都必须有显式完成条件必需字段是否齐全关键工具是否成功证据是否覆盖问题输出是否通过 Schema是否存在未处理的高风险动作是否超过步骤、时间、Token 或费用预算比如「合同助手」的完成条件肯定需要包含合同来源已确认、付款条款有没有原文证据、总结和证据必须一致、邮件生成草稿、发送是否已经执行。然后还需要支持「检查点和持久化」能力因为长任务过程肯定会存在暂停和恢复比如等待用户补充订单号等待审批第三方接口暂时不可用进程重启或节点故障人工修改中间状态后继续运行支持在 Agent 保存这些检查点也是很关键的需求一般来说至少需要保存状态版本、已完成节点、待执行节点、工具结果摘要、幂等键和审批信息。然后最后就是「恢复和执行」的支持这里最重要的就是「防止重复执行」 因为和 Coding Agent 不同Coding 你重复编译和重复扫描问题不大但是类似「合同助手」这种肯定不行系统从检查点恢复时可能某个节点已经运行过了但是当时我们没等待结果所以所有具备有副作用的操作都要考虑幂等发送邮件使用幂等键数据更新使用条件更新或 upsert支付和退款保存业务请求号创建记录前先检查是否已存在审批前不执行不可逆副作用这部分其实就和 Agent 没直接关系更多是业务后端的能力和状态同步设计。三、工具系统工具其实就是 Agent 里的业务抽象也是一个 Agent 的价值和智力表现但是定义工具也不是说就写一个 funciton call 就完事了它本身也需要一套可靠流程支持一般来说Agent 里的工具类似一份契约你需要给工具定义和准备好一整套的定义比如名称和版本适用场景与禁用场景输入 JSON Schema输出 Schema权限要求风险等级是否有副作用需不需要支持幂等超时、限流和重试策略可能返回的标准错误码比如一个工具定义可以类似from typing import Literal from pydantic import BaseModel, Field ​ class SearchMailArgs(BaseModel): sender_role: Literal[manager, finance, customer, unknown] start_date: str Field(descriptionISO-8601 日期) end_date: str Field(descriptionISO-8601 日期) attachment_type: Literal[contract, invoice, any] contract max_results: int Field(default20, ge1, le50) ​ class ToolProposal(BaseModel): tool_name: Literal[search_mail, read_attachment, extract_clause, create_draft] arguments: dict expected_result: str risk_level: Literal[read, write, high_risk]当然在这里 Schema 只保证执行结果的结构但是结果是否正确还需要后续判断比如日期可能格式合法但范围错误金额可能是数字但超过权限邮箱可能合法但属于错误收件人这些都需要 Schema 校验在进行有业务校验。其次就是工具匹配和检索前面我们说的意图拆分大部分为的就是匹配上合适的工具所以工具最好能做到尽可能精准如果模型上限不是 Top 规则也做不到工具精细化区分那么工具一定不要太多。比如一次性把几十或上百个工具暴露给模型大部分时候只会增加误选和参数混淆所以一般来收在 Agent 会提前先检索工具然后再注册给这次任务的大模型比如可以根据意图和领域筛选工具集合根据用户权限删除不可用工具根据当前状态排除不合适工具只向模型暴露最相关的少量工具然后在执行前都需要做格式校验、业务校验、权限校验和风险确认这也是工具执行的基本礼仪。def execute_tool(proposal, context): args schema_registry.validate(proposal.tool_name, proposal.arguments) policy.authorize(context.user, proposal.tool_name, args) policy.validate_business_rules(context, proposal.tool_name, args) ​ if policy.requires_confirmation(proposal.tool_name, args): return pause_for_human_approval(proposal, args) ​ idempotency_key build_idempotency_key( context.task_id, proposal.tool_name, args ) ​ return executor.run( tool_nameproposal.tool_name, argsargs, idempotency_keyidempotency_key, timeout_ms10_000, )另外就像前面说的意图置信度和风险工具也需要有风险评级或者说前面的意图风险基本就是来自工具风险比如等级典型操作默认策略R0 纯推理分类、摘要、改写可自动执行R1 只读查询订单、搜索邮件、读取文档授权后自动执行记录审计R2 可逆写入创建草稿、添加标签、保存临时配置可自动或轻确认必须幂等R3 高风险写入发邮件、退款、删除、转账、执行脚本、修改生产配置强确认、最小权限、完整审计R4 禁止或隔离超出业务授权、跨租户访问、敏感批量操作直接拒绝或转人工甚至在用户 UI 上我们可能需要展示接下来将调用什么工具、操作哪个对象、影响范围、是否可撤销、关键参数是什么之类的展示。然后工具肯定会有执行失败的时候这里失败的错误也必须结构化比如{ status: error, error_type: MISSING_ARGUMENT, retryable: false, field: contract_id, message: 缺少合同标识需要用户选择候选合同, suggested_action: ask_user }一般来说常见错误分类节点错误超时、限流、网络抖动可指数退避重试模型可修复错误参数格式错误、缺字段可反馈后重规划用户可修复错误缺少订单号、候选对象不唯一应追问权限与策略错误不可重试应解释并终止永久业务错误订单状态不允许取消不应反复调用系统性错误工具连续失败触发熔断和告警有错误分类和评级然后才能够对错误进行重试重试的次数也可以按工具的幂等性、错误类型、时延预算和业务后果配置。高风险操作肯定是允许重试次数为 0。四、结构化输出结构化我们前面一直强调需要在 Agent 内部流转和持有但是模型输出结构化也是有讲究的一般 LLM 输出 JSON 时常见问题会有夹带解释文字、Markdown 代码块、字段缺失、类型错误、截断、枚举越界和语义错误。这些都是很常见的问题所以兼容和自动处理错误就需要一个可靠的 JSON flow 支持比如明确的输出契约 → 模型原生 Structured Output / Function Calling → 检查停止原因和截断 → JSON 解析 → Schema 校验 → 业务语义校验 → 有限修复 → 带错误信息重试 → 降级或拆分任务一般来说肯定优先使用模型原生结构约束比如支持严格 JSON Schema、Function Calling 或 Structured Output 的模型肯定是不能依靠 Prompt 要求“只输出 JSON”这种毫无保障的渣男语录。但是一般来说我们还是必须区分三种正确状态语法正确JSON 能解析结构正确字段和类型符合 Schema语义正确值符合真实业务和用户意图严格的 Schema 判定主要解决前两项语义正确就需要业务后续审查。然后针对语法正确和结构正确问题Agent 运行过程中肯定会出现错误所以我们可以增加多种方式进行修复和重试但是不要保证一定能修成功不然容易死循环。实际上 JSON 结构问题可以安全修复的通常只有明确的格式问题比如去掉代码块提取唯一 JSON 片段去掉尾逗号补齐可确定的末尾括号清理前后无关文本但是如果遇到这些问题一般不建议修复比如不知道模型本来想选择哪个枚举字段值在业务上矛盾输出被截断且缺失大量内容多个候选 JSON 无法判断哪个正确这时候应该直接判定失败然后重新请求或拆分任务重试直接忽略这一份 JSON 结果。另外不建议用 Agent 去处理又长又深的结构化数据如果数据层级又长又深那就需要进行拆分比如可以拆成先抽取事实再生成标签再做风险判断最后再通过程序合并不然截断概率和问题会很多拆分后也可以对每个子步骤独立校验和评测。五、RAGRAG 这个也是老生常谈的话题了按照 Agent 上的常见规则一般可以分成先保证找得到再保证排得对最后保证答得忠实也就是说我们虽然简单说RAG 不就是“向量库 Top K LLM” 么但是实际生产链路上一般至少包含解析、切分、索引、查询理解、多路召回、去重、重排、上下文装配、生成和引用。比如文档解析合同就是一个很典型的场景它需要保留原始结构因为普通文本可以按标题、段落和长度快速切分但是合同、技术规范、政策文件、表格和扫描件则需要更精细的结构化解析。所以对于文档Chunk 除了正文还需要保存文档 ID、版本和来源标题层级页码和段落位置生效时间权限标签内容类型与前后 Chunk 的关系然后再根据业务做资源分层比如“70% 普通文档、30% 高价值文档”这个就需要根据你的实际业务情况去尝试了。然后接下来要做的就是两件事召回和重排。在召回阶段一般可以做加法主要是为了避免关键证据出现遗漏比如可以组合向量检索处理语义相似BM25处理关键词、编号、专有名词Metadata Filter处理时间、部门、文档类型和权限Query Rewrite补充实体、同义表达和时间范围Multi-Query从多个角度扩展召回Parent-Child Retrieval小块匹配大块提供上下文然后重排阶段就需要做减法了召回较多候选后我们就需要用 Reranker 和规则特征排序比如与问题的直接相关性标题和章节匹配来源权威性时效性权限与租户是否包含完整答案所需的多个事实最后就是上下文装配把东西都拿到手之后就可以进行上下文状态这里一般就可以做一些二次优化比如针对每个来源控制可能的最大长度重复内容去除多跳问题的证据覆盖新旧版本冲突处理引用编号校对不可信内容与系统指令的隔离比如对于一个合同助手检索结果必须能追溯到具体合同、页码和条款不能只给模型一段失去来源的文本。六、记忆Agent 里的记忆一般来说可以分成短期状态、长期事实和外部知识结构上类似也就是一般来说可以做四层记忆例如层次保存内容典型存储生命周期工作记忆当前任务步骤、临时变量、最近消息Graph State / Checkpoint当前线程摘要记忆项目目标、关键决策、未完成事项摘要表或线程摘要中期语义记忆历史对话片段、代码讨论、事件向量库长期、可检索结构化记忆稳定偏好、项目配置、联系人、版本关系库 / KV / 文档库长期、可更新简单来说就是短期状态解决“当前做到哪一步”长期记忆解决“过去有哪些与当前任务相关的信息”外部知识库解决“组织拥有的事实资料”这几个东西需要分开存储不能混成一个向量库。而实际上记忆写入也需要策略用户角度肯定不是每句话都值得长期保存所以写入前至少判断这是不是长期稳定的信息是否用户明确保存有没有包含敏感信息和已有的记忆会不会重复或者冲突内容是不是只是临时假设有没有过期时间用户需不需查看、修改和删除比如项目从 Flutter 改为 Swift 后旧记忆就不能继续通过“当前技术栈”被召回所以根据业务形态我们需要保留版本关系过去使用 Flutter某天决策改为 Swift当前有效值为 Swift。最后还需要防止记忆污染比如从网页、邮件或工具结果中读取的内容可能包含恶意指令。所以外部内容只能作为数据不能自动升级为系统指令或长期偏好所以一般也会建议为记忆保存结构化信息比如来源、创建时间、确认状态、可信度、有效期、覆盖关系和敏感等级重要事实最好通过程序校验或用户确认后再写入。这部分其实还可以看《Claude Opus 5 系统提示词泄漏》的介绍Claude 就在它系统提示词设计了一套持久化 memory filesystem 规范。七、评测评测也是关键的实现Agent 开发里整个评测主要看的是执行轨迹一般来说可以比较完整的测评可以分成四级评测比如第一层组件评测单独测试意图识别准确率和澄清率工具 Top-K 命中率参数字段准确率JSON / Schema 成功率检索 Hit Rate、RecallK、MRR、NDCGReranker 排序效果权限和风险分类召回率第二层轨迹评测最终答案虽然可能对了但是你也需要关注过程是不是安全比如轨迹评测可以关注是否选择了必要步骤有没有调用了多余工具做没做先写后确认有没出现在缺参数时脑补是不是发生过循环有没有超过预算执行会不会有越权资源失败后恢复路径有没有走对第三层可以做结果评测比如关注任务完成度事实正确性引用一致性格式正确性是否满足用户约束第四层就是业务和运行指标比如一次任务成功率人工接管率用户澄清轮数P50 / P95 / P99 时延单任务 Token、模型和工具成本高风险操作拦截率重试率与熔断率用户满意度和问题一次解决率所以做 Agent 可能很快但是跑评测测试稳定性可靠性模型兼容性反而是最费时费力的一个过程。然后针对 RAG 的评测还要能反推故障层因为在 「合同助手」里RAG 出现问题是最大也是最容易出现的所以你需要知道 RAG 问题出现的轨迹trace 信息要支持反推故障层比如现象更可能的问题优先排查Context Recall 低关键资料没找回Chunk、Query Rewrite、混合检索、Top-KContext Precision 低噪声太多Reranker、Metadata、去重、查询理解Recall 高但 Faithfulness 低资料找到了模型仍在编生成模型、Prompt、引用约束、上下文冲突Faithfulness 高但 Answer Relevancy 低没乱编但答非所问意图、问题改写、Prompt 和完成条件工具调用成功但任务失败工具结果没有解决用户目标结果验证和重新规划离线高分、线上低满意度数据分布或业务目标不一致线上样本、任务定义、产品交互最重要的就是要建立完成的 Agent 测试集。八、可观测性 TraceTrace 就是 AI 调试 Agent 的最重要入口我们前面说了那么多轨迹说的就是 TraceAgent 必须记录完整轨迹。比如每次运行都记录trace_id / task_id / thread_id 用户与租户上下文 模型、版本、温度、Token 使用 路由结果、置信度和风险等级 状态快照和节点耗时 召回 Query、候选 Chunk、重排分数和引用 工具候选、最终选择、参数和 Schema 版本 授权、确认和策略判定 工具耗时、状态码、重试和幂等键 最终完成条件和失败原因 人工修改与用户反馈当然在日志上我们不能无边界保存 Prompt、邮件正文和敏感参数Trace 本身也要遵守最小化、脱敏、访问控制和保留期限比如关键看板可以包括任务成功率失败原因分布每个节点时延工具错误率平均步骤数和循环率单任务成本人工确认率和拒绝率RAG 召回与引用质量不同模型、Prompt 和工具版本的对比总而言之Trace 必须完整至于需不需要脱敏这个实际上看你业务。最后所以这些都是基础的 Agent 逻辑概念也是一个 「合同助手」需要的 Agent 能力介绍不管你是古法做或者 AI 做你都需要在类似基础上进行整体规划核心是怎么构建一套基于你业务的 Flow 和黄金测试框架。Agent 的好坏和效果必须有一套可以量化的指标而整个 Agent 的目标和作用就是让 AI 变得可靠和可控在代码 Agent 上你出现幻觉问题不大但是在合同、法务、购物场景一个幻觉或者逃逸操作带来的 P0 问题可就大了。