从AI对话Demo到可演进Agent平台:架构设计与工程实践
发布时间:2026/9/25 4:54:42来源:尧图网络
开篇从 AI 对话 Demo 到可演进的 Agent 平台这两年 AI 圈最热闹的词一个是“AI”一个是“Agent”。市面上 Demo 满天飞今天一个聊天机器人明天一个自动写周报的工具后天又冒出个能帮你订机票的智能体。但说句实话绝大多数 Demo 活不过三个月——因为从“能跑通的演示”到“能撑住真实场景的平台”中间隔着一条巨大的鸿沟。我自己就是从这个坑里爬过来的所以想写一个系列记录一下我是怎么把一个 AI 对话 Demo 慢慢磨成一个可演进的 Agent 平台的。这一篇是开篇先把整体思路、技术选型和最常见的那些“为什么这样做”讲清楚。这篇文章适合谁如果你刚接触 Agent 开发手头有个能对话的 Demo 但不知道怎么往下走或者你已经用 LangChain、Semantic Kernel 之类的框架搭过原型想搞清楚生产环境里的 Agent 到底需要哪些组件再或者你就是单纯好奇为什么有的 AI 产品看起来聪明有的看起来像个只会复读机的玩具——这篇文章都能给你一个比较明确的答案。我不打算写那种全是概念的文章咱们直接聊代码、聊架构、聊踩坑。先说清楚一件事Demo 和平台不是量的区别是质的区别。Demo 的核心目标是“证明可行”平台的核心目标是“保证可用”。后者需要你考虑并发、状态、可观测性、容错、版本演进、权限控制这些东西在 Demo 阶段完全不需要碰但一旦你想让 Agent 真正干活一个都躲不掉。接下来我会从设计思路、核心细节、实操过程、问题排查、平台化建议这五个角度把这个演进路径完整的拆出来。1. 整体设计与思路拆解为什么 Demo 必须死一次1.1 从“对话模型”到“Agent 平台”的本质转变先给 Agent 下一个我自己的定义Agent 大模型决策大脑 工具手脚 记忆经验库 执行环境工作台。Demo 阶段的 Agent 往往只做到了第一项也就是接一个大模型 API做个聊天界面用户说什么就回什么。这种 Demo 本质上就是一个“加了皮肤的大模型聊天框”它没有工具调用能力、没有上下文管理、没有任务规划更不用说多轮对话之间的状态保持。你可能会说这不就是 Chatbot 吗对它就是一个 Chatbot还不是 Agent。Chatbot 和 Agent 的区别在于Chatbot 是被动的用户问一句它答一句Agent 是主动的它能根据目标拆解任务、调用外部工具、根据执行结果调整策略、甚至在没有用户介入的情况下完成一个多步骤的复杂任务。从技术架构上说对话 Demo 只需要四个部分前端界面、后端 API、大模型接口、简单的会话存储。但 Agent 平台最少要有八层前端交互层、网关层、任务编排层、工具注册与调度层、记忆管理层、模型路由层、执行沙箱层、可观测性层。这不是我拍脑袋想出来的而是我在实际演进过程中一步步加上的——每加一层都是因为线上出了事故或者用户提出了真实需求。1.2 演进式架构的核心思路不为明天过度设计在搭建 Agent 平台之前我一直在想一个问题要不要一开始就上个完整的微服务架构Kubernetes、服务网格、事件驱动、多租户隔离全部一步到位答案是否定的。如果你的第一版就把这些全部安排上那大概率在三个月之后还是在写配置而不是在调 Agent。我的做法是演进式架构保持单体应用的简单性但通过模块边界的清晰划分为后续拆分成独立服务留好口子。具体到代码层面就是把对话管理、工具调度、记忆管理、模型接口封装成独立的内部模块每个模块有明确的接口定义模块之间通过事件或接口调用通信而不是直接共享数据库表。这样做的优势在于第一版可以快速上线验证业务逻辑后期当某个模块成为瓶颈或者需要独立扩展时再拆出去才是水到渠成的事情。这里有个关键的架构决策接口设计要面向接口而非面向实现。举个例子模型路由层不应该写死“调用 OpenAI”而是应该抽象出一个LLMProvider接口后面接 OpenAI、Claude、本地部署的开源模型、甚至自训练的微调模型都是通过实现这个接口来接入。我在前期吃过亏就是把模型调用写死在业务逻辑里后来想切换模型时几乎重写了整个对话模块。1.3 为什么“工具调用”是 Agent 平台的核心分水岭如果说大模型是 Agent 的大脑那工具调用就是 Agent 的手脚。为什么我把工具调用列为分水岭因为一个只能生成文本的 Agent和一个能查数据库、调 API、操作文件系统、发 HTTP 请求的 Agent完全是两个物种。前者只能做信息整理和文本生成后者才能真正参与业务流程。实现工具调用的技术路径主流是 Function Calling。大模型在生成回复时会同时输出一个结构化的工具调用请求通常是 JSON 格式包含工具名称和参数。后端拿到这个请求后执行对应的工具函数把执行结果返回给大模型大模型再基于结果生成最终回复。这个机制看起来简单但实际落地时有很多坑工具数量多了以后模型的选择准确率会下降工具参数复杂时模型容易生成格式错误的 JSON工具执行结果太长时上下文会被撑爆。我在设计工具调度层的时候做了一个关键决策给每个工具加上独立的超时控制、错误处理策略和重试机制。某个工具挂了不能拖垮整个 Agent 的执行流程。具体怎么实现后面实操部分会详细讲。2. 核心细节解析与实操要点Demo 阶段就要打好的地基2.1 消息协议设计别让前端和后端各说各话很多人觉得消息协议是小事后端返回 JSON 就好了前端拿到渲染就完事。但在 Agent 场景里消息不是一次性的它是一个持续演进的数据结构。我第一版 Demo 的消息协议就设计得太简单了就是一个{role: user | assistant, content: string}的结构。后来要支持流式输出、工具调用状态、多模态内容、内容引用、结构化中间结果改协议改到头大。我建议在最开始就设计一个稍微超前一点的消息结构{ id: msg_123456, session_id: session_789, role: user, content: [ {type: text, text: 帮我查一下上个月的销售数据}, {type: tool_call, tool_name: query_database, arguments: {table: sales, month: 2024-06}} ], metadata: { token_usage: 1200, latency_ms: 350, model: gpt-4o-mini, timestamp: 2025-01-15T10:30:00Z } }这个结构有四个好处第一content是数组而不是字符串将来要加图片、表格、工具调用结果直接加数组元素就行不用破坏原有结构第二metadata可以塞调试信息和性能指标生产排查问题非常有用第三session_id从第一天就留着后面做记忆管理和多轮上下文都是基于这个字段第四整个结构本身就支持流式更新的语义。这个协议我强烈建议在 Demo 阶段就定好不然后面改起来的成本是你想象不到的。我见过不少项目前后端接口改了五六版每次都是因为消息格式缺字段这都是前期设计偷懒的代价。2.2 大模型接入层的抽象换模型不换业务代码接入层抽象这事我再强调一次因为它实在太重要了。我见过太多人在代码里直接写openai.ChatCompletion.create(...)然后整个项目就死绑在 OpenAI 上了。不是说 OpenAI 不好而是说你把自己绑死了以后想换模型的时候就会非常痛苦——而现在的模型市场变化太快了今天一个开源模型登顶明天一个国产模型免费开放后天你老板说预算不够要换更便宜的你能直接换吗我的做法是定义一个LLMProvider接口然后为每家服务商写一个实现class LLMProvider(ABC): abstractmethod def chat(self, messages: list[dict], tools: list[dict] | None None, **kwargs) - ChatResult: pass abstractmethod def chat_stream(self, messages: list[dict], tools: list[dict] | None None, **kwargs) - Iterator[StreamChunk]: pass然后 OpenAIClient、AnthropicClient、LocalLlamaClient、ZhipuClient 各写一个实现类。注意ChatResult里不能只存响应文本还要存 token 用量、延迟、模型名、结束原因是正常结束还是达到最大 token 数被截断。这些元信息在 Agent 场景里非常关键因为你要根据结束原因决定是否要触发后续动作。这个抽象层还有一层隐藏作用做模型路由的灰度切换。比如新来一个模型你可以在线上先切 5% 的流量过去跑几天看下效果指标再逐步扩大。如果没有这层抽象这种灰度操作几乎无从谈起。2.3 上下文管理为什么你的 Agent 记忆力那么差聊上下文管理之前先想一个生活场景你去一家餐厅吃饭第二次去的时候服务员说“王先生您好还是老位置吗”你会觉得这家店服务很好。但如果服务员每次都问“您要吃点什么”你就觉得好像也没啥差别。Agent 也是一样的没有上下文管理的 Agent每次对话都是“第一次见面”用户会觉得自己在跟一个失忆症患者聊天。Demo 阶段的上下文管理很简单把对话记录全部塞给大模型。但到了生产环境你会遇到两个问题第一是成本问题上下文越长token 费用越高第二是效果问题上下文过长时大模型会“迷失在长篇中”注意力分散记住开头忘掉结尾。我推荐的方案是三层上下文管理短期上下文当前对话窗口最近 5-10 轮消息这是模型直接能看到的内容。中期记忆对历史对话做摘要每隔几轮对话对前面的内容做一次总结放入上下文。长期记忆把用户偏好、关键事实、历史决策提取成结构化的 Memory Record存入向量数据库需要时召回。基于长期记忆的召回我用的方案是把关键信息抽取成{key: value}对例如{用户偏好: 喜欢简明回答不喜欢长篇大论, 常用工具: [SQL查询, 图表生成]}然后用嵌入模型转成向量存储。召回时通过用户当前输入向量检索最相关的一批记忆记录拼接到上下文中。这个结构在 Demo 阶段不需要做全但至少要把基础数据结构设计好知道后面要往哪个方向扩展。换句话说不要在 Demo 阶段就做三层上下文但要在数据结构里留session_id、memory_refs这些字段为后面铺路。3. 实操过程与核心环节实现从单体到多智能体3.1 单体架构阶段先让一个 Agent 跑通完整闭环我第一次真正搭建 Agent 平台的时候没有急着上微服务而是在一个单体应用里写了完整的 Agent 执行逻辑。这个单体应用的核心是一个AgentRuntime类它把“人机对话”、“工具调用”、“上下文管理”串成了一个循环class AgentRuntime: def __init__(self, provider: LLMProvider, registry: ToolRegistry, memory: MemoryManager): self.provider provider self.registry registry self.memory memory async def run(self, session_id: str, user_input: str): # 1. 加载历史消息 messages await self.memory.get_context(session_id) messages.append({role: user, content: user_input}) # 2. 最多循环 5 次防止无限工具调用 for _ in range(5): response await self.provider.chat(messages, toolsself.registry.schema()) if response.tool_calls: # 3. 执行工具调用 for tool_call in response.tool_calls: result await self.registry.execute(tool_call) messages.append({ role: tool, tool_call_id: tool_call.id, content: result }) continue # 4. 如果没有工具调用直接返回最终回复 await self.memory.save(session_id, messages) return response.content raise AgentLoopExceededError(工具调用次数超出限制)这个循环是 Agent 执行的核心模式你去看 LangChain、AutoGPT、BabyAGI 等框架底层的逻辑都差不多。关键点就在第 5 行的for _ in range(5)——这一步是防止 Agent 陷入无限循环的保险丝。我见过太多 Agent 死在无限工具调用上没有这个限制的 Agent线上会把自己跑死账单也会飞起。工具调度层的ToolRegistry我用了注册器模式给每个工具加装饰器注册registry.register(namequery_database, description查询业务数据库支持 SQL 和自然语言) async def query_database(database: str, question: str, **kwargs): 执行数据库查询返回结果给大模型 ... registry.register(namesend_email, description发送邮件给指定收件人) async def send_email(to: str, subject: str, body: str, **kwargs): 发送一封邮件 ...第 5 行的self.registry.schema()是工具调用的关键——它会把所有注册的工具转成大模型需要的 JSON Schema 格式。这一步看起来简单但其实有不少细节比如工具的description写得越清楚模型选择正确工具的概率越高参数的格式越规范模型生成参数时越不容易出错。我在工具描述上吃过不少亏一开始写的都是“查询数据库”这种模糊描述后来学乖了每个工具描述都写成 “当用户想查询销售数据时使用此工具支持按日期范围、客户维度、产品维度过滤” 这种带明确使用场景的描述工具选择准确率一下子就上来了。3.2 工具调用链路数据怎么在模型和工具之间流转工具调用链路是 Agent 平台里最容易出错的一环我要重点讲一下数据流转的过程。假设用户说“帮我查一下最近一周的销售数据然后画个折线图发到邮件里”这个需求会拆成两个工具调用query_database和send_email中间可能还有一个generate_chart。整个流转过程是这样的大模型对用户输入进行意图识别输出两个工具调用的 JSON格式类似[{tool: query_database, args: {time_range: 2024-06-01~2024-06-07}}, {tool: generate_chart, args: {chart_type: line, x_field: date, y_field: sales}}]。后端拿到这个 JSON 后先校验工具是否存在、参数是否合法然后顺序执行这些工具有依赖关系时还可能并行执行。每个工具执行完返回一个结构化的结果比如query_database返回一个 JSON 数组generate_chart返回一张图片的 URL。后端把这些工具结果按顺序追加到消息队列中重新发给大模型让大模型基于所有执行结果生成最终的用户回复。这里有个细节工具结果追加的时候一定要带上tool_call_id因为大模型要求工具结果和工具调用一一对应。如果漏了对应关系模型会报 “Invalid tool_call_id” 的错误整个链路就断了。我见过太多人在这上面踩坑因为框架帮你做了这个关联一旦你手写链路就容易漏掉。执行链路设计环节有个优化我很推荐工具并行调用。大模型一次输出多个工具调用时如果它们之间没有依赖关系就可以通过 asyncio.gather 并行执行。比如“查数据库”和“查天气”这两个动作没有依赖可以同时跑能大幅缩短整体响应时间。但有依赖关系时必须串行比如“先查询数据库拿到数据再生成图表”后者依赖前者的返回结果。3.3 从单体到多智能体拆分的时机与方式很多人一上来就要做多智能体架构这是典型的过度设计。单体 Agent 能解决的问题没必要拆成多智能体。但你一定会遇到单体解决不了的时候。我自己判断的标准是当两个能力之间需要隔离开的时候就该拆了。举个例子我发现客服助手这个 Agent 同时负责“查订单”和“表单填写”两件事但“查订单”的模型配置需要低延迟、高准确率“表单填写”则更需要创造力和上下文理解。这两个能力挤在同一个模型配置下经常互相干扰——要么查订单太慢要么表单生成质量差。于是我把它们拆成两个 Agent分别配置不同的模型和参数再通过一个调度器根据用户意图把请求路由到对应的 Agent。多智能体架构下我需要加一个协调层。协调层有两种模式中心化编排有一个主 Agent其他都是子 Agent主 Agent 负责任务拆解和结果汇总和去中心化协商多个 Agent 通过消息互相协商。实际生产中大部分场景用中心化编排就够了。我在这个阶段引入了一个轻量级的任务分派机制主 Agent 接收用户请求拆解成子任务分派给对应的子 Agent子 Agent 完成后把结果返回主 Agent 整合最终答案。这个过程代码如下// 使用 TypeScript 示例生产环境我用的就是这个模式 type AgentUnit { name: string; capability: string; handle: Function; modelConfig: ModelConfig; }; class Orchestrator { private agents: AgentUnit[] []; register(agent: AgentUnit) { this.agents.push(agent); } async dispatch(input: string): Promisestring { // 第一步让主 Agent 决定如何拆解任务 const plan await this.plan(input); // 第二步按计划分派给子 Agent 执行 const results await Promise.all( plan.tasks.map(async (task) { const agent this.findAgent(task); if (!agent) return 未找到能处理任务 ${task} 的 Agent; return agent.handle(task); }) ); // 第三步汇总所有结果 return this.synthesize(input, results); } }这里我强烈建议也不要一上来就写 Orchestrator。先把单体跑稳线上有真实流量了再根据流量日志去判断哪些请求是单 Agent 搞不定的再引入多 Agent。拆分的时机一定是“业务驱动”而不是“技术炫酷驱动”。3.4 状态管理与持久化对话中断了怎么恢复Agent 平台的稳定性很大程度上取决于状态管理做得好不好。Demo 阶段对话状态都存在内存里进程一重启就全丢了。但在生产环境用户可能跟你聊到一半去开会回来继续聊你不能让他重新说一遍。我的做法是把状态分成两层对话层状态消息历史、会话 ID和执行层状态当前任务进度、已完成的子任务、待执行的工具调用。对话层状态存 Redis过期时间设为 7 天执行层状态也存 Redis但过期时间设为 24 小时因为一个任务的执行周期一般不会超过一天。Redis 里存执行状态的数据结构我用的是 JSON 字符串格式长这样{ session_id: sess_123, task_id: task_456, status: executing, current_step: waiting_for_tool_result, pending_tool_calls: [ {tool: query_database, args: {...}, status: done, result: ...}, {tool: generate_chart, args: {...}, status: pending} ], retry_count: 2, deadline: 2025-01-16T10:00:00Z }有了这个状态结构当用户的请求因为异常中断时新请求进来会先从 Redis 读取执行层状态判断上一个任务是否完成。如果发现status是executing并且current_step是waiting_for_tool_result就可以从上次断点继续而不是重新开始。这个机制在生产环境中非常有用尤其是遇到网络抖动、后端重启、模型超时这些意外情况时。4. 常见问题与排查技巧实录那些让我深夜加班的 Bug4.1 模型突然不调工具了怎么排查这是一个让我印象很深的线上事故。本来 Agent 跑得好好的用户说“帮我查天气”模型正确地调用了weather_api工具。突然有一天开始模型一直给出相似的回答就是不调用工具像是退化成了一个纯聊天机器人。排查了很久最后定位到是升级了模型版本后工具描述格式被改动模型解析工具 Schema 出了问题所以它“干脆不调用工具了”。排查工具调用异常我的经验是首先拉日志看模型输出的原始响应。如果原始响应里有tool_calls字段但没有触发执行那问题出在工具执行层如果原始响应里根本没有tool_calls字段那问题大概率出在模型侧——不是模型被降级了就是工具 Schema 格式不对或者描述语义不清晰。另外我还遇到过一种情况工具描述里出现了enabled: true这种配置某个版本的模型会把这个字段理解为“这个工具总是返回成功”然后就不执行了。这个问题的教训是工具 Schema 尽量保持简单不该加的字段不要加加了反而会混淆模型的理解。4.2 Agent 陷入无限循环预算被烧掉一半有一次上线后我们监控发现某个 Agent 的 token 消耗异常一小时烧掉了平时一天的量。排查发现是 Agent 陷入了“工具调用失败 → 重试 → 再失败 → 再重试”的循环模型不断地查询一个已经确定查不到数据的数据库因为工具返回的错误信息没有告诉模型“这个数据不存在不要重复查询”。这个问题的根源是工具的错误信息写得太笼统。当时query_database工具返回的错误是Error: query failed这个错误没有告知模型具体是哪个字段查不到、数据范围是什么、有没有替代方案。模型不知道数据不存在所以一直换种方式再查。解决方式所有工具必须返回结构化的错误信息明确告知错误类型、错误原因、建议替代方案。比如{ error: no_data, message: 在 2024-06-01 至 2024-06-07 范围内没有销售数据, suggestion: 尝试扩大时间范围例如查询 2024-05-01 至 2024-06-07 }这样模型一看就知道“哦数据不存在不是查询姿势不对”会停止重试转而给出合理的用户回复。这个改动上线之后Agent 的不再浪费 token 在无意义的重复尝试上。4.3 上下文爆炸对话超过 20 轮之后Agent 变笨了对话轮数增加后Agent 的效果变差这是很多人会遇到的问题。我遇到过最夸张的情况用户和 Agent 聊了大概 30 轮Agent 开始忘记用户最开始提到的约束条件开始自己编造信息回答内容前后矛盾。问题出在上下文管理上——把所有历史消息都塞给模型到了 30 轮时上下文里的历史消息已经几千个 token模型处理起来已经“糊了”。而且 token 费用也在飙升。我的解决办法是引入“上下文压缩”策略。每轮对话结束时对话历史超过一定长度我的阈值是 10 轮就启动一次压缩把前面的对话摘要成一个简短的summary消息放回上下文。同时保留最近 5 轮原始完整内容。# 压缩前 [system: 你是客服助手] [user: 我订单一直没到] [assistant: 您好请稍等我查一下订单状态...] [user: 订单号是 ABC123] [assistant: 好的查到了订单正在配送中...] ... 省略中间 25 轮 ... [user: 那优惠券什么时候能用] # 压缩后 [system: 你是客服助手] [user: summary 用户反映订单 ABC123 延迟我们已经告知正在配送中。用户对配送时效不满已经安抚并解释了原因。最近用户询问优惠券使用时间。 /summary] [assistant: 好的我来查一下优惠券的使用规则...]这个策略的效果立竿见影上下文长度控制住了模型不会被海量历史消息干扰响应速度也快了不少。代价是摘要过程多了一次模型调用但对比 token 费用的节省这个代价完全可接受。4.4 排查工具集Agent 可观测性很多 Agent 平台最缺的就是可观测性——你不知道用户跟 Agent 聊天的时候内部发生了什么出了问题只能靠猜。所以我在搭建平台的过程中坚持在第一天就埋点第一天就上追踪。每个会话、每个工具调用、每次模型请求都有独立的 trace ID通过 trace ID 能把整条链路串起来。我用的是 OpenTelemetry 标准把每个 Agent 执行环节的数据都打到集中式日志平台。具体记录以下字段会话 ID、用户 ID如果有模型的输入/输出 token 数量、响应延迟工具名称、工具调用的输入参数、返回值状态上下文压缩前后的大小对比每个环节的时间戳、耗时错误类型、错误堆栈有了这些数据我排查问题的效率提高了 10 倍不止。遇到问题不再靠猜而是直接看链路追踪找到瓶颈或报错点。这里也建议大家别想着等平台大了再补可观测性补的代价远高于一开始就加。埋点是最容易又最值钱的投入。5. 走向平台化的扩展建议Agent 平台还需要哪些组件5.1 模型路由与降级策略别让大模型当单点Agent 平台里的大模型调用是最容易出问题的一环限流、超时、内容审核拦截、价格变动、模型下架。如果你把大模型当作单点来用是真正的风险后果是线上必出故障。我的方案是做一个模型路由层支持三个策略按优先级路由优先使用高质量模型失败后自动降级到备用模型。按成本路由简单问题用便宜模型复杂问题用贵模型。按能力路由需要视觉理解的任务走多模态模型需要代码生成的任务走代码能力强的模型。实现降级逻辑的代码非常简单class ModelRouter: def __init__(self, strategies: List[RoutingStrategy]): self.strategies strategies async def route(self, task: Task) - ModelProvider: for strategy in self.strategies: provider await strategy.select_provider(task) if provider: return provider raise NoAvailableModelError() async def execute_with_fallback(self, task: Task): primary await self.route(task) try: return await primary.chat(task.messages, toolstask.tools) except Exception as e: logger.warning(f主模型 {primary.name} 失败尝试备用模型: {e}) backup await self.route_with_exclude(task, excludeprimary.name) return await backup.chat(task.messages, toolstask.tools)这个模块不长但它能解决的问题非常大。一个很典型的场景是高峰期大模型服务商限流没有路由层的平台直接报错给用户有了路由层的平台可以自动切换备用模型用户完全没有感知。5.2 Agent 评测体系没有评测就没有优化做 Agent 平台最难的不是写代码而是“怎么判断这次改动是变好了还是变坏了”。自然语言生成不像传统软件有一个明确的 pass/fail 标准。你改了一版提示词输出看起来好像更流畅了但也可能丢失了某些关键信息。这种情况下没有评测体系根本无法判断。我的做法是把评测体系拆成三层确定性指标工具调用成功率、错误率、响应延迟、Top-1 工具选择准确率。这些是硬指标可以直接跑自动化测试统计。内容质量指标回答的相关性、完整性、格式正确性、是否包含幻觉。这些指标目前主要依赖人工评估但可以借助另一套大模型来辅助打分。业务指标用户满意度、任务转化率、用户留存率。这些是最终衡量 Agent 价值的指标。具体到实现我开发了一套评测 runner每两天自动跑一次回归测试集。测试集里包含 100 个典型用户问题覆盖知识问答、工具调用、复杂任务拆解、多轮对话这几种场景。评测 runner 把 Agent 的输出和期望结果做对比输出一个分数。如果分数下降说明这次改动是有问题的需要回滚或者调整。评测集我用一个 JSON 配置管理[ { id: test_001, scenario: 查询订单状态, user_input: 帮我查一下订单 12345 的配送状态, expected_tools: [query_order], expected_keywords: [配送中, 预计送达], max_allowed_latency_ms: 3000, min_score: 0.85 } ]这个配置里expected_tools是关键它验证“Agent 是否选择了正确的工具”而不是仅仅验证“最后说什么”。这个评测体系帮我在后续改版中避免了很多次“感觉上变好了但实际上关键能力退化了”的陷阱。5.3 平台的 API 化让 Agent 的能力被其他系统集成平台要真正落地必须 API 化。我第一版 Agent 只有前端界面能用后来技术团队、运营团队都来问“能不能让你们 Agent 的能力接入到我们的系统里”我只能说抱歉然后回去加班加 API。API 设计我遵循几个原则所有接口都是异步的因为 Agent 执行可能耗时数秒不可能让调用方一直阻塞等待。通过 Webhook 通知任务完成Agent 执行完成后回调调用方传入的 Webhook 地址。有权限控制API Key 管理API Key 对应不同的工具权限和模型权限。举个例子用户查询插件的调用流程是POST /v1/agent/task # 创建任务传入会话 ID、用户输入 返回 { task_id: task_789, status: accepted } Agent 处理完毕后 POST https://customer-system.com/webhook/agent-result # 回调通知 返回执行结果、会话上下文、工具调用记录API 化之后Agent 平台从一个“只能内部使用的工具”变成了“可供全公司甚至外部系统调用的服务”这个转变是平台化最重要的体现。这个方向也是我认为 Agent 平台未来真正产生价值的地方——它不再只是个别产品里的一项功能而是整个业务体系里可以重复调用的通用能力单元。从 Demo 到平台不是一个单纯的技术升级而是一整套思维方式的变化。Demo 阶段你关心的是“能不能跑通”平台阶段你关心的是“能不能长期稳定地跑、能不能被别人集成、能不能在模型和工具快速迭代的情况下持续可用”。这条路没有终点模型在变、工具在变、用户需求在变Agent 平台也必须跟着变。这一篇先把整体架构、核心环节和常见问题讲清楚了后面的系列文章里我会展开聊工具调用深挖、评测体系建设、多智能体协作模式、记忆机制的进阶玩法这些方向。如果你也在折腾 Agent 平台欢迎一起交流你在架构演进中遇到的问题——因为我踩过的坑很可能你正在踩。
网站建设高端定制企业官网