前阵子有个内部项目找上门需求写得很简单把公司知识库接进大模型对话做一个MCP套壳。字面上的工作量不超过三天——一个MCP Server、两个Tool、一条检索接口。可后来事情失控了这个“套壳”最后长成了一个带文献检索、多模型交叉验证、结论溯源的研究决策系统。标题这句话是我盯着代码仓库时冒出来的。这篇就聊聊为什么一个薄壳会“长”成系统哪些需求是伪需求哪些需求才真正改变了架构走向顺带把踩过的坑和能直接抄作业的关键配置一起列出来。1. 从“套壳”到“系统”不是失控是“壳”这个词骗了你1.1 套壳MCP的原始画像一层薄薄的协议外壳所谓套壳MCP本质上就是把一个大模型能力包装成符合MCP协议的“服务”。MCP的全称是Model Context Protocol模型上下文协议近两年在AI工具链里普及得很快。它做的事情你可以理解成一个“USB-C接口”无论你用什么宿主只要对方支持MCP你的服务就能被接进去。这里不需要关心对方的内部实现也不需要重新写接口文档。我接到需求时画出来的结构图非常简单一个MCP Server进程注册两个工具检索知识库、生成摘要用stdio或HTTP暴露给宿主核心代码大概一百行以内就能跑起来。当时我给项目取了个很朴素的代号“套壳X”意思是“薄薄一层能通气就行”。我甚至没有考虑数据库设计——检索直接走现有接口摘要直接调模型API。现在回想这个阶段的“没想到”才是后来一切变化的起点。1.2 需求的第九个词才是真相用户最初提需求的时候原话很短核心词是“让对话能查到资料”。这听起来像是一个搜索增强功能。但等到真的把检索结果返回给用户之后对方马上冒出一句话“能不能告诉我我从哪份文档得出这个结论”这个问题一出来“套壳X”就回不去了。因为“结论”和“来源”是两码事前者是模型根据检索结果生成的回答后者需要系统在生成过程中保留引用关系、原文编号、上下文片段。如果你只在表面套了一层MCP壳模型吐出来的话根本追溯不到具体出处。紧接着第二个问题也来了“两篇文档的说法冲突你帮我评估哪边更可靠。”这一步要从“检索信息”变成“分析信息”已经需要多来源比对、冲突检测、可信度判断。第三个问题更直白“以后的研究日报能不能自动按这个格式输出。”这时候套壳已经不只是一个协议适配器而是一个要负责任的支持系统。我把这三次追问总结成一句话用户要的从来不是“接口”而是“决策支持”。“套壳”只是他描述需求时最顺手的一个词并不是他真正想要的边界。1.3 三次清晰的“长成”节点我后来复盘把系统的演进过程切成了三个节点V1无状态问答提问→检索→生成回答支持简单链接引用但模型无法对结论负责V2带状态的分析助手支持多轮研究目标、子问题拆解、证据暂存用户可以追问“为什么”V3研究决策系统在V2基础上加了证据链校验、冲突检测、默认输出结构化结论、自动回归评测。每一步升级都不是我主动加戏而是被真实使用场景逼出来的。V1交付后的第一天用户试了三个问题前两个很满意第三个是“查一下近两年关于模型评估的综述对比三家的方法”。这时模型一次只能带一个上下文检索工具返回了一大堆论文摘要但在单轮对话里模型没有能力组织跨论文的对比。我需要让它分步骤思考先查第一组再查第二组最后汇总。这个需求直接催生了V2里的状态与子任务调度。V2上线后用户开始拿它写内部评审意见。评审意味着结论要负责任因此“来源”必须有这个需求又催生了V3的证据链。这套演进路径非常有代表性不是项目计划里写出的架构而是用户每次多问一句“然后呢”系统一步步长成了现在的样子。1.4 为什么挂在MCP协议上而不是全部自己写在V2阶段我一度动过把工具调用全换成自研接口的念头觉得更自由。但很快发现不对劲研究决策系统需要的工具太多了。文献检索、数据看板、统计接口、文件读取、验证服务每个工具都有自己的认证方式、参数规范、返回格式。如果每个都自研接入等于是给宿主客户端写了一堆强耦合的插件每加一个工具都要改一遍客户端代码。MCP的价值恰好是标准化。它规定Tools、Resources、Prompts三个原语把工具的发现、调用、认证统一起来。我的系统只需要实现MCP Server任何宿主的MCP Client都能直接发现并调用我的工具。这就好比你把设备的接口都统一成USB-C插哪个外设都方便。所以即使“套壳”这个起点很薄协议本身并不薄。它给了我一个长期不腐化的底座后续每加一个工具都只是往MCP Server里多注册一个方法而不需要动宿主、动客户端、动调度器。2. 研究决策系统到底“长”成了什么架构2.1 四个核心模块分工各有讲究我最后做出来的系统可以拆成四个层工具接入层一组MCP Server暴露检索、数据、文件、验证等能力信息组织层查询改写、结果去重、相关性重排、上下文裁剪推理与论证层多轮任务调度、证据收集、子问题拆解、冲突检测决策输出层结构化结论、置信度标注、引用溯源、行动建议工具接入层的责任是“受控暴露”。注意这里不是把数据库直接连给模型而是暴露受白名单约束的检索函数。比如文献检索工具的入参只能是query、top_k、date_range这些出参固定是论文列表含标题、摘要、链接。信息组织层解决的是“多工具结果混在一起”的问题。一个复杂提问会触发文献搜索、内部文档搜索、统计数据查询三个工具并行返回。如果直接把几万字塞给模型效果很差成本也高。信息组织层会把结果按相关性重排、去重再用一个抽取模型把最关键的片段拆出来组成一个紧凑的证据包。推理与论证层是系统区别于普通QA问答的本质。普通问答是一次性的问题→上下文→回答。研究决策系统不是它把问题拆解成子任务、逐项收集证据、暂存中间结论、最终汇总。有点像把一个“大问题”切成几块“小作业”每块都附上证据再拼成最终答案。决策输出层则负责把结论做成能被“使用”的东西而不是一段散文。输出格式是结构化的结论、支持证据列表、反方证据列表、置信度、未解决风险。这样下游可以拿这个数据结构去生成报告、推送日报或者归档。2.2 MCP在架构里的位置有人会觉得MCP只是协议不参与系统设计。但实际恰恰相反MCP在这个系统里承担了“工具总线”的角色。我用的最小角色划分是角色在系统中的职责举例MCP Host持有会话状态与调度逻辑工作台客户端、命令行工具MCP Client发起工具调用系统内的调度服务MCP Server提供Tools、Resources、Prompts文献检索服务、数据查询服务这种划分带来的好处是系统本身的调度层只需要穿一件“MCP Client”的马甲就能调用所有工具。消息格式、返回格式、错误处理全部统一不需要为每个工具单独写适配器。这也解释了为什么“套壳”会长成系统MCP本身太适合加工具了。加一个检索工具是一个方法加一个验证工具还是一个方法。系统的复杂度不是被协议绑定的而是被能力放大的。2.3 一份可以直接照抄的工程目录我最后整理出了这么一份最小可运行的工程结构不是完整代码而是目录与职责对齐research-decision/ src/ mcp_servers/ literature.py # 文献检索服务 dataset.py # 数据查询服务 validate.py # 验证与交叉检查服务 orchestrator/ scheduler.py # 子任务调度与状态管理 context.py # 上下文组装与裁剪 reasoner/ planner.py # 研究问题拆解 evidence.py # 证据收集与冲突检测 output.py # 结构化结论生成 eval/ cases.jsonl # 回归评测集 compare.py # 新旧版本对比 config/ tools.json # 工具注册表配置工具注册表里写的是每个工具的MCP描述这部分非常关键后面避坑环节我会展开讲。评测目录一开始我是没有的后来才补上它对系统稳定性的帮助远远超出预期。3. 长成系统的过程复盘每个变化都不是白来的3.1 从单工具到工具矩阵为什么单一工具撑不住研究场景最初的套壳X只有一个检索工具。用户问“某方法在三个数据集上的表现如何”检索工具返回的是一堆论文列表模型只能从摘要里猜答案经常是表面正确、细节错误。单一工具的问题在于它把“找信息”和“验信息”混在一起了。检索结果本身是二手信息需要原始数据、统计接口、完整文本来交叉验证。于是我在V2阶段一口气加了六个工具文献检索、内部知识库检索、数据集统计接口、全文抽取、数字校验检查引用数字是否和原文一致、格式转换。工具矩阵给系统的推理能力带来了质的提升但也立刻带来了新问题模型面对一长串工具列表选错工具、给错参数的频率变高了。这逼着我做两件事一是给每个工具写非常详细的描述二是调整工具注册表里的顺序让高价值工具排前面。把这条经验前置如果你的MCP工具能被模型准确调用你的系统已经稳定了一半。描述写得不到位后面所有优化都白搭。3.2 从无状态问答到多轮状态机研究本来就是一连串追问V1最让我头疼的是模型记不住研究上下文。用户问“对比A和B两种方法”模型回答完就算结束了。用户再追问“那A在小样本下有问题吗”模型已经把A、B的中间结论忘了只能重新检索。要支持研究决策核心状态必须持久化。我设计了一个简单的状态机状态对象包含四个字段研究目标用户本次要解决的问题已收证据从各工具拿到的关键结果集合待验证假设当前还没有定论的中间判断结论草稿已完成的子问题结论。每次用户提问调度器先加载这个状态再决定是补充检索还是直接基于已有证据回答。这个设计让“追问”变成系统第一公民而不是每个问题都被当独立请求处理。状态机的引入是系统从“对话工具”进化成“决策支持工具”的分水岭。3.3 从“给答案”到“给证据链”让模型无法甩锅研究决策系统最大的敌人是“权威感错误”——模型用一套听起来很专业的术语给了一个完全是编造的结论用户信了然后出问题。这个问题靠调prompt是治不了的必须从输出约束层面解决。我在V3里做了一件很硬核的事所有结论对象必须包含evidence_id列表且每个evidence_id必须对应工具返回的真实内容。模型在生成最终结论前调度器先把工具返回结果的原文片段传给它并强制它引用这些片段的编号而不是自己编。实现上就是要求模型输出遵循一个JSON Schema{ conclusion: 综合现有证据A方法在小样本场景下更稳定, confidence: 0.78, support_evidence: [lit_001, data_002], risks: [样本量小于30时置信度显著下降] }后校验器再检查support_evidence里的ID是否真实存在。如果ID不存在输出直接标红提示“结论不可信”。这一层机制让系统在“负责任”这件事上有了底线。3.4 从手工调prompt到回归评测系统复杂度必须用数据守住系统长到V3prompt、工具描述、调度逻辑都已经很复杂。有一阵子我改了某个工具的排序第二天才发现之前能正确回答的问题开始胡说八道。问题出在我改的是工具注册表影响的却是推理结果但这种影响不会立刻爆出来。解决办法是建回归评测集。我准备了大约60个历史典型问题分四类事实查询、方法对比、风险分析、报告生成。每次改完配置自动跑一遍这60个问题把新旧输出做比对看核心结论是否保持一致、证据链是否完整。这个动作让系统重新变得“可维护”。它也是判断你的应用是不是真的长成了系统的标准之一如果改动一个配置你需要担心产生蝴蝶效应说明复杂度已经超越了手工调试的边界必须有自动化评测兜底。4. 实操避坑真正卡住我的几个坎4.1 MCP工具注册了模型就是不调用这个坑几乎一定会遇到。我第一次写文献检索工具描述就一行“搜索文献”。结果模型只在用户明确说“搜索”时才调用稍微绕一点的提问就无视工具直接凭训练数据回答。比如用户问“这个方法在小样本上的表现如何”文献里明明有答案模型却选择自己编。原因是工具描述和参数说明没有触发语义联想。后来我把描述展开成了带场景、触发条件、参数示例的完整说明工具文献检索 用途当用户的问题涉及研究方法、实验结论、模型性能时必须使用本工具获取最新信息。 触发条件提问中出现特定方法名、数据集名、研究问题关键词或用户要求查证、溯源、对比。 参数说明 query核心关键词建议把主题词和限定词一起写例如“小样本学习 模型评估” top_k返回数量默认5研究综述类问题建议10改完之后调用命中率高了一截。这条经验概括成一句话工具描述不是文档是搜索引擎的索引文案要站在模型理解的视角去写。4.2 多工具并行返回上下文直接爆窗研究问题一做复杂信息组织层会同时触发三个工具每个工具返回几百行结果加起来好几万字。模型上下文窗口再大也扛不住而且信息太多会稀释关键信号。我的处理方式是“三段式裁剪”先全局去重再做相关性重排最后只取每个结果里最关键的段落比如摘要前两句话、表格结论行。裁剪后的证据包控制在模型能稳定处理的长度内大概会让成本下降三到五成答案质量反而提升。另一个补充方案是“分块处理”子任务统一调度每个子任务只带自己需要的证据不让全局上下文无限膨胀。这个方案对应的是上一节的状态机设计两者配合效果最好。建议在MCP工具返回时就限制字段长度而不是等到组装上下文时再后悔。4.3 模型自信地胡说怎么压都压不住这是研究决策系统最刺痛的部分。我尝试过在prompt里写“请确保事实准确不要编造来源”模型偶尔还是会编。后来发现光靠提示根本不够必须在模型输出之后加一道“物理校验”。校验手段有两类一类是结构约束前面说过的JSON Schema加evidence_id强制引用另一类是事实验证把模型引用的每一条evidence重新跑一遍工具如果结果对不上就拒绝采信。双通道叠加之后胡说的空间被压到很低。还有很多细节温度调太低小于0.2会让模型在复杂推理时思维固化反而不利于发现矛盾调太高又会开放联想。我最终的权衡是事实性任务用0.3动态决策类任务用0.4。不要照着某个绝对数值抄要根据评测集调。4.4 成本悄悄上涨账单比代码先失控研究决策系统热爱检索和验证但这两件事都是烧钱大户。我在V3初期不关心上下文大小每个子任务都全量塞证据结果token消耗翻了好几倍。我现在固定用三招控成本按难度路由简单的查询走小模型处理只有需要深度推理时才上大模型缓存命中相同问题或相似证据结果直接复用不做重复计算按需降级非核心步骤比如格式转换、摘要压缩用轻量模型抽检效果。这套组合打下来单位问题的平均处理成本大概降了一半而且答案质量几乎没有下降。4.5 权限与安全工具越多攻击面越大MCP Server把工具暴露给模型调用的同时也把一个“网络攻击面”带进来了。潜在风险是恶意输入诱导模型调用危险工具比如越权读取文件、执行命令、向外部接口发请求。我的做法是白名单机制每个MCP Server只注册被允许暴露的方法宁可少一个工具也不多放一个风险口子入参校验所有工具参数都做类型和范围校验不合法直接拒绝操作审计每次工具调用都记录时间、参数、调用方、返回结果一旦出问题可以精确回溯。这套权限设计并不复杂但它决定了这个系统能不能真正落地生产。如果只是在实验室里自娱自乐可以跳过如果要给业务团队用安全与权限一定要一开始就划线。4.6 别写“万能工具”最后一条个人经验也是踩过最多坑的地方不要试图写一个“万能工具”。比如我在V2阶段写过一个“综合查询工具”想着什么都能查结果因为描述太泛模型不知道该传什么参数经常把query写成一段很长的自然语言工具内部还得做解析稳定性极差。后来我把“综合查询”拆成“文献检索”“内部文档查询”“数据统计”三个细粒度工具每个工具只做一件事描述清晰参数明确。模型反而更容易做出正确选择。工具粒度原则很简单每个工具解决一个问题宁可数量多一些也不要做一个什么都做、什么都做不好的怪物。5. 直接能抄的最小方案5.1 从零到研究决策系统的四步如果你也想做相似的东西我建议按这个顺序推进每一步都是前一步验证后再走先搭最小MCP Server。只注册一个检索工具和一个摘要工具用一个客户端跑通“对话→调用工具→返回结论”的完整链路。这一步目的就是验证MCP协议通不通别贪多。再加信息组织层。给检索结果做去重、重排、裁剪让模型输入变成一个紧凑的证据包。做完这一步你可以明显感觉到回答质量和稳定性提升。然后加证据链约束。强行要求所有结论带evidence_id输出结构化为JSON。这步是系统从“能聊”变成“能负责”的关键跳跃。最后建回归评测集。积累至少几十条代表性题目每次改配置都跑一遍。这里可以安排自动比对流程不通过的配置不允许上线。这四步的节奏刚好和系统的四个核心模块对应先有壳再有管道再有机制最后有护栏。5.2 关键配置速查表我整理了一个配置速查表覆盖我项目里最常用的几项方便你直接参考配置项建议值说明与注意点工具描述长度80-150字太短没有语义触发太长稀释模型注意力检索top_k默认5综述类10太少漏信息太多挤占上下文温度事实性0.2-0.3决策类0.4低温度压幻觉但过低会影响复杂推理证据包最大长度不超过模型稳定处理长度的70%留出输出与推理的token余量缓存时长知识库数据1小时动态数据10分钟太短没用太长信息过期评测集规模至少60条覆盖事实、对比、风险、报告四类这些值是我项目里调出来的不一定适合你的数据。真正的用法是建好评测集之后用A/B对比测谁给你的指标高就用谁。5.3 建议的技术选型一个轻量的技术组合是这样的服务端用Python配合MCP官方SDK或社区常见的轻量封装来搭建Server状态管理用带存储的关系型数据库或简单的文件存储都行工具注册表配置用JSON文件维护方便管理评测脚本用Python写跑在CI或本地定时任务里。这套选型没有特别前沿的东西但足够稳。它保证了套壳MCP这个起点不会因为选型过于花哨而偏离主线。6. 几句大实话做这个项目最大的体会是软件架构不是设计出来的是长出来的。如果一开始就想着“我要做一个研究决策系统”八成会设计出一堆用不上的模块但从一个薄薄的MCP套壳开始被真实需求一步步推着走反而长出了特别贴合实际的结构。第二句实话是套壳这个词被人看轻了。套壳不是简单包装它是在协议边界上做适配。只要是做研究决策这类严肃场景壳外的协议标准化和壳内的证据链路一样重要。最后分享一个小技巧也是踩过几次坑之后最想早知道的一条当系统长到第五个工具以上记得先写回归评测集再改任何配置。这个顺序能帮你省下大量修复“未知回归”的时间。