ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

大模型应用三层架构:输入工程与输出工程决定AI应用形态

大模型应用三层架构:输入工程与输出工程决定AI应用形态

做过大模型应用的人应该都有这种感觉:一年前还在追各种新模型,半年后在追各种新框架,现在回头看,真正改变应用形态的,从来不是模型底座本身换了多少代,而是大家围绕「输入什么」和「输出怎么处理」这两件事做了太多文章。

我把这套东西整理成了一个三层架构,分享过几次,反馈都说比较适合拿来分析需求、拆解方案。今天展开聊聊这个框架,以及为什么我说所有 AI 新花样,本质上都只是在输入侧和输出侧做改造。

1. 三层架构:底座、输入、输出

1.1 第一层:模型底座层——不变的天花板

模型底座层就是那个被你天天调用的预训练语言模型:它的 Transformer 架构、它的参数规模、它的训练数据、它的推理能力。这一层决定了模型的上限,也是模型厂商们疯狂内卷的战场。

但在绝大多数应用开发场景里,这一层对开发者来说是「黑盒」。你拿到一个 API 调用权限,传一段文本进去,拿到一段文本出来,中间发生了什么你基本控制不了。即便你能做微调,那也是在这个底座之上做有限的适配,而不是重写它的认知能力。

所以我把这一层称为「不变的天花板」。不是说它真的不变,而是在一个具体项目周期内,你能影响的选项也就那么几个:选哪个模型、买多少上下文窗口、用多大的 max_tokens。选择本身有意义,但选完之后,模型内部的参数你一根手指头都碰不到。

1.2 第二层:输入工程层——让模型「看懂」

输入工程层就是标题里「输入什么」的部分。系统提示词、用户问题、上下文拼接、检索增强、多模态内容、工具定义、历史对话……所有这些在你把请求发给模型之前,被人为组装起来的文本和信号,都属于这一层。

这一层之所以有巨大的发挥空间,是因为模型本质上是一个「条件续写器」:它看到什么,就基于什么续写。你在输入里塞进去参照标准,它就照着参照标准说话;你在输入里塞进去企业知识库片段,它就表现得像懂业务的老员工;你在输入里塞进去一段代码报错信息,它就自动切换成调试模式。

做过实际项目的人都知道,同一个模型,换一个输入组装方式,效果可以天差地别。这不是玄学,而是注意力机制在起作用——输入内容的分布会直接影响模型在生成时给哪些词更多的关注权重。

1.3 第三层:输出工程层——让模型「干成」

输出工程层对应标题里「输出怎么处理」的部分。模型生成完内容之后,你如何约束它的格式、解析它的文本、校验它的结果、处理它的错误,以及把它的输出重新变成下一轮输入,都在这一层。

模型输出本质上是 token 序列。你以为它在说「好的,正在为您查询」,但它其实只是在概率分布里逐个选词。所以输出侧工程要做的,就是不让这些词随便组合:要么通过结构化输出约束格式,要么通过解析和校验拦截幻觉,要么通过循环调用把一次生成变成一串行动。

第三层的重要性,被很多人低估了。我刚做第一版对话机器人时,以为把模型响应直接展示给用户就完了。后来才发现,没有输出侧的结构化处理和异常兜底,模型说错话、说废话、说重复话的问题会让你修改到怀疑人生。

1.4 三层之间的关系:一个表看清分工

层级核心问题典型手段谁在管
模型底座层模型能做什么选型、微调、上下文窗口模型厂商、架构师
输入工程层模型看到什么Prompt、RAG、多模态、记忆应用开发者、算法工程师
输出工程层模型产出怎么用结构化输出、校验、重试、Agent循环应用开发者、后端工程师

看这个表就清楚了:模型厂商管底座,而绝大多数 AI 应用的创新空间,集中在中间和下面这两层。你负责的产品体验好不好、业务闭环通不通,往往也取决于这两层做得细不细。

2. 输入侧:所有「让它懂」的功夫

2.1 Prompt 不是说话技巧,而是对注意力的控制

很多人把写 Prompt 当作「跟 AI 好好说话」,这其实是很大的误解。Prompt 的真正作用,是控制模型在生成时把注意力放在哪些信息上。

自注意力机制的计算逻辑比较复杂,但结果可以简化理解:模型生成下一个 token 时,会综合考量输入序列中每个 token 与当前上下文的相关性,相关性高的权重高,相关性低的权重低。你写的 Prompt 相当于在初始化这个权重分布——你重点描述了某个要求,它就会在本轮生成中反复参考这条要求。

举一个我常拿来演示的例子。做客户反馈分类时,我最初写的 Prompt 是「请判断这条评论是好评还是差评」,准确率大概七成。后来改成:

你是电商平台的客服质检员。请仅根据以下用户评论,判断情绪倾向为「正向」或「负向」。 判定标准: 1. 出现表扬、感谢、复购意向 -> 正向 2. 出现抱怨、退货、投诉 -> 负向 3. 模棱两可 -> 负向,需人工复核 用户评论: (在这里粘贴评论)

准确率直接提升到九成以上。Input 内容没有变,变的是输入里给了模型明确的判定坐标和示例边界,它的注意力被引导到了「关键词匹配 + 分类标准」这条路径上,而不是自由联想。

这个案例说明,输入工程不是简单的「把话说清楚」,而是有意识地设计模型应该关注什么、忽略什么、按照什么顺序处理。

2.2 RAG:临时给模型「翻书」,而不是逼它背诵

检索增强生成(RAG)是输入工程里最典型的动作。它的思路非常简单:模型不知道的知识,你在输入里直接告诉它。

为什么大多数场景应该优先考虑 RAG 而不是微调?我个人的判断标准是:如果知识是静态的、需要更新的、数量庞大的,用 RAG;如果行为模式是固定的、风格需要统一的,才考虑微调。

原因在于微调是痛苦的,它需要准备高质量数据集、需要训练资源、每次知识更新都要重来。而 RAG 只需要把新文档切成 chunk、灌进向量库、在查询时检索出相关内容拼进输入里就行。

RAG 的细节里有个容易被忽略的点:检索出来的 chunk 怎么拼、拼在 Prompt 的哪个位置。早期我为了图省事,把检索到的前三条结果直接堆在用户问题前面,结果模型经常分不清「它在回答用户」还是「它在复述资料」。

后来调整成「资料区 + 指令区 + 问题区」的结构,效果立刻不一样:

【参考资料】 (这里放检索到的文档片段,并用编号区分) 【指令】 仅使用参考资料回答用户问题。如果参考资料中没有答案,直接回复「暂未找到相关信息」,不要编造。 引用资料时注明来源编号。 【用户问题】 (用户输入) 【回答】

这个结构的核心逻辑是:把资料区放在指令区之前,让模型先「阅读」资料,再理解指令,最后处理问题。实测下来,不知道答案硬编的情况少了很多。

另外注意,RAG 不是往输入里塞得越多越好。上下文窗口再大,塞进一堆无关片段只会稀释注意力。我一般限制检索片段控制在 3-5 条,每条控制在 500 字以内,超过这个量成本和噪音都明显上升。

2.3 多模态输入与工具上下文:把整个世界塞进输入

多模态输入也是输入工程的一部分。图片、音频、文件、网页链接,这些内容经过处理后最终都会变成模型可以读取的 token 序列,整体上仍然属于「输入什么」的范畴。

比如做智能客服时,用户传一张产品照片,模型基于照片进行故障判断。输入侧的工作包括:把图片转成模型能理解的格式、在 Prompt 里说明这张照片是用户实拍图、要求模型结合照片中的细节做分析。这一套流程里,模型底座的视觉能力是前提,但真正让功能成立的,是你如何把「图片 + 业务规则 + 用户问题」组装成一个有效的输入。

工具上下文也值得提一句。如果一个 Agent 需要调用多个工具,你必须在输入里把每个工具的名称、功能、参数格式描述清楚。有些 Team 觉得 Agent 不听话、不会选工具,多数时候不是模型的问题,而是工具描述写得太含糊。你把工具描述写成「用天气API查天气」和「查询指定城市未来7天天气,入参:city_code(城市代码)、days(查询天数)」,模型的选择准确率完全是两个水平。

2.4 输入侧实战:一个客服系统的输入拼装示例

拿一个实际项目举例。我做过一个售后客服答疑系统,底座模型没换过,所有改动都在输入层:

初始版本只是用户提问拼上系统 Prompt,回答经常跑偏。迭代后的输入结构长这样:

【系统信息】 你是某品牌的售后客服顾问,回答必须简洁、准确、不啰嗦。 【对话历史】 (最近三轮对话,按时间倒序) 【知识库参考】 (按向量相似度检索出的售后政策片段,每条带编号) 【用户当前问题】 (用户最新的提问) 【要求】 1. 优先依据知识库参考回答,没有依据时直接说不清楚 2. 涉及退款、换货时,必须引用具体政策条款编号 3. 回答控制在150字以内

这个结构里的每个区块都有明确分工:系统信息定角色,对话历史给上下文,知识库参考给事实依据,当前问题是触发点,要求约束输出风格。三个月的线上数据对比下来,同样一颗模型底座,改动只发生在输入侧,一次解决率提升了差不多三成。

3. 输出侧:所有「让它干活」的功夫

3.1 解码参数:模型输出的第一个约束

很多人对解码参数的理解还停留在「temperature 高一点更有创意」,这有点浪费。解码参数是输出工程的第一道阀门,它决定模型在生成时如何做选择。

temperature 控制的是概率分布的锐化程度。温度越低,越倾向选概率最高的 token,输出更稳定、更保守;温度越高,越倾向在较低概率的 token 里冒险,输出更多样、更容易发散。top_p 控制的是候选池的大小,只在累计概率前百分之多少的 token 里选。max_tokens 限制输出长度,stop 序列则可以在命中某个字符串时强制停止生成。

我一般的参数组合经验:

场景temperaturetop_p备注
客服答复0.1-0.20.8求稳,避免自由发挥
文案创作0.7-0.90.9保持多样的同时不离谱
代码生成0.2-0.30.8稳定优先
数据分析/推理0.0-0.20.7尽量确定性输出

要注意的是,temperature 和 top_p 不是叠加使用的,通常固定一个、微调另一个。两个都调高很容易让输出变成脱缰野马。

3.2 结构化输出:让模型从「说话」变成「交数据」

做应用的人最怕什么?最怕模型输出一段漂亮的话,但你的代码根本没法处理。所以输出工程的核心目标之一,是逼模型交出结构化数据。

JSON Mode 就是干这个的。你要求模型只输出合法 JSON,配合 Prompt 里给出的字段定义,它就能把回答变成你直接能解析的对象。举个例子,做一个差评分析功能,我在 Prompt 里规定:

请输出 JSON 格式,字段如下: - sentiment: 正向/负向/中性 - category: 产品/物流/客服/其他 - summary: 一句话总结 - keywords: 关键词数组 示例输出: {"sentiment": "负向", "category": "物流", "summary": "用户抱怨配送超时", "keywords": ["配送慢", "超时"]}

配合 JSON Mode,模型返回的就不再是一段自然语言,而是一个可以直接反序列化的对象,后端落库、统计、打标一气呵成。

Function Calling 是结构化输出的进阶形态。它让模型在回复里携带一个结构化的函数调用请求,比如:

tool_calls: [ { "name": "search_orders", "arguments": {"user_id": "12345", "status": "pending"} } ]

代码解析到这个结构后执行真实查询,把查询结果作为下一轮输入再交给模型。这一步非常关键,因为它的本质是:模型负责决策,代码负责执行,输入和输出像装配线一样循环起来。

顺带说一个坑:有些模型开了 JSON Mode 仍然偶尔输出 JSON 外的前缀词,比如「好的,以下是.....」。这种情况不要只靠模式开关兜底,在后端解析时要做容错处理,比如剥掉首个{之前的字符,再尝试解析。

3.3 输出校验与重试:别相信模型,相信校验器

模型输出里最让人头疼的就是幻觉和不合规数据。幻觉的终极解法不在模型侧,而在输出侧的校验代码里。

我之前做过一个医疗问答系统,模型回答中如果出现药品剂量,必须经过规则校验:剂量是否在安全范围、是否与药品说明书一致、是否与咨询者描述冲突。这些校验不依赖模型二次判断,而是用确定性的代码去卡。

还有纯格式层面的校验。比如模型被要求输出 200 字以内的总结,结果它输出了 600 字;要求只输出三要素,它给加了第四点。这种情况我会在代码里截断、抽取首段、或者重新调用一次模型要求压缩。

重试策略也值得设计一下。我常用的策略是:第一次解析失败时,把报错信息和原始输出一并拼进新 Prompt,让模型自己修改输出。效果比无脑重试好得多,因为模型看到自己的错误长什么样之后,修正能力相当强。

这个流程总结起来就是:生成 -> 解析 -> 校验 -> 不合格就带着错误信息重新生成。最多重试两次,超过三次直接转人工兜底。

3.4 输出侧实战:让模型输出直接可落库

做一个用户反馈归因分析模块时,我设计了这样的输出侧流程:

第一步,模型输出 JSON,包含反馈分类、情绪、关键信息。第二步,后端解析 JSON,如果解析失败,截取 JSON 片段再次尝试。第三步,业务规则校验,例如手机号字段必须是 11 位数字、订单号必须存在,校验不通过则字段置空并标记。第四步,规整后的数据写入数据库,同时记录模型的 raw_output,方便日后排查。

这套流程跑下来,模型输出的脏数据比例被压得很低。即使偶尔出现模型发疯,系统也能保证库里存的是干净的、结构化的、可追溯的数据,而不是一段飘忽不定的车轱辘话。

4. 为什么「输入什么 / 输出怎么处理」能解释所有新花样

4.1 Agent:输出侧长出了一个调度器

Agent 是这两年最火的 AI 新花样之一,拆开看,它并没有绕过三层架构。Agent 做的是:在输出侧长出一个工具调用的调度器,在输入侧循环注入工具执行结果。

具体拆解:模型首轮输出一个函数调用请求,这是输出工程在管;代码执行这个调用拿到真实结果,这是应用逻辑在管;把执行结果拼接回输入喂给模型做下一轮推理,这是输入工程在管。如此循环往复,直到模型输出一个「最终答复」或「结束指令」。

所以 Agent 所谓的「自主规划」「多步推理」,并不是模型突然变聪明了,而是你把一次问答拆成了多轮「输出工具调用 -> 回填执行结果 -> 再输入继续推理」的循环。循环本身没有魔法,每一轮的输入和输出都可控、可观测、可干预。

理解了这一点之后,你会发现做 Agent 的核心难点根本不在「让模型想明白」,而在「如何把工具执行结果高效地组织成输入」,以及「如何在输出里稳定地拿到正确的工具调用参数」。这两个点都是输入工程和输出工程的活。

4.2 RAG、多模态、工作流:都是输入输出的排列组合

我们来把目前常见的新花样挨个过一遍:

  • RAG:输入侧注入检索到的外部知识,本质是炒资料的拼装。输出侧仍走标准问答流程。
  • 多模态:输入侧增加图像、音频、文件内容,让模型「看得见」。输出侧有时也产出多模态结果,比如文生图,这时输出侧要做的是把生成结果校验、转码、落存储,再通知下游。
  • 工作流编排:多个模型节点串成流水线,前一个节点的输出就是后一个节点的输入。整个工作流设计都是在连通「谁的输出」和「谁的输入」。
  • 结构化报告、合同审查助手、代码评审工具:无一例外,要么在输入侧塞规范文档和审查标准,要么在输出侧生成严格遵守格式的结果。

如果你拿到一个新需求时不知道从哪里下手,先问自己两个问题:模型需要看到什么材料才能给正确答案?模型产出的结果要满足什么格式、经过什么校验才能被业务使用?这两问基本能定出方案的骨架。

4.3 底座层真的不重要吗?——边界问题

讲到这里可以回答一个争议:是不是底座层直接可以忽略?当然不是。底座层决定了模型能力的边界,输入工程和输出工程只是在边界内把能力发挥到极致。有些任务模型底子不够,输入输出改出花来也做不了,比如复杂的数学推理、超长文本理解这类场景,底座能力的差异是硬门槛。

但大多数业务应用落不了地、体验差,问题并不在底座,而在输入输出这座桥没搭好。很多人一遇到效果差就想去换模型、做微调,我的建议是先检查一下自己的输入组装是不是足够严谨、输出校验是不是足够兜底,大概率能省下很大成本。

4.4 一个核心心法:把模型当「能力受限的实习生」

用一句话总结我的三层架构心法:不要指望模型肚子里那点权重满足你,而是要把它当成一个能力很强但胆子很大的实习生,你要做的是给足参考资料(输入工程),明确提交格式和验收标准(输出工程),再配好异常处理机制(输出工程)。

这样想之后,很多问题就豁然开朗。实习生答不上来问题时,你会赶紧翻资料递给他,而不是逼他硬编,这对应 RAG。实习生交上来的东西常常不合格式,你会建好模板让他照填,还要有检查的人,这对应结构化输出和校验。实习生干一个复杂任务容易忘步骤,你会拆成几步一步一催,这对应 Agent 循环。

5. 实操中的常见问题与排查实录

5.1 输入侧典型翻车现场

先说几个我踩过的输入侧坑。

第一个是上下文爆满。对话历史无限拼接,结果模型越来越「健忘」,反而对最新问题视而不见。后来我给上下文设了滑动窗口,只保留最近三轮对话,再配合一个事先提取好的用户关键信息摘要,效果立刻回升。摘要由模型生成,每轮更新,相当于把长对话压缩成关键状态。

第二个是检索增强变负效果。一次我在金融问答里塞了很多新闻片段,模型反而被噪音带偏,回答出现股评式口吻。排查后发现是检索片段中混入了大量营销性质的内容,质量标准没设好。后来给知识库加了一轮内容质量过滤,再调整检索相似度阈值,线下测试才恢复稳定。

第三个是角色设定和指令冲突。系统 Prompt 里写了「你是严格的中立助手」,任务区又写道「强调产品的优点」,模型输出经常自相矛盾。这种问题本质是输入内部的逻辑打架,排查时要把整个 Prompt 从头读一遍,看看有没有互相抵消的指令。

5.2 输出侧典型翻车现场

输出侧也有几个高发性事故。

JSON 解析失败是我见过最多的问题。典型表现为多了一个逗号、单引号当双引号用、或者开头多了句「好的」。处理方案不只是开启 JSON Mode,还要在后端做第一层剥壳、第二层尝试局部 JSON 提取、第三层把解析报错回喂给模型重试。

停不下来也是常见问题。模型在 Agent 循环里反复调用同一个工具,或者生成了结尾标志却不结束。我会在输出校验里加入「循环次数上限」和「重复工具调用检测」,连续三次相同调用强制终止,并转交给兜底逻辑。

还有一种情况是模型「过度承诺」。客服场景里模型回答「我们会尽快退款」,但售后流程根本不允许这么大的权限。解决方式是在输入侧补一句「若涉及退换货,说明转人工处理,不要承诺具体进度」,这属于输入约束和输出校验双管齐下。

5.3 一张速查表:按症状找根因

症状可能根因优先检查点
回答问非所答输入里关键信息被淹没Prompt结构是否清晰、历史对话是否太长
总是编造事实输入缺少参考依据是否配置RAG、参考资料质量如何
输出格式不稳定缺少格式约束或输出校验是否开结构化输出、解析容错是否到位
Agent反复调用同一工具输出侧缺停止条件循环上限、重复调用检测
模型太啰嗦输出侧缺长度约束max_tokens设置、Prompt里是否有字数要求
换一次模板效果就崩输入侧指令冲突系统Prompt与任务指令是否互相矛盾

这张表不能穷尽所有情况,但可以作为排查的第一站。遇到问题先对号入座,大概率能缩窄调试范围。

我在实际项目中还有一个习惯:每次改动只动一个变量,要么只改输入,要么只改输出,不做混合调整。这样出了问题,回溯起来简单很多。接收一个存量项目时,第一件事也是先把现有 Prompt 和输出处理逻辑完整读一遍,搞清楚哪些约束在起作用,哪些只是历史遗留,然后再谈优化。

三层架构这套框架,说到底是一个分析和拆解的工具。它不保证你一次就能做出惊艳的应用,但能帮你在面对复杂的 AI 需求时快速找到下手点:先想清楚模型要看到什么,再想清楚返回的东西怎么处理、怎么进业务流程,剩下的事,就是像搭积木一样把输入输出接成一个顺畅的闭环了。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进