从多项目痛点到统一底座:XXL-AI 平台如何用 MCP+SKILL+RAG 搞定 Agent 编排与多模型接入

📅 发布时间:2026/10/7 19:18:57
从多项目痛点到统一底座:XXL-AI 平台如何用 MCP+SKILL+RAG 搞定 Agent 编排与多模型接入
1. 为什么我会去折腾一个 AI 应用开发平台先说结论我最初并不是想造一个平台而是被现实逼出来的。手上同时跑着三四个 AI 应用的小项目有的做客服问答有的做文档摘要有的做内部知识检索还有的在做流程自动化。每个项目单独看都不复杂但一旦并行推进问题就集中爆发了模型供应商的接口各写一套提示词散落在各个文件里知识库检索逻辑重复实现工具调用也就是现在大家常说的 MCP 那一套每个项目都要重新接一遍最后连日志和成本统计都对不上。这种状态下任何一次需求变更都是灾难。客户说想从 A 模型换成 B 模型我得翻遍代码找调用点业务说知识库要加一批新文档我得重新跑一遍索引脚本运营说想让 Agent 多调一个外部工具我又得改一遍工具注册逻辑。改到最后代码里全是补丁自己都不敢动。所以我开始认真思考一件事能不能把这些重复的、易变的、跨项目通用的部分抽出来做成一个统一的底座让上层应用只关心业务逻辑这就是 XXL-AI 这个 AI 应用开发平台诞生的直接动机。它要解决的核心问题就三个Agent 编排、多供应商模型接入、以及以 MCP SKILL RAG 为核心的扩展能力再叠一层工程化底座把可观测性、配置管理、部署这些事情兜住。这篇文章适合两类人看。一类是正在做 AI 应用、被多模型和多工具集成折磨的开发者另一类是团队里负责技术选型、想知道一个 AI 平台到底该有哪些模块的人。我会尽量把每个设计决策背后的“为什么”讲清楚而不是只丢一堆名词。你不需要是 AI 专家只要写过一点后端代码就能看懂这套东西是怎么搭起来的。2. 整体架构设计与核心思路拆解2.1 平台到底该管什么、不该管什么做平台最容易犯的错就是什么都想管。我一开始也差点掉进去想着把提示词管理、模型路由、知识库、工具市场、评测、监控全塞进来。后来冷静下来问自己一个问题如果某个能力只有一两个项目用得上它凭什么进底座我的判断标准是凡是跨项目重复出现、且变更频率高的部分才值得进底座。按这个标准筛下来真正该进平台的是四块Agent 编排定义 Agent 怎么思考、怎么调工具、怎么在多轮里保持状态这是所有 AI 应用的公共骨架。多供应商接入模型调用是刚需而且供应商会换、模型会升级必须做成可插拔。扩展机制MCP 负责工具接入SKILL 负责能力封装RAG 负责知识注入这三者构成了 Agent 的“外挂系统”。工程化底座配置、日志、追踪、限流、成本统计这些不做平台就是个玩具。至于具体的业务逻辑、行业提示词、专属数据处理一律留在上层应用里。平台提供的是“插座”不是“电器”。这个边界一旦划清楚后面的设计就顺了。2.2 为什么是 MCP SKILL RAG 这个组合很多人会问工具调用、能力封装、知识检索这三件事为什么不能合成一个机制我试过合并结论是合不了因为它们解决的是三个不同层次的问题。MCP解决的是“Agent 如何与外部世界通信”。它本质上是一套标准化的工具调用协议让 Agent 能以统一的方式去调用文件系统、数据库、第三方 API。它的关键词是协议和互操作。你写一次 MCP Server理论上任何支持 MCP 的客户端都能用。SKILL解决的是“如何把一段复杂能力打包成一个可复用的单元”。一个 SKILL 可能内部调用了好几个 MCP 工具加上自己的提示词和流程控制对外只暴露一个简单接口。它的关键词是封装和复用。比如“生成周报”这个 SKILL内部可能要读数据库、调模型总结、再格式化输出但对 Agent 来说就是一句话的事。RAG解决的是“如何让模型用上它训练时没见过的私有知识”。它的关键词是检索和增强。文档切分、向量化、召回、重排这一整套流程和工具调用完全是两码事。打个比方MCP 是电源插座标准SKILL 是各种家用电器RAG 是给电器配的说明书和资料库。三者各司其职硬要合并只会让每一块都变得臃肿。所以 XXL-AI 把它们做成三个独立的扩展点各自有清晰的接口和生命周期。2.3 多供应商接入的抽象层次多供应商接入听起来简单不就是把不同厂商的 API 包一层吗真做起来坑很多。不同厂商的请求格式、返回结构、流式协议、错误码、计费方式都不一样。如果只是简单包一层上层代码还是会被供应商细节污染。我的做法是定义一层统一的模型抽象把差异收敛在适配器里。核心抽象包括ChatModel负责对话补全输入是消息列表输出是流式或非流式的回复。EmbeddingModel负责文本向量化RAG 依赖它。RerankModel负责召回结果重排提升 RAG 精度。每个供应商实现这几个接口上层只依赖接口。这样换供应商就是换一个实现类配置里改个名字就行。下面这张表是我在实际选型时整理的对比维度供参考维度关注点为什么重要接口兼容性是否兼容主流协议格式决定适配器工作量流式支持是否支持 SSE 流式输出影响用户体验函数调用是否原生支持工具调用影响 Agent 能力上限上下文长度最大 token 数决定能塞多少 RAG 内容计费方式按 token 还是按次影响成本统计设计稳定性限流、超时表现影响重试策略提示不要为了“支持所有供应商”而过度抽象。我建议先支持两到三家主力供应商把抽象层打磨稳定再逐步扩展。过早追求全覆盖抽象层会被各种边缘 case 拖垮。3. Agent 编排的核心细节与实操要点3.1 Agent 编排到底在编排什么很多人对“Agent 编排”这个词有误解以为就是画个流程图把几个节点连起来。实际上编排的核心是控制流和状态管理。一个 Agent 在一次任务里可能要经历“理解意图 → 规划步骤 → 调用工具 → 观察结果 → 调整计划 → 生成回复”这样的循环每一步的输入都依赖上一步的输出还要处理失败重试和分支跳转。XXL-AI 里的编排模型我采用的是基于状态机的循环执行而不是纯 DAG。原因是 DAG 适合流程固定的场景但 Agent 的特点是路径不确定它可能调一次工具就结束也可能来回调十几次。状态机更适合这种动态性。一个 Agent 的定义大致包含这几部分角色设定系统提示词定义 Agent 的身份和边界。可用工具集这个 Agent 能调用哪些 MCP 工具和 SKILL。可用知识库绑定哪些 RAG 知识库。执行策略最大循环次数、超时时间、失败重试规则。输出格式是纯文本还是结构化 JSON。3.2 单 Agent 与多 Agent 编排的取舍单 Agent 够用吗大部分场景够用。但有些任务天然需要分工比如“先调研再写作再审核”一个 Agent 既当运动员又当裁判效果往往不好。这时候就上多 Agent 编排。多 Agent 有两种常见模式我在项目里都实现过串行流水线Agent A 的输出作为 Agent B 的输入像工厂流水线。适合步骤明确的场景比如“检索 → 总结 → 翻译”。主管-工人模式一个主管 Agent 负责拆解任务和分派多个工人 Agent 各自执行最后主管汇总。适合任务复杂、需要动态分工的场景。选哪种我的经验是能用串行就别用主管模式。主管模式看起来灵活但调试难度陡增因为主管的决策路径不可预测出了问题很难定位是主管分派错了还是工人执行错了。串行流水线虽然死板但每一步都可控、可测、可回放。下面是一个多 Agent 串行编排的配置示例用 YAML 描述pipeline: name: research-and-write agents: - id: researcher role: 你是一名调研员负责收集和整理资料 tools: [web_search, doc_reader] knowledge: [internal_wiki] output: text - id: writer role: 你是一名撰稿人根据调研结果撰写文章 input_from: researcher tools: [] output: markdown - id: reviewer role: 你是一名审核员检查文章的事实准确性和逻辑 input_from: writer output: json max_rounds: 3 timeout: 3003.3 状态管理与上下文压缩Agent 跑多轮之后上下文会越来越长这是绕不开的问题。一个跑了二十轮的 Agent历史消息可能已经上万 token既贵又慢还可能超出模型上下文限制。我的处理策略分三层第一层是滑动窗口只保留最近 N 轮对话简单粗暴但有效。第二层是摘要压缩把较早的对话用模型总结成一段摘要保留关键信息。第三层是结构化记忆把重要的中间结果比如工具返回的关键数据单独存起来不放在对话历史里需要时再注入。注意摘要压缩本身也要调模型是有成本的。我一般设置一个阈值比如历史超过 8000 token 才触发压缩避免频繁调用。实操中我发现很多 Agent 之所以“越跑越傻”就是因为上下文里塞了太多无关的工具返回结果。解决办法是在工具返回时做一次过滤只保留和当前任务相关的字段而不是把整个 JSON 原样塞进去。这个细节能显著提升长任务的稳定性。4. 多供应商接入与 MCP、SKILL、RAG 扩展实现4.1 多供应商适配器的落地写法前面说了抽象层这里讲具体怎么落地。以对话模型为例我定义了一个统一的请求对象和响应对象适配器的职责就是在这两个对象和供应商原生格式之间做转换。class ChatModel: def chat(self, messages, toolsNone, streamFalse): raise NotImplementedError class OpenAICompatModel(ChatModel): def chat(self, messages, toolsNone, streamFalse): payload self._build_payload(messages, tools) if stream: return self._stream_request(payload) return self._sync_request(payload)关键点在于_build_payload和响应解析。不同供应商在工具调用的字段名、流式分片的格式上差异很大这些差异全部收敛在适配器内部。上层拿到的永远是统一的ChatResponse对象。我踩过的一个坑是流式输出的错误处理。非流式请求出错直接抛异常就行但流式请求可能已经吐了一半内容才出错这时候如果直接抛异常用户看到的就是半截回复。我的做法是在流式过程中捕获异常把已输出的内容保留并在末尾追加一个错误标记让上层决定怎么展示。4.2 MCP 工具接入的实操流程MCP 的核心价值是标准化。接入一个 MCP Server 的流程大致是配置连接信息指定 Server 的地址和启动方式。拉取工具清单MCP Server 会暴露它支持的工具列表和参数 schema。注册到工具池把工具注册进平台的工具注册表供 Agent 选用。调用与结果处理Agent 决定调用某个工具时平台负责转发请求并处理返回。这里有个容易被忽略的点工具的参数校验。MCP Server 会给出参数的 JSON Schema平台应该在调用前做一次校验避免把非法参数发出去。我见过太多因为参数类型不对导致工具调用失败的案例加上校验后这类问题基本消失。{ name: read_file, description: 读取指定路径的文件内容, parameters: { type: object, properties: { path: { type: string, description: 文件路径 } }, required: [path] } }提示MCP 工具的描述文字会直接影响模型是否愿意调用它。描述要写清楚“什么时候用”而不只是“它能做什么”。我实测下来把描述从“读取文件”改成“当需要查看本地文件内容时使用”调用准确率明显提升。4.3 SKILL 封装的设计与复用SKILL 是我最喜欢的一层因为它真正实现了能力复用。一个 SKILL 本质上是一个“带提示词和流程的复合工具”。它对外暴露的参数很简单内部却可以很复杂。举个例子“生成周报”这个 SKILL内部流程是查数据库拿本周数据 → 调模型总结 → 按模板格式化。对 Agent 来说它只需要传一个“周次”参数。这种封装让 Agent 的提示词可以保持简洁不用把复杂的多步逻辑写进系统提示里。SKILL 的定义我采用声明式配置加脚本的组合skill: name: weekly_report description: 根据指定周次生成工作周报 parameters: week: { type: string, required: true } steps: - type: mcp_call tool: query_database args: { sql: SELECT * FROM tasks WHERE week {{week}} } - type: llm_call prompt: 根据以下数据总结本周工作{{step1.result}} - type: template template: weekly_report.md这种设计的好处是非核心逻辑用配置描述复杂逻辑才写脚本兼顾了灵活性和可维护性。4.4 RAG 知识库的构建与检索优化RAG 是决定 AI 应用“懂不懂业务”的关键。我见过很多 RAG 项目效果差问题往往不在模型而在检索环节。整个 RAG 流程我拆成四步切分、向量化、召回、重排。切分是最容易被低估的一步。按固定长度切分简单但会切断语义。我一般用递归切分优先按段落、再按句子最后才按字符数兜底。切分块大小我通常设在 500 到 800 字符之间太大召回不准太小上下文不完整。向量化依赖 Embedding 模型这里要注意不同模型的向量维度不同换模型必须重建索引。召回阶段我一般同时用向量召回和关键词召回然后合并结果。纯向量召回对专有名词不敏感加上关键词召回能补上这个短板。重排是提升精度的杀手锏。召回阶段拿回 20 条用 Rerank 模型重新排序取前 5 条喂给模型效果比直接取前 5 条好很多。阶段常见问题我的处理方式切分语义被切断递归切分保留重叠向量化换模型索引失效索引与模型版本绑定召回专有名词召回差向量 关键词混合重排精度不够引入 Rerank 模型注意RAG 不是万能的。如果知识库本身质量差、内容重复、格式混乱再好的检索也救不回来。我一般会先花时间清洗数据这一步的投入回报比调模型高得多。5. 工程化底座与常见问题排查5.1 工程化底座包含哪些必备模块平台能不能上生产工程化底座是分水岭。我把它拆成五个模块配置中心模型密钥、供应商地址、Agent 定义、SKILL 配置统一管理支持热更新。可观测性每次调用的输入输出、耗时、token 消耗、工具调用链全部记录方便排查。限流与熔断防止某个供应商挂了拖垮整个平台也防止被恶意刷量。成本统计按项目、按 Agent、按模型维度统计花费这是给老板看的硬指标。版本管理Agent 和 SKILL 的配置要能回滚改坏了能一键恢复。这五块里我认为可观测性最重要。AI 应用的调试和传统应用完全不同传统应用看堆栈就能定位AI 应用得看完整的调用链和输入输出。没有可观测性出了问题就是两眼一抹黑。5.2 常见问题速查表下面这张表是我在实际运维中整理的高频问题基本覆盖了八成以上的故障场景现象可能原因排查方向Agent 不调用工具工具描述不清 / 提示词冲突检查工具描述和系统提示工具调用参数错误Schema 不匹配校验参数定义RAG 召回不准切分不合理 / 未重排调整切分策略加 Rerank响应超时上下文过长 / 供应商限流压缩上下文加重试成本异常高循环次数过多 / 上下文膨胀检查 max_rounds 和压缩策略流式输出中断网络抖动 / 供应商异常加断流重连和错误标记5.3 几个我踩过的坑和独家经验第一个坑是过度依赖模型自主决策。我一开始把工具选择完全交给模型结果它经常选错工具或者反复调同一个工具。后来我加了“工具调用次数上限”和“同一工具连续调用检测”情况好转很多。模型不是万能的该加约束就得加。第二个坑是忽略冷启动。RAG 知识库第一次检索时如果索引还没加载进内存响应会特别慢。我的做法是平台启动时预热索引把常用知识库的向量提前加载好。第三个坑是配置散落。早期我把 Agent 配置写在代码里改一次要重新部署。后来全部外置成配置文件配合配置中心热更新运维效率提升了一个档次。提示如果你刚开始做 AI 平台我建议先把可观测性和配置管理做扎实再去做花哨的编排功能。前者是地基后者是装修顺序反了会返工。5.4 平台后续可以怎么扩展这套底座跑稳之后能扩展的方向其实很多。比如接入评测模块对 Agent 的输出做自动化打分比如做提示词版本管理支持 A/B 测试再比如把 SKILL 做成一个市场团队之间可以共享和复用。我个人最看好的扩展方向是评测。因为 AI 应用的输出是不确定的没有评测就没有迭代的依据。你改了提示词效果到底是变好还是变差光靠肉眼看几个 case 是不够的得有一套自动化的评测集和打分机制。这块我还在持续打磨等成熟了再单独写一篇。最后分享一个我在实际使用中的体会做 AI 平台最忌讳的是追求一步到位。我见过太多团队想一开始就把所有能力做全结果半年过去还在搭架子。正确的做法是先跑通一条最小闭环——一个 Agent、一个模型、一个工具、一个知识库让它真正在业务里用起来再根据实际痛点逐步扩展。平台是长出来的不是设计出来的。