ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

AI智能体技术架构与工程实践:从ReAct模式到多工具编排

AI智能体技术架构与工程实践:从ReAct模式到多工具编排 1. 从“会聊天”到“会干活”智能体到底在解决什么问题这两年“AI智能体”这个词出现的频率越来越高但你要是真去问一圈会发现大家对它的理解差得挺远。有人觉得它就是能多轮对话的聊天机器人有人以为是能自动写周报的脚本工具还有人直接把它等同于大模型本身。我最早接触这个方向的时候也走过弯路踩过不少坑。经过几个项目的实际打磨我对智能体的理解更偏向一个“会调用工具、能拆解任务、能自主决策”的软件系统它更像是给AI装上了手和脚让模型从“动嘴”变成“动手”。先聊一个最基础的问题我们为什么需要智能体而不是直接调用大模型API我在做模拟项目X的时候最开始就是简单的“用户提问-大模型回答”效果其实还行。但一旦涉及复杂任务比如“帮我调研一下这个行业的竞争对手整理成表格再写一份摘要发到群里”单次对话根本搞不定。原因很简单大模型本质上是一个概率文本生成器它没有记忆长对话能力再强也有上下文窗口、不能执行外部操作不能真的去访问网页或者写数据库、也不具备持续的任务状态管理。智能体的价值恰好在这些缝隙里补位。智能体能做的核心事情可以归成三类第一是任务分解把用户模糊的意图拆解成可执行的步骤第二是工具调用通过函数或者API去操作外部系统第三是状态管理在多轮执行中记住“做到哪一步了、下一步该干什么”。这三件事串起来就是一个智能体的最小闭环。这篇文章我会基于实际做过的项目经验把智能体的技术架构拆开讲清楚从最外层的应用入口到核心的Agent编排引擎再到底层的模型接入、工具层和数据层每一层都结合具体的方案选型和踩坑经历来聊。内容适合两类读者一类是刚开始接触智能体开发想搞明白整体架构的初学者另一类是已经写过一些Demo但觉得自己的Agent“不够聪明、不够稳”想找优化方向的开发者。2. 分层看架构一个能落地的智能体由哪几部分构成聊架构之前先给一个全景式的分层视图。一个完整的智能体系统从下往上大致是基础设施层、数据与知识层、模型服务层、Agent核心引擎层、工具/插件层、应用与交互层。这六层之间有明确的调用关系但又不是纯粹的“上层依赖下层”有些层是横切的比如可观测性和安全审计会贯穿所有层。我用一个生活化的类比来解释这个分层。想象一个“智能管家”的运作过程管家Agent核心引擎接到主人的指令“把书房收拾好”应用层入口他需要先理解这句话的意思模型服务层结合自己脑子里对书房布局的记忆数据与知识层制定一个“先分类→再清扫→最后归位”的计划任务规划然后动手去做——搬书、擦桌子、扔垃圾工具层整个过程中他要知道自己做到哪一步了有没有出错状态管理与可观测。最后他向主人汇报“书房收拾完了另外我发现两本旧书可能卖掉了”结果生成与交互。回到技术实现上每一层都有自己的关键组件。基础设施层是最容易被忽视的。很多团队做智能体上来就写代码调模型结果到了部署阶段才发现GPU资源怎么分、服务怎么扩容、模型怎么缓存都没想好。我见过不少项目原型阶段用别人的API跑得很烫一上生产就各种超时、限流说到底就是基础设施层没设计。数据与知识层解决的是“模型不知道的事”和“模型记错的事”。大模型的训练数据有时间截止点企业内部的知识库它完全没见过这时候就需要RAG检索增强生成或者Fine-tuning来把私有知识接进去。RAG适合知识量大、更新频繁的场景Fine-tuning适合格式固定、风格要求严格的场景两者各有优劣后面会展开。模型服务层是智能体的“大脑”。这里要决策的事情包括用闭源API还是开源模型用单一模型还是多个模型各司其职模型的温度、上下文窗口、工具调用格式怎么配这些决策直接决定了智能体的“聪明程度”和“性格”。Agent核心引擎层是整个系统的技术难点所在。它负责理解用户意图、规划执行步骤、调用工具、观察结果、决定下一步动作构成了一个循环。常见的技术路线包括ReAct模式、Plan-and-Execute模式、以及目前比较火的Graph-based多智能体协作模式。这一层是后面第三、四、五节的重头戏这里先不展开。工具层是智能体能力的边界。没有工具的智能体只能“纸上谈兵”有了工具才能“动手干活”。工具的形式可以是大模型API调用Function Calling/JSON Mode、代码解释器、RPA脚本、数据库查询接口、Web搜索接口等。工具层的设计质量很大程度上决定了智能体的实际可用性。应用与交互层是用户直接接触的部分。可以是网页聊天框、IM机器人比如钉钉/企微机器人、命令行工具、甚至语音交互这些形式对智能体内部状态的要求差别很大。例如IM场景需要处理异步消息和会话中断恢复Web场景则更重视流式输出效果。这六层说完你大概能感受到智能体不是“一个大模型包打天下”而是一个系统工程。接下来我会挑几个技术复杂度最高、踩坑最多的层深入讲。2.1 工具选型之前的灵魂拷问你要做的是哪种智能体正式开始写代码之前有一件事必须先想清楚你的场景到底需要哪种智能体。我见过最典型的返工案例就是有人一上来直接上多智能体框架结果业务逻辑简单反倒被框架的并发和通信机制拖累原本两天的活儿拖了一周。从复杂度维度来分智能体大致有五种形态。第一是单轮工具调用型。用户输入一句指令Agent判断要调用哪个工具调用完直接把结果返回。比如“帮我查一下今天北京的天气”查询天气API就是一次调用。这种最简单不需要做状态管理本质上就是“意图识别工具路由”。第二是多轮任务执行型。用户给一个目标Agent内部要拆成多个步骤每个步骤可能需要不同的工具而且步骤之间有依赖关系。比如“帮我把这份Excel里的数据清洗一下剔除空行把金额列格式化成万元再生成一份图表”。这需要Agent维护一个中间状态知道当前执行到哪一步。第三是对话式任务型。在第二类的基础上用户可能中途介入、修正指令、追加需求。比如“停一下金额不要格式化了先给我看一下前10行数据”。这对Agent的上下文管理能力要求更高要能随时暂停当前计划、处理新指令、然后决定继续还是调整。第四是自主规划型。用户给一个模糊的长期目标Agent自己制定计划并逐步执行过程中可以自主调整策略。比如“帮我盯着这个竞品网站每周整理一次更新动态并生成简报”。这种需要有定时触发机制、跨Session的记忆、以及异常处理策略。第五是多智能体协作型。多个Agent各有分工通过某种通信机制协作完成复杂目标。比如“销售日报智能体”和“客户画像智能体”协同给市场部生成每日线索质量分析。这种需要设计通信协议、任务分发和结果汇聚机制。我做过的项目里第一类和第二类占了大多数。说句实在话很多第三类需求实际上是第二类加了一个“人工审核节点”没必要真做成全双工对话。这里给一个实用建议能用单Agent解决的就不要上多Agent能用流程编排解决的就不要让模型自由发挥。智能体越“自由”不可控性越大调试成本直线上升。3. 核心引擎细节ReAct模式、Plan-and-Execute与状态管理Agent核心引擎是智能体的“大脑”也是最需要吃透原理的部分。把它的工作方式作为一个“循环”来理解是最直观的。我将它拆成六个环节。第一是感知Perceive接收当前状态包括用户最新的输入、历史上下文、上一步的工具执行结果等。第二是思考Think结合当前状态分析“现在是什么情况、需要做什么”。第三步是决策Act决定执行哪个工具调用、传什么参数。第四是执行Execute真正调用外部工具并获取结果这一步通常由代码框架完成不经过模型。第五是观察Observe工具返回的结果作为新的“感知”进入下一轮循环。第六是终止Finish达成用户目标或达到最大轮数限制后生成最终回复。这整个过程就是ReAct模式——Reasoning和Acting交替进行。它的核心优点在于把“推理”和“行动”解耦每一步都既可以推理也可以行动像人类的思考方式。通过一个实际例子来看这个循环的实际运作。假设用户说“帮我查一下某家公司的最新融资动态顺便梳理一下最近三个月他们CEO的公开演讲观点”。Agent的第一轮会思考“用户要两件事我需要先搜索融资信息”然后调用Web搜索工具执行后观察返回的页面片段。第二轮思考可能是“搜索结果比较杂需要筛选一下时间再看一下CEO演讲的信息”于是再调用一次搜索或者调用新闻聚合API。第三轮如果没有找到演讲信息Agent会考虑换个搜索词或者直接搜索这个CEO的公开演讲如果还是找不到可能会给用户一个诚实的说明“CEO演讲信息未找到已搜索N个关键词建议补充信息来源。”这里有个容易被忽略的重点模型的每一次“思考”和“行动”都会被记录在上下文中这意味着上下文长度决定了Agent能“想多少步”。如果你的模型上下文只有4K那基本上做不了真正的多轮工具调用——搞两三轮就满了。这也是为什么做Agent开发建议选择长上下文模型。Plan-and-Execute模式与ReAct不同它省去每步推理过程。给定目标后Agent先综合生成一份完整计划再逐步执行。这种模式适合步骤相对明确的场景优点是Token消耗低、执行稳定缺点是不够灵活用户中途改变主意时调整成本较高。我用过的一个折中方案是主干用Plan-and-Execute做规划但每个执行步骤里用ReAct做异常兜底。具体来讲如果某个步骤执行失败自动退化成ReAct——模型查看错误信息自行调整工具调用参数进行重试。这种混合模式在实际项目中表现不错比单一模式更稳健。状态管理是Agent引擎里最容易被忽略的细节。很多时候Demo看起来“聪明”一旦恢复会话、覆盖长任务就出现“失忆”问题。我的做法是设计一个“任务状态对象”至少包含以下字段任务ID、用户ID、当前状态pending/running/paused/completed/failed、目标描述、执行计划、每一步的执行状态与入参/出参、已执行的中间结果摘要、错误次数与错误信息列表。这个状态对象有两个关键用途。一是支持暂停与恢复。比如一个分析任务要跑十分钟用户中途说要改需求Agent可以先暂停等用户改完再恢复执行。实现上就是把正在跑的任务状态持久化到数据库恢复时读取状态并继续。第二个用途是支持“智能体自我总结”因为上下文窗口有限Agent不可能把每一步原始结果都塞进上下文我的方案是每执行完一个步骤用模型生成一段不超过100字的摘要存入状态对象作为下一轮思考的参考信息。这招“中间结果摘要化”很好用能有效延长Agent的有效工作轮次。3.1 Function Calling让模型正确调用工具的三个关键设计工具调用能力是智能体真正能“干活”的基础。目前主流模型都支持Function Calling或者Tool Use中文社区常把这几个概念混着说这里统一一下OpenAI定义的是Function CallingAnthropic叫Tool Use开源社区沿用的词是Tool Calling。本质上都是同一件事——让模型输出结构化JSON参数来调用外部工具而不是输出自然语言。想让模型“正确地”调用工具最关键的是API描述文档的质量。这个质量直接决定成功率。我给一个自检清单。第一函数名要语义清晰。不要用func1、process_data这种名字模型不是读代码的高手函数名就是它理解“什么时候用这个工具”的第一线索。比如search_web_articles(query, date_from, region)模型一看就知道是搜索网络文章。第二参数描述要说清楚三件事这个参数的业务含义、有哪些合法取值、如果不传会怎样。例如参数region可填“中国大陆、港澳台、其他区域默认不填则不限区域”描述越具体模型越少胡乱发挥。第三要做到“用例子喂模型”。对于不太常用的工具在工具描述里附一个调用示例。有些API文档会示范“当用户想了解北京天气时调用get_weather(city北京, unitcelsius)”模型产生的幻觉就会大幅减少。最后再补充一个我踩过的坑Tool调用参数校验。模型生成的JSON参数虽然格式对但值可能是错的——比如日期写成“今天”或者把“最近三个月”解析成具体日期时因时区问题出错。所以我的建议是在工具层设立一个“参数规范化层”专门负责把模型输出的原始参数转换成工具真正需要的格式比如把中文时间词翻译成时间戳把模糊的数字范围换算成Upper和Lower。不要指望模型输出一次就对要做校验、修正、重试机制。注意如果模型的函数调用三次都失败建议记录下来形成一个“模型不擅长调用工具”的分析。很多问题其实是工具描述不清晰而不是模型能力弱。我遇到过一个案例同一个工具描述把“操作执行失败时请调用get_error_detail查询详情”改成“遇到错误时调用get_error_detail接口获取错误原因再根据原因决定是否重试”模型的重试成功率从62%升到88%。说明描述方式重大影响行为。4. 实操环节从零搭建一个多工具智能体前面把架构拆得比较细这节进入实战从头搭建一个具备“搜索、计算、数据库查询”三类工具的智能体用来完成一个复合型任务。我们以“从商品库中找出销售额排名前十的商品再搜索这些商品的相关新闻最后生成一份简报”为例。这个场景覆盖了智能体的核心能力数据库查询SQL工具、计算排名计算可以交给代码解释器、Web搜索抓取新闻、内容生成汇总简报。整个Demo用Python写Agent框架自己实现不依赖重型商业框架方便你理解底层逻辑。4.1 环境准备与工具定义使用Python 3.10以上的版本依赖包安装清单包括openai或anthropic看用什么模型、pydantic用于参数模型、flask或fastapi用于外部服务模拟、sqlite3自带的可以做数据库工具。我们需要定义三个工具。第一个是query_product_sales对应SQL查询工具负责执行SELECT语句。它的输入参数包括表名、列名和条件第二个是execute_python_code对应代码计算器用来做数据加工第三个是search_web_news默认调用一个搜索API接口。用JSON Schema来描述这三个工具示例如下。真实项目中工具描述会更长但结构保持一致。[ { type: function, function: { name: query_product_sales, description: 查询商品销售数据库返回满足条件的记录列表。表名为products重点字段包括product_id, product_name, category, total_sales_31d近31天销售额, total_orders订单量, updated_date。, parameters: { type: object, properties: { fields: {type: array, items: {type: string}, description: 需要查询的字段名列表例如[product_name,total_sales_31d]}, condition: {type: string, description: SQL WHERE子句条件不包含WHERE关键字。例如\category数码\}, order_by: {type: string, description: 排序字段例如\total_sales_31d DESC\}, limit: {type: integer, description: 返回记录的最大条数默认10} }, required: [fields, condition, order_by, limit] } } }, { type: function, function: { name: execute_python_code, description: 执行一段Python代码用于数据计算和聚合。代码在受限环境中执行可安全处理数据支持运行数学运算、列表推导、字符串处理。, parameters: { type: object, properties: { code: {type: string, description: 完整的Python代码代码通过变量data接收输入数据处理结果显示在最终返回中。例如data是list[dict]你想排序取前10可以写sorted_data sorted(data, keylambda x: x[total_sales_31d], reverseTrue)[:10]} }, required: [code] } } }, { type: function, function: { name: search_web_news, description: 根据关键词搜索互联网新闻返回标题、链接、发布时间和摘要片段。, parameters: { type: object, properties: { query: {type: string, description: 搜索关键词例如某品牌 最新新闻}, max_results: {type: integer, description: 返回结果条数默认5} }, required: [query, max_results] } } } ]这里我要强调一下execute_python_code的工具描述。为什么要在描述里给示例代码因为模型经常搞不清楚“我应该写完整的代码还是伪代码”给一个具体的示例它可以照着做。我实际测试中发现加了示例后模型生成的代码质量有明显提升不容易出现“只写函数定义忘记调用”的问题。4.2 Agent运行主循环自己写还是用框架如果你只是想快速验证可以用业界主流编排框架比如LangChain、LlamaIndex、AutoGen、CrewAI、Dify等它们内置了Agent循环和工具调用逻辑。但如果你想把底层原理吃透我强烈建议你至少手写一遍极简Agent循环。我手写版本的代码逻辑大致如下。def run_agent(user_query, tools, system_prompt, max_iterations8): # 初始化对话历史 messages [{role: system, content: system_prompt}] messages.append({role: user, content: user_query}) # 准备tool definitions从tools中提取 tool_schemas [t.get_schema() for t in tools] for step in range(max_iterations): # 请求模型允许调用工具 response client.chat.completions.create( modelMODEL_NAME, messagesmessages, toolstool_schemas, temperature0.3, # 工具调用场景温度不宜太高 ) msg response.choices[0].message # 如果模型没有要求调用工具说明任务完成直接返回 if not msg.tool_calls: return msg.content # 否则追加模型输出 messages.append(msg) # 遍历每个工具调用依次执行 for tool_call in msg.tool_calls: func_name tool_call.function.name func_args json.loads(tool_call.function.arguments) # 在tools列表中查找并执行 result execute_tool(func_name, func_args) # 把工具结果返回给模型result是字符串化后的数据 messages.append({ role: tool, tool_call_id: tool_call.id, content: json.dumps(result, ensure_asciiFalse)[:8000] # 防止超长截断 }) # 超过最大迭代次数强制收尾 return 已达最大步骤数未能完成任务请简化需求或补充信息。这个循环大概是Agent编排引擎的最核心骨架。有几个细节值得单独讲。第一关于temperature参数建议在做工具调用时设置低一点的温度0.2~0.4保证模型的输出更稳定、更少随机发散做内容生成和创意思考时再调高温度。我见过一个“机智”的办法同一套消息先用低温跑工具调用拿到结果后用高温生成最终文案效果挺好。第二关于工具结果截断我在代码里加了[:8000]的限制。这是实战中必须做的防御否则工具返回一个超长文本比如报告全文直接把上下文挤爆。更好的做法是对返回内容先做摘要再塞进上下文。如果是结构化数据只选关键字段透传。第三关于max_iterations这是一种“及时止损”机制。很多Demo失败的原因就是Agent陷入无限循环——调工具、报错、重试、再报错。循环上限建议设置在6-10之间防止成本失控。4.3 手动跑一遍这个案例把上述代码跑起来用户输入是“找出销售额前十的商品然后查一下它们最近的新闻生成一份简报”。大致执行的流程如下。第一步Agent先调用query_product_sales构造查询参数。我期望它能生成类似这样的参数fields[product_name,total_sales_31d,category]condition11order_bytotal_sales_31d DESClimit20。注意我设limit是20而不是10。为什么因为如果只取10名后面筛选时余地不够取20名再做二次排序更稳妥。这属于“给模型留容错裕度”的技巧纯靠模型自己领悟容易翻车可以在system prompt里提示“取数时可以适当多取最终再筛选”。第二步SQL查询返回20条商品记录后Agent调用execute_python_code对data做排序并选出前十。它生成的代码大致是sorted_data sorted(data, keylambda x: x[total_sales_31d], reverseTrue) top10 sorted_data[:10] result [{rank: i1, name: item[product_name], sales: item[total_sales_31d]} for i, item in enumerate(top10)] result第三步Agent需要拿着这10个商品名去搜索新闻。这里有个常见的操作一次性调用10次search_web_news还是合并为一次实际中我建议一次搜索一个商品但也建议控制并行度否则工具延迟会拖慢整体流程。我们的循环里每个tool_call都会串行执行10次搜索可能得等不少时间。一种加速办法是第一轮先查销量前3的商品生成简报后告诉用户“已覆盖前三剩余7个如果需要可以继续”这样更快且不会显得“不干完活”。第四步 Agent把新闻搜索的结果和商品销售数据汇总调用最终的文本生成能力也就是不让他调用工具在messages里给出所有数据让他写简报输出一份结构化的中文简报。整个过程跑下来你会看到模型“纠结”的一些痕迹。比如它会在一次回复里同时调用两个搜索工具或者搜索的时候把商品名搞错。这些都是正常现象调优方向就是我们上面说的工具描述优化和参数校验。4.4 可观测性设计没有日志排查的Agent就是一场灾难智能体项目开发中最容易忽视也最致命的是可观测性。普通API开发出错看堆栈就行Agent出错却要面对“模型哪一步想歪了”这种问题。没有完整的日志调试等于盲人摸象。我的做法是做一个“思维链追踪器”。每轮循环里把以下信息记录下来当前的步骤编号、模型的思考内容就是assistant message里的content部分有时为null、调用的工具名称和参数、工具返回的状态码和数据前500字符、加了这轮之后的总Token数、当前迭代到第几步。最后把这些日志转成可视化的时间线一眼就能看到Agent在哪一步走偏了。这里再分享一个从实际项目中总结的经验Agent的“错误”分两类——一类是模型理解错了比如该调A工具调成了B另一类是需要多次尝试才成功的“软错误”比如第一次搜索没结果第二次换关键词才搜到。后者其实是正常现象不要一看到重试就觉得是bug。我见过一个调优案例把“单次搜索失败就放弃”调整为“允许最多3次改词重试”任务的最终成功率从78%升到了94%。成本追踪同样不能忘。每一轮Agent循环都是多次模型调用Token消耗上升很快。建议在日志里记录每一轮的Tokens并设置“单次任务Token上限”超过上限就强制结束。5. 工具层设计从简单API调用到多工具编排工具层决定了智能体能力的边界也是最需要精细设计的一层。我用“三个原则”来概括工具层设计。第一个原则是“工具尽量细粒度”。不要设计一个超级工具把所有事干了。比如“处理数据”不如拆成“排序”“过滤”“聚合”“绘图”四个工具。细粒度工具的好处是模型更容易理解每个工具的适用场景参数也更简单。但也不是越细越好太细会导致模型需要连续调用很多次才能完成任务增加Token开销和失败概率。一般经验是保持每个工具的职责单一但入参设计要灵活。第二个原则是“返回结果要结构化且减幅”。工具返回给模型的数据最好用JSON格式而且要预先压缩。比如数据库查询返回100行数据如果全塞给模型上下文很快就爆了。我的做法是工具层内置“结果摘要函数”对于超过一定长度的结果先做聚合摘要再返回。比如查询销售额明细返回的是{total_records: 10000, top_10: [...], summary: 前三名是A、B、C}而不是直接给一万条记录。模型的决策需要的是关键信息和概要不是原始数据。第三个原则是“工具要有容错和可恢复机制”。工具执行失败时返回给模型的不应该只是一句“ERROR”。要返回有信息量的错误信息——失败了哪一步、可能的原因、建议的重试方向。比如“数据库连接超时5秒可重试或检查条件”模型就能据此调整。我在实际开发中专门写过一个“错误信息规范化模块”把不同工具的错误统一成标准格式智能体判断错误处理方式的准确率提升明显。5.1 工具与记忆要不要给Agent配一个外部记忆智能体的记忆力决定了它是“见过就忘”还是“越来越懂你”。我在做项目时越往后越发现记忆设计是提升体验的关键。智能体的记忆可以分三层短期记忆就是对话上下文已经聊过长期记忆是关于用户偏好的持久化信息需要写入数据库工作记忆是当前任务的中间状态前面讲的“任务状态对象”。三层记忆各自有不同的技术实现。长期记忆的实现我比较推荐向量数据库加RAG的做法。每次对话结束时用模型生成“用户关键信息摘要”比如“用户偏好简洁回复关注数据准确性”把摘要向量化存到向量数据库。下次对话开始时检索相关性最高的几条摘要注入到System Prompt里让模型“想起”用户是谁。这种“摘要化记忆”比直接存对话原文好用得多不仅省存储还能避免私密信息泄露。不过要注意的是长期记忆也是一把双刃剑。如果摘要写得不准确反而会误导模型。我踩过的一个坑是在某个项目里系统自动把“用户催过两次进度”摘要成了“用户性格急躁对回复速度高度敏感”结果后续每次回复都过度解释用户体验很差。所以我的建议是记忆摘要要过滤主观判断只记录客观事实和明确偏好。比如“用户在上次任务中要求用表格呈现数据”可以记“用户好像很急”就不应该记。5.2 多智能体协作一人干活和多人干活怎么权衡聊到多智能体很多初学者会兴奋觉得“越多越智能”。实际做下来我的看法是多智能体协作是“杀鸡用牛刀”的高频场景必须谨慎。多智能体系统的核心难点在于如何分工、如何通信、如何避免重复劳动和资源浪费。常见的方案有三种。第一种是主管-下属模式。由一个“主管Agent”接收用户任务分解后分发给多个“专家Agent”并行处理等结果回来后由主管统一汇总。这种模式适合任务可以明确拆分的比如“产品分析报告”—市场Agent整理竞品销售Agent整理销冠数据研发Agent整理技术动态最后由主管整合。第二种是流水线模式。任务按顺序经过多个Agent每个Agent处理自己负责的阶段再传给下一个。比如“数据清洗Agent → 数据分析Agent → 报告生成Agent”。这种模式需要提前设计好上下接口的数据协议任务流清晰。第三种是Debate模式。多个Agent扮演不同立场角色互相提出观点和质疑最后汇总。这种模式适合需要多角度分析的场景比如“对某市场策略做可行性分析”正方和反方Agent互相反驳最后给决策参考。我这边的建议是在多智能体架构中优先采用主管-下属模式因为这种模式对流程的控制能力最强也最容易实现断点重试。Debate模式Idear很酷但Token消耗大、结果波动大不适合生产环境。此外多智能体之间的通信机制建议采用“结构化消息”而不是自然语言聊天。自然语言通信容易产生歧义调试困难。结构化消息可以用协议约定消息字段比如{sender: scheduler, receiver: market_agent, task_type: research, payload: {...}}。6. 模型选型与接入方案闭源API、开源模型还是混合方案模型是智能体的大脑选型的决策树我把它总结为三个问题。第一你的业务对数据安全性要求多高如果数据不能出内网基本只能选开源模型或私有化部署的商业模型。第二你的场景对能力上限的要求多高例如复杂推理、长文档理解、多语言能力这些都对更顶尖的模型更友好。第三你的预算是多少Token成本要算细账。这里给一个成本核算的小示例。假设每天活跃用户1000人每人平均对话30轮每轮模型返回200tokens模型价格按常见闭源模型的中档价格估算。如果N轮中包含工具调用上下文实际tokens往往是输出的好几倍。我粗略算了一下这类场景如果用性能较强的模型一个月的Token成本可能要到一万块钱这个量级。如果你用的是开源模型自部署主要成本是GPU机器比如一张消费级显卡对于7B左右的模型推理够用但能否撑住并发要看工程优化水平。两种路线各有利弊没有绝对优解关键看场景和预算。团队不赶时间、技术储备够的话可以走混合路线主体用开源模型支撑大多数高频任务对复杂推理任务路由到能力更强的商业模型。这种“能力路由”架构用一个模型网关层实现统一模型接口底层可随时替换。我在项目中实践过效果不错。这里提一个模型网关层的设计统一输入输出格式、统一错误处理、可配置路由策略例如按输入长度/任务类型路由。有了网关后续换模型、做灰度都方便得多。6.1 开源模型与闭源模型在Agent场景下的优劣势对比在Agent场景下模型的核心能力不只是“生成自然语言”还包括严格遵循系统指令的能力、准确输出JSON结构化内容的能力、长上下文中的信息保持能力、以及最关键的“对齐工具调用格式”的能力。从我的实际测试看闭源商用模型在Function Calling的格式遵循上做得比较成熟官方API文档就写得很清楚很少出现工具调用格式乱掉的状况。开源模型的兼容性则要看具体型号有些开源模型虽然也宣称支持Tool Call但原生格式可能与你的Agent框架不完全兼容需要做一层适配。好消息是现在不少开源模型都在强化工具调用能力尤其一些国内的开源模型在中文工具描述理解上表现相当好效果不输闭源模型在中低复杂度场景下的表现。给一个非科学的经验值如果你要做的Agent复杂度在“单工具调用简单任务”级别开源模型完全够用如果是“多工具协同复杂推理长流程任务”建议优先考虑能力更强的商业模型或者把开源模型与商业模型混合路由使用。另外还有一个容易被忽略的点开源模型的上下文长度如果不是特别长长任务场景的可用性会受影响。选型时要注意不同型号的上下文窗口差异别拿短上下文的模型硬跑长任务。6.2 混合模型路由策略用低成本完成高质量任务混合路由是我在项目中实践过的一个有效方案。核心思想是不同的任务类型对模型能力的要求不同很多高频任务其实并不需要最贵的模型。设计一套路由规则把简单任务分流到便宜的模型上把难任务交给更强的模型总体成本可以下降很可观。举一个可落地的例子。某客户的智能体系统每天处理两类任务一类是“查快递单号”模型只需要从用户输入中提取出快递公司和单号再调用查询API这类任务简单用便宜的模型就够了另一类是“总结与分析市场报告”需要很强的理解能力用更贵的模型。路由规则可以这样设置根据任务长度和是否需要调用工具的参数数量来判断。如果用户输入短工具调用参数是枚举类用便宜模型如果用户输入长工具调用参数复杂、任务本身是多步骤的用贵模型。更精细的做法是先用便宜模型做初步判断如果遇到它没把握的情况再升级到贵模型。我在实践中用的是一种“置信度阈值”策略便宜模型输出时附带一个置信度分数低于阈值就转给强模型重跑。这个策略被验证过能在功能质量下降幅度很小的情况下节约不少Token成本。7. 数据与知识层RAG、Fine-tuning到底怎么选数据与知识层要解决的核心问题是让智能体“知道别人不知道的信息”。两个主流技术路线是RAG和Fine-tuning很多新手喜欢把两者对立起来我理解下来它们解决的其实是不同层次的问题。RAG全称检索增强生成核心流程是文档切块→向量化→存储到向量数据库→用户提问时检索最相关的块→把检索结果塞进Prompt→让模型基于这些信息回答。RAG适合的是“知识量巨大、需要实时更新、来源多”的场景。比如企业内部资料库、行业资讯追踪、客服知识库这些都是典型RAG场景。它的优点是更新知识只要换文档不用重新训练模型它的缺点是检索质量直接决定回答质量有引用链条可查但遇到检索不到的情况回答就会“胡编”。Fine-tuning全称微调核心流程是准备一批符合输出格式要求的高质量样本用这些样本对基础模型做增量训练让模型学会你要的风格和格式。Fine-tuning适合的是“输出格式固定、风格要求严格、推理规则明确”的场景。比如我要让模型严格按照JSON格式输出企业财报摘要或者模仿特定风格写营销文案Fine-tuning效果比RAG好。用一句话总结我的取舍经验RAG负责“给模型找材料”Fine-tuning负责“教模型怎么说话”。大多数智能体项目优先做RAG只有当你发现“材料都对但输出格式/风格总不对”的时候再考虑Fine-tuning。也有两者结合的方案先用RAG检索材料再用一个大模型或Fine-tuned小模型做格式化输出。7.1 文档切块的细节块长、重叠、索引优化RAG系统效果很受文档切块影响切块策略不同检索结果可能天壤之别。我把切块的关键参数和踩坑经验总结如下。块大小通常建议在300到800字之间设越大上下文信息越全但检索精度越差冗余噪音也越多设太小又容易丢失上下文语义。这里说的字是汉字字数英文Token差不多按比例折算。实际调优方法是拿一份代表文档多尝试几种块大小对比检索命中率再结合下游回答质量来选。块重叠指的是相邻块之间重合的部分一般建议设块大小的10%~20%。为什么需要重叠因为切块通常按固定长度切很可能把一个主题从中间砍断重叠可以在一定程度上弥补这种割裂。索引方面向量索引加倒排索引的混合检索效果往往优于纯向量检索。纯向量检索的优点是语义理解强缺点是遇到专有名词比如产品型号、人名容易飘BM25这类倒排索引的优点是精确匹配强缺点是理解不了同义语义。混合检索把两者结果用RAG Fusion方式融合实际效果稳定不少。再补充一个“父子块”方案。把长文档切成粗粒度的大块父块同时在内部切出更细的小块子块。检索时用子块匹配用户问题命中后把对应的父块整块送给模型。因为父块上下文信息更全模型能读到更完整的上下文子块命中又足够精准。这种方案在处理技术文档、学术论文时特别好用。7.2 向量数据库选型参考向量数据库是RAG的核心底座。给出按场景的选型参考表格。场景推荐方案理由Demo原型、数据量10万条轻量级方案本地文件型零运维、上手快适合快速验证中小型项目、数据量10万~500万条开源向量数据库性能与功能平衡支持多种索引大规模生产、数据量500万条成熟的数据库服务或自建集群高可用、水平扩展能力更强有完整监控已有业务数据库的团队在原有数据库上加向量扩展减少额外组件利用已有运维体系选型还有几个非功能性指标要重点看索引构建速度、查询延迟、过滤查询能力比如按时间、权限过滤、更新删除的实时性、以及与现有技术栈的集成便利性。不要只盯着基准测试的分数生产环境最烦的是运维问题。另外我建议如果数据量级在千万以下别自己搭分布式向量数据库用成熟方案够用了自建集群大多是给自己找事。8. 应用层与交互体验如何让智能体像一个靠谱的同事应用层是用户直接感知的一层也是智能体“像不像真人”的体验关键。我总结下来应用层设计有三个重点流式输出、意图确认与澄清、多轮会话管理。流式输出这个词可能有人不熟就是模型生成内容的同时一个字一个字地推送给用户。如果没有流式输出用户提问后要等几秒甚至十几秒才能看到完整回复体验非常“憋”。流式输出能让用户先看到文字在跳动感觉系统在“思考”。现在主流大模型API都支持SSE流式输出实现成本不高强烈建议启用。意图澄清是容易被忽视但很影响体验的环节。用户在提需求时往往信息不足比如“帮我看一下最近销售情况”这时好的Agent应该追问“是看哪个区域的什么时间段按销售额还是订单量”而不是瞎猜一通直接执行。我的做法是在Agent的System Prompt里明确指示“如果用户需求存在多种合理解释且会影响工具参数必须向用户确认选项而不是自行假设”。多轮会话管理涉及用户发言、Agent回复、工具调用中间状态全套的存储和恢复。这里的难点是实现“任意的深度链接恢复”。比如用户早上开了个任务中午关电脑走了晚上打开网页想接着聊系统应该能恢复早上的上下文和任务状态。这块需要对话存储的SessionID设计、状态持久化和检索增强。很多智能体项目在Demo阶段不重视这个问题一到真实生产就暴露了。8.1 输出结构化的最佳实践让模型“好好说话”智能体的输出不只给用户看很多场景还要给下游系统消费。这就涉及到结构化输出。比如Agent生成了“对这个商品的评估结论与三个建议”如果只是自然语言文本下游系统无法解析。更好的方案是要求模型输出一个JSON对象包含“结论”和“建议”等字段。强制JSON输出的技术方案有三种。一是用模型的JSON模式目前主流API基本支持你可以在请求参数里开一个JSON输出模式模型会保证生成合法JSON二是用Function Calling的“伪装调用”定义一个叫final_answer的函数明确函数参数就是一个结构体让模型把最终输出放进结构体里返回这是很常用的技巧三是用提示词强制约束比如“您必须以JSON格式回复格式为{...}”这个方法在开源模型上成功率不稳定需要配合解析后端的容错处理。我在实战中的经验是结构化输出的系统提示词最忌讳的是“又要自由发挥又要JSON格式”。模型一旦纠结怎么组织语言JSON就容易被破坏。正确做法是把系统提示词里的格式要求做到“死板而清晰”。比如你让它输出报告就规定好“只输出JSON不要附带任何解释文字不要使用markdown代码块”这样模型反而更稳定。8.2 人工审核与人工接管Agent不能完全放飞再智能的Agent总有自己搞不定的时刻。我强烈建议在应用层设计“人工审核节点”和“人工接管机制”。适用于以下场景涉及高风险操作比如批量删除数据、发送对外邮件、修改核心配置时Agent只负责生成操作计划和参数执行前必须等人工确认。技术实现上可以拦截Agent的工具调用在Agent引擎和执行层之间加一个“审批网关”对定义了“需要人工确认”权限的工具先把调用申请发到人工审核界面审核通过后再真正执行。这个机制用代码实现就几十行但对生产系统的安全性提升巨大。另外建议给智能体加一个“投降机制”当连续多次尝试失败、或者检测到任务超出能力范围时允许Agent主动把会话转移给真人员工。我的经验是在System Prompt里写清楚“当用户的需求涉及操作权限不足、系统能力不支持、或者连续3次重试仍未解决问题时请主动告知用户将转接人工支持并提供当前的执行日志摘要。”这能让用户感觉Agent有分寸而不是硬撑到底。9. 常见问题与调试思路Agent开发者的避坑手册代码写得再熟也会在Agent项目里遇到一堆“看起来玄学”的问题。这一节我按问题出现的频率整理一个速查表每一条都是实战中验证过的排查思路。症状可能原因排查与解决方向模型不调用工具总是直接文本回复工具描述不清晰或系统提示词没强调必须调工具检查工具description是否写清了“何时使用”在system prompt里强调“要获取数据必须调用工具”模型调用工具但参数明显不对工具参数描述不够具体或模型缺少示例参考为每个参数加上“合法取值”说明必要时给一个调用示例工具调用陷入了循环错误信息不够可操作模型不知道下一步怎么走让工具返回“原因建议动作”结构化错误信息限制最大迭代轮数第一次调用成功但后续上下文错乱消息历史拼接有问题检查tool消息是否与assistant的tool_call关联正确检查上下文顺序任务跑到一半模型“忘了”最初目标上下文太长早期信息被挤出窗口做中间结果摘要把关键目标固定在system prompt中每轮重述输出偶尔不是合法JSON模型能力边界使用JSON模式、Function Calling兜底或增加解析重试逻辑系统响应太慢几秒才回一句话链式调用太多、模型推理慢减少不必要的中间步骤考虑并行多个工具调用或用更强模型降低自我纠错次数成本飙升明显超出预算Token用量失控设“单任务Token上限”工具结果截断与摘要化用便宜模型处理简单任务排查Agent问题时最重要的一件事是“复现”。我建议在调试环境里把用户输入原样重现一遍观察每一步的工具调用和模型输出。不要试图靠经验猜问题Agent的状态空间太大猜不出来的。把日志打开逐轮分析比什么都管用。9.1 经验总结Agent开发者的三个习惯做了一年多的Agent项目我归纳出三个受益很深的工作习惯。第一个习惯是“先写测试用例再写Agent”。好的做法是先准备15~20条典型用户语料覆盖正常情况、模糊需求、异常输入三大类然后让Agent跑这些用例记录通过率和失败原因。每次调整系统提示词、工具描述或模型参数后都重跑一遍这组用例做回归。这样迭代的每一步自己心里都有数。第二个习惯是“让工具返回信息更丰富而不是让模型猜”。工具层是最好优化的地方把工具返回结果做得越规范模型的决策质量就越高。这一原则我屡试不爽。第三个习惯是“面向简化设计”。每当觉得Agent逻辑越来越绕时就提醒自己——用户要的是结果不是复杂度。简化任务流程、简化工具数量、减少中间环节往往可靠性显著提升。给Agent留的“自由发挥”空间要越小越好只有把不确定性压缩到最小系统才能真正稳定。10. 写在最后一点个人的体会回到题目说的“AI智能体的技术架构与解决方案”。经过这些项目的实操我的体会是智能体开发最难的往往不是模型或者算法层面的创新而是一大堆工程细节的堆叠——工具描述怎么写、状态怎么管、日志怎么记、出错了怎么降级、超时时怎么兜底。这些都是“笨功夫”但决定了一个Agent项目是停留在Demo级的炫技还是能真正落到生产环境里跑业务。如果让我给刚开始做智能体的朋友提一个最具体的建议那就是第一版永远用手写的方式把“模型-工具-状态”这个循环跑通不要急着套重型框架。等你亲手调试过一轮、亲手把模型“调教”得会正确使用工具之后再去看各类编排框架你的理解会完全不一样——你会知道每一步发生了什么也就能判断框架替你省了什么、又替你藏了什么坑。这个“手写一遍”的过程我觉得是绕不开的功课。另外还有一个小技巧可以分享给每个工具都加一个“是否适合当前任务的简要说明”字段虽然模型不一定每次都会看但真的有用。而且这个字段还有个额外的好处——你在调试工具调用失败时可以通过日志一眼看出模型为什么选错工具绝大多数原因都会写在它自己的思考里。善用模型自己留下的线索调试Agent的效率会高很多。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表