ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AI应用开发平台实战:从多模型接入到Agent编排与RAG落地

AI应用开发平台实战:从多模型接入到Agent编排与RAG落地 我去年接手一组内部AI项目时印象最深的一件事同一个团队的三套系统分别在各自代码里写死了不同厂商的SDK有的直接调HTTP接口有的套了一层很薄的封装。结果每次换模型、加工具都要把业务代码翻一遍改完还得重新回归老功能。后来我做了一个类似“XXL-AI”的平台把LLM调用、Agent编排、工具接入和知识检索统一收口才算真正把AI应用的迭代速度提上来。这篇文章就围绕XXL-AI这套AI应用开发平台把我搭建过程中的设计思路、核心模块拆解、工程化落地细节以及踩过的坑一次性讲清楚。内容偏实操适合正在做AI平台抽象、Agent应用编排或者想把RAG、MCP、Skill这些能力整合到业务系统里的同学参考。1. 整体设计思路为什么需要一个新的AI应用开发平台1.1 平台要解决的真实痛点做AI应用早期大家都会经历一段“野蛮生长”。业务方提出一个智能问答需求开发同学直接在服务里拼一个RAG流程另一个团队要做数据分析助手又自己写了一套Agent循环调模型、调工具、处理上下文。单看每个demo都跑得挺欢一旦进入生产环境问题立刻暴露。我梳理下来核心痛点无非四类。第一是模型供应商锁定。代码直接依赖某个厂商SDK之后想换模型几乎等于重构。价格波动、新模型发布、供应商稳定性全都变成不可控因素。第二是工具接入方式混乱。有人用Function Calling有人直接让模型生成JSON再自己解析还有人把工具逻辑写死在Agent代码里。每加一个工具都要动主流程代码越来越臃肿。第三是知识库与Agent之间耦合过深。RAG的索引、切片、召回策略散落在业务代码中Agent很难复用也无法统一评估效果。第四是缺少工程化底座。没有统一的链路追踪、测试集、灰度机制出了问题只能靠“肉眼找日志”。XXL-AI的定位不是再做一个“大模型套壳”而是把这些零散能力抽象成平台层上游统一对接多家模型供应商中间提供Agent编排引擎外围通过MCP、SKILL、RAG三种机制扩展能力底层用一套工程化体系兜底。这样业务方只需要描述“我要一个什么Agent、用哪些工具、喂哪些知识”平台负责把底座扛住。1.2 为什么扩展体系偏偏选了MCP、SKILL、RAG这三件套做平台前我调研过不少方案见过很多人把“插件”“工具”“知识库”混在一起聊。落到实际开发它们解决的问题完全不同最好分开抽象。MCPModel Context Protocol解决的是“Agent如何标准化地调用外部系统”。它相当于给Agent装了一个通用插座数据库、浏览器、设计稿、内部API这些原本各家有各家协议的资源接上MCP之后统一成一套工具调用协议。SKILL解决的是“多步过程如何沉淀复用”。比如“写一篇行业分析报告”这件事可能要拆成查资料、列大纲、分章节撰写、风格校准、格式整理多个步骤。把这些步骤封装成一个SKILLAgent遇到同类任务时直接按这套流程走比每次从零推理稳定得多。RAG解决的是“模型不知道的知识怎么补”。企业内部文档、产品手册、实时数据通过索引和检索注入到生成上下文里让模型在有限窗口内拿到最新、最相关的信息。我习惯用一个类比MCP是插座SKILL是操作手册RAG是资料室。Agent本身是那个干活的人需要接电时用插座需要按流程干活时翻手册需要查资料时进资料室。三者职责清晰组合起来才不打架。2. 多供应商接入把“换模型”变成改配置2.1 供应商适配层怎么做才不出幺蛾子平台第一个要收口的就是模型调用。我的做法是定义一层统一的Completion抽象不同供应商各自实现适配器业务侧只面对一个接口。class LLMProvider(ABC): abstractmethod def chat(self, messages, **kwargs) - Message: pass abstractmethod def embeddings(self, texts: list[str]) - list[vector]: pass abstractmethod def models(self) - list[ModelInfo]: passOpenAI、通义、文心这些供应商各自写一个实现类在内部完成消息格式转换、鉴权、重试逻辑。业务代码里永远只出现provider.chat(...)至于背后是哪个模型全看配置中心的gateway参数。这一步看起来简单真正坑人的是细节。比如不同模型对上下文窗口的处理不同有的需要显式声明max_tokens有的会自动截断有的返回里带reasoning_content有的只会随时间补充信息。适配层必须把这些差异消化掉对外输出统一的消息结构否则上层Agent编排时很容易被这些边角情况带偏。另外embedding模型也要统一接入。RAG通常只依赖一个向量模型但不同索引库可能有不同的向量维度兼容性问题。适配层里我会把向量维度声明成provider的元数据索引服务依托该元数据去选择是否重建向量库省掉很多“为什么相似度变差了”的排查。2.2 路由与降级策略不只是做负载均衡多供应商接入最大的红利是“能用路由策略控制成本和质量”。我在平台里建了一张路由表规则大致如下。场景路由目标原因复杂推理、代码生成旗舰模型质量优先出错成本高摘要、分类等短任务轻量模型速度快成本低向量化文本专用Embedding模型性能和价格更优供应商A超时或限流自动切到供应商B保障可用性凌晨低峰批处理任务限价模型对延迟不敏感可接受离线排队实现上我调整过不少轮次。早期简单按模型名硬编码路由很快发现一个事实同一个模型在不同时段的价格并不一样某些供应商的按量计费深夜时段更低。后来把价格表也做成配置路由时用“目标成本 质量权重”做综合打分批处理任务在凌晨自动跑低价通道日常对话保持高响应质量。降级不能只靠路由还要考虑任务类型。如果用户正在多轮对话中突然从旗舰模型降到小模型可能语气、格式都在逐步退化。我的做法是为会话绑定初始模型档位只有当连续失败超过阈值时才允许触发同档降级比如从旗舰A降到旗舰B而不是直接跳回小模型。2.3 一个值得抄作业的切换案例在我们的平台里有一类需求很常见客户说“我现在用OpenAI想换成国内的模型”。以前遇到这种事开发要改SDK、改prompt、改参数一周起步。接入XXL-AI后客户只需要在配置中心新建一个gateway条目选好供应商和模型然后跑一遍平台自带的评测集。评测集里放了几十个典型问题涵盖角色扮演、长文本总结、工具调用、拒答策略。系统自动对比新旧模型的输出质量并给出达标率。如果新模型某些case表现不足可以针对该case绑定一个SKILL或者调整路由而不是回滚整个版本。这套“配置驱动 评测验收”的流程让我换模型的时间从几天压缩到几小时。3. Agent编排从单轮对话走向多角色协作3.1 编排引擎的核心抽象模型接入只是第一步真正让平台有想象空间的是Agent编排。我做的编排引擎只有三个核心概念节点、连接、状态。节点代表一个执行单元可以是一次LLM调用、一个工具操作、一个条件判断甚至是另一个子Agent。连接定义了节点之间的流转关系支持顺序、分支、并行。状态是贯穿整个执行过程的共享上下文记录每一步的输入输出、中间结果、token消耗。class AgentNode: id: str type: str # llm / tool / condition / sub_agent config: dict next: list[str] class AgentGraph: nodes: dict[str, AgentNode] entry_points: list[str] state_store: dict很多朋友一开始纠结要不要用Prompt工程来搞定复杂任务我的体会是能用一个固定流程描述清楚的任务就别让模型自由发挥。写一个“客服工单处理Agent”如果放任模型自己决定调哪些工具、查哪些字段结果通常是失败的因为模型要么漏查要么顺序颠倒。而用编排图明确画出“先查用户信息再查订单状态如果异常则转人工”稳定性会成倍上升。3.2 计划-执行-反思循环的落地方式对于更开放的复杂任务我通常采用“Plan-Execute-Reflect”循环。这不是让模型无脑递归而是按阶段设计。Plan阶段模型根据用户目标拆解出子任务列表每个子任务标注所需工具、预期输出。Execute阶段任务按计划依序执行工具调用结果回填到状态。Reflect阶段模型参照最终目标和已完成子任务判断是否需要补充查询、修正方法或者直接收尾。落地时我暴露了一个参数max_iterations默认5。因为不加限制的话模型经常陷入“反思-再尝试-再失败-再反思”的死循环。我自己遇到的最高纪录是一个Agent连续反思14轮每轮都在改写同一个工具参数。后来我在Reflect节点上加了“较上一次是否有变化”的判断如果两轮生成的动作完全一致直接终止并输出当前结果。3.3 多Agent协作主管与执行者模式编排到后期自然会遇到多Agent协作。最稳妥的落地方式是“主管-执行者”模式主管Agent负责拆解任务、派发、验收结果执行者Agent各管一摊比如有的擅长写代码有的擅长查文档有的擅长做结构化输出。主管Agent接收需求 → 拆解为子任务data_query, code_gen, doc_search ... → 按子任务分发给对应执行者Agent → 收集执行结果 → 汇总、校验、生成最终回复这里面比较容易踩坑的是上下文隔离。执行者Agent不需要看到主管和别的Agent聊天的全过程否则token消耗惊人而且容易“信息过载导致跑偏”。我的做法是每个子任务构建独立的上下文片段只传必要信息执行结果的summary再回到主管的上下文中。这个细节让多Agent的稳定性提升非常明显。4. MCP、SKILL、RAG三大扩展能力拆解4.1 MCP用统一协议接入五花八门的工具MCP最大的价值是把“工具接入”从代码级变成配置级。以前让Agent查数据库得自己写SQL执行函数、做结果格式化、处理鉴权。现在如果目标系统暴露了MCP服务端Agent通过MCP客户端直接发现工具、读取工具描述、完成调用整个过程对Agent来说是标准的。一个典型的MCP工具信息如下{ name: query_order_status, description: 查询订单当前状态输入订单号返回物流和相关时间信息, input_schema: { type: object, properties: { order_id: {type: string} }, required: [order_id] } }MCP客户端的核心工作就是定期从服务端拉取这个工具列表交给LLM的Function Calling机制让模型自己决定何时调、传什么参数。我在平台里专门做了一个MCP网关层作用有两个一是统一管理授权和可见范围比如某个MCP服务只对特定Agent开放避免工具被滥用二是做工具结果的后处理把过长的原始返回截断成摘要避免撑爆上下文。有朋友问过“根据上下文嵌入到Figma MCP怎么授权”实操上无非三步在MCP服务端配置你的应用标识和访问令牌然后在客户端配置对应工具名映射最后测试一下“列出画布节点”能否正常返回。很多“授权失败”其实是因为访问令牌的scope配少了少了读权限自然拉不到数据。另外一个值得表扬的做法是参考一些低代码平台合并MCP的方式把MCP工具动态渲染成表单或者按钮让运营人员可以配置“问题关键词→触发某个MCP工具”的规则降低AI平台的使用门槛。4.2 SKILL把一段过程封装成可复用“手艺”SKILL是我个人最喜欢的一个抽象。它本质上是一套“方法论的序列化描述”告诉Agent在执行某类任务时应该分几步、每步注意什么、输出格式是什么。一个SKILL文件通常包含三部分触发条件什么样的任务适合用它。执行步骤有序的步骤清单每个步骤附带工具调用建议或风格要求。验收标准怎么判断这个任务干得好不好。举例来说“写一份市场分析报告”这个SKILL可以这样描述明确分析对象和范围列出必须覆盖的关键维度市场规模、竞品动态、用户画像、趋势预测。调用搜索工具收集近3个月的公开资料。用结构化表格整理信息源标注发布时间和可信度。按“现状-问题-机会-建议”的框架撰写初稿。检查结论是否有信源支撑避免空泛表述。输出Markdown文档含执行摘要。SKILL的好处是让Agent从“每次靠prompt猜”变成“按已验证的一系列方法执行”。团队里恰好有人做得好时可以直接把流程沉淀成文件新Agent挂载同一个SKILL即可复用。我反复提醒团队SKILL不要写大而全的通用套话聚焦“这个领域里真正管用的行动顺序”比一堆形容词有价值得多。4.3 RAG知识库不只是“分期向量化”RAG是大家相对熟悉的但做得好的RAG远不止“把文档切片、丢进向量库、检索TopK”。我在实战中总结过几个容易被忽略的关键点。一是切片策略必须跟着文档结构走。我见过太多人按固定长度硬切结果把表格拦腰砍断、把章节结论和依据切到两个块里检索时只能召回一半内容。正确做法是先解析标题层级和表格结构按语义段落切分长度可以不等但尽量保证每个切片是一个“可独立理解”的信息单元。二是检索不能只靠向量。向量召回擅长语义相关但不擅长“精确匹配”。比如用户搜一个平台的内网产品代号向量召回往往不如关键词精确过滤。我在RAG检索层做的是“多路召回”向量召回一路、关键词召回一路、结构化知识库查询一路最后用rerank模型统一排序。三是上下文组装要讲究。很多RAG效果差不是检索没召回到正确答案而是把不相关的块也塞进去干扰了模型判断。我会做相关性阈值过滤并且对召回块做摘要压缩让最终进入Prompt的知识既精炼又足够。RAG知识库能不能存图片当然可以但纯向量化“图片文件”没有意义。真正有效的是对图片做多模态解析提取出图中文字信息或物体描述后再向量化。比如一份截图里包含产品操作流程要先OCR和版面分析把图片转化为可检索的文本描述用户问“这个界面上的按钮在哪”系统才能给到准确答案。本地搭建简易RAG知识库不少零基础教程都能跑通但生产级RAG还要解决增量更新、弱引用、权限隔离、回答引用溯源这四个问题。尤其是引用溯源用户看到AI回答得再漂亮如果无法回到原始文档可信度会大打折扣。5. 工程化底座把项目从“能跑”拉到“可靠”5.1 可观测性链路上每一跳都要看得见AI应用调试起来难受很大程度上是因为它的链路太长了用户输入进来说自然语言然后被解析成任务触发工具调用注入知识生成模型输出。任何一环出问题表面症状都可能是“回答不对”。我做的可观测性体系围绕“Trace”展开每一条用户请求生成一个全局TraceID贯穿供应商调用、Agent节点执行、MCP工具返回、RAG检索结果。在平台看板上可以看到这样的记录哪个节点耗时多少、调用了哪个模型、消耗了多少token、召回了哪几个文档片段、工具执行是否报错。这些数据不光用来排查问题也是做成本分析的基础。我每周都会导出token消耗报表按供应商、按Agent、按用户维度做透视。很多“模型叫得异常频繁”的情况就是这样抓出来的比如某个Agent误把普通对话也路由到了旗舰模型白白消耗预算。5.2 评估与回归没有评测集重构就是赌运气Agent应用最怕的是“这次改好了上次的却坏了”。没有评测集做回归这种问题几乎必然发生。我的做法是维护三层测试资产单轮问答集、多轮对话集、端到端任务集。单轮问答集主要验证知识问答和简单工具调用多轮对话集验证上下文记忆和澄清机制端到端任务集模拟真实业务流程比如“用户发起退货请求Agent完成身份验证、订单查询、退货单创建、结果通知”。每次平台升级、模型切换、SKILL调整都要跑一遍三层测试集。输出对比不只是看“回没回答出来”还要看格式、引用、拒答合理性。实测下来这套机制帮我拦下了至少三次“感觉优化了实际退步了”的上线事故。5.3 发布与隔离多环境各跑各的互不干扰工程化的另一块是环境治理。我在XXL-AI里划分了三个环境开发环境连真实供应商的沙箱AB测试很方便。预发环境使用完整生产数据副本但对外不可访问。生产环境只有经过评估的配置才能进入。三个环境共用一套代码库差异只在配置中心的gateway和feature flag上。发布一个新SKILL首先在开发环境跑评测然后调整预发环境的label绑定通过后再切换生产环境的路由灰度比例。这样做的好处是模型供应商升级API版本这类外部变化也能先在预发环境里验证完再放量到生产。6. 高频问题与排查技巧实录6.1 高频问题速查表现象可能原因排查思路Agent提示找不到MCP工具工具列表未刷新/权限未开放检查MCP网关是否成功拉取最新工具列表核对Agent的可见工具白名单MCP授权失败访问令牌scope缺失逐项核对权限配置先用“列出工具”做连通性测试RAG回答中出现了不相关内容相关性阈值太低检查rerank分数提高召回过滤阈值或者检查切块是否包含噪声段落Agent反复执行相同动作Reflect逻辑未判断动作变化在两轮Reflect间做工具参数相似度比对相同则终止循环切换供应商后输出格式乱了适配层没有统一system prompt风格检查供应商适配器的默认prompt和参数映射知识库新增文档后检索不到增量索引未触发/向量库分片异常查看索引任务日志确认切片和向量化流程执行成功模型回调token激增上下文未裁剪/工具结果过长开启工具结果摘要压缩历史消息限制max_iterations6.2 我踩过的三个“看着小、影响大”的坑第一个坑是MCP工具描述写得太糙。早期为了让模型“自由发挥”工具描述写得很模糊结果模型经常用错参数。后来我把每个工具描述都改成交互式文档什么时候用、参数边界在哪、返回值有哪些字段模型误用率立刻降下来。第二个坑是RAG索引缺少“文档生命周期管理”。有一次客户撤掉了一份旧版手册但向量库里还留着导致用户反复得到过时回答。后来我加了文档生效时间和状态字段检索时过滤过期版本这个体验问题才算根治。第三个坑是Agent编排时过度并行。早期为了提升速度把多个独立工具调用并行执行结果发现某些接口有速率限制反而整体更慢。后来我在编排引擎里加了“并发预算”按工具级别控制最大并发数响应时间反而更稳定。7. 写在最后的实操体会如果让我给后来者一个建议那就是别一上来就追求大而全的Agent编排能力。先把你最常用的工具、知识库、流程固化成MCP、SKILL、RAG三件套用最朴素的方式跑通再逐步加编排复杂度。XXL-AI这套平台在我这里最大的价值不是“看起来智能化”而是让每个AI能力的交付都有标准化路径接入模型有统一适配器扩展能力有规范载体上线发布有评估和灰度。等到你习惯了这种工程化节奏会发现自己已经在不知不觉中告别了“天天调prompt、天天改代码”的状态。
返回列表