刚接触大模型的人常卡在同一个问题上:模型答得不对,到底是提示词没写好,还是它压根不知道这件事?前者靠 Prompt 工程,后者才轮到 RAG。搞混了会白折腾很久——把资料塞进提示词里当 RAG 用,几十页就开始丢细节;该写清楚的要求却去搭知识库,纯属绕远路。这篇不重复原理,只讲两者在接入方式、代码结构、运维成本和验收方法上的实际差别,帮你判断某次需求该走哪条路。
刚碰大模型的人常卡在同一个岔路口:模型答得不对,到底是提示词没写好,还是它压根不知道这件事?这两种情况要动的地方完全不同。前者属于 Prompt 工程,后者才轮到 RAG(检索增强生成)。混淆的代价不小,最常见的是把几十页资料直接塞进对话里当知识库用。开头几段还行,往后模型就开始丢细节、记错条目,因为你其实是在用提示词冒充检索系统。
另一头也很亏:明明只是要模型换个语气、按固定格式输出,却兴师动众去搭向量库、清洗文档、配索引,绕了一大圈远路。这篇不讲原理,只讲两者在接入方式、代码结构、运维成本和验收方法上的实际差别,给你一套能照着走的选择流程。需要预先说明的是,本文提到的所有价格、能力范围、延迟水平,都不写死数字,一律到站内页面核对当时的口径。
先分清:模型是「没听懂」还是「不知道」
判断的第一步不是改代码,而是做一个小实验。同一件事换三种说法去问:先平铺直叙,再给一个示例,最后要求它分步思考。如果表现明显变好,问题就出在指令侧,属于 Prompt 工程的活儿。如果怎么说都答不出,或者答得像模像样但细节全是编的,那多半是知识压根没进到上下文里,这才需要检索。
- 判断口诀:换个说法它就会答,通常是 Prompt 问题;怎么说都答不出或答得似是而非,多半是知识没进上下文
- 可执行动作:同一问题问三遍,分别改措辞、补示例、要求分步,观察表现有没有台阶式的改善
- 对照组实验:把一段标准答案原文贴进对话再问同一个问题,如果这次答对了,说明缺的是知识不是指令
- 注意边界:模型本身能力不足时(复杂推理、小众语言、特定领域代码),两条路都不解决问题,得先换模型
需要提醒的是,这个判断法有失效的情形。当问题本身超出模型能力范围时,你会发现改措辞、给示例、加检索都没有用,输出质量始终在一个低水平上徘徊。这时候该做的是换模型,而不是继续在提示词或检索上打磨。当时的模型范围和各自擅长的方向,到 /models 看当时的资料,别凭印象选。
Prompt 工程管的是什么:同一份资料的表达方式
Prompt 工程解决的是一个很具体的矛盾:模型其实知道这个知识,但输出不符合你的要求。要求包括格式、语气、长度、边界、什么时候该拒答、遇到模糊问题先反问还是先猜。它本质上是把模型已有的能力约束到你想要的形状上,而不是给它补充新信息。
落地形态上,最值得养成的一个习惯是把系统提示词集中管理——放在一个文件、一个常量、或者一份配置里,不要散落在业务的十几处调用中。散落的后果是改一处忘一处,线上表现忽好忽坏,排查时连「到底发出去了什么」都说不清。
| 适用情形 | 不适用情形 |
|---|---|
| 统一输出格式、语气、角色设定 | 需要精确引用原文出处 |
| 规定拒答规则和边界条件 | 需要按用户权限过滤内容 |
| 把长任务拆成分步指令 | 知识截止之后发生的事 |
| 要求模型先澄清再作答 | 公司内部规章、私有文档 |
表格右侧那几项是很多人踩过的坑。靠提示词去约束「只能引用原文」并不可靠,模型仍会顺手改写;靠提示词做权限过滤更危险,用户换个问法就可能套出不该看的内容。这类需求得上检索层,在召回阶段就把不该给的内容挡在外面。
RAG 管的是什么:把资料找出来再放进上下文
RAG 解决的是「模型不知道」这件事,对象是私有文档、内部规章、更新频繁的业务资料。工程上它不是一个函数,而是一条链路:文档清洗切块、向量化入库、检索召回、拼进提示词、生成答案。每一段都能单独坏掉,这也是它比写提示词难维护的根本原因。
什么时候值得上?下面这几条满足任意两条,投入就比较划算。
- 资料量大到塞不进上下文窗口,硬塞会导致模型丢细节
- 需要对答案标注来源,让用户能点回去核对原文
- 内容会持续更新,不想每次更新都手工改提示词
- 同一个知识库要服务多个入口,比如客服机器人和内部问答共用一份资料
反过来,什么情况不该上?资料就一两页、几个月才改一次,直接贴进提示词更省事。引入向量库会带来一整套新麻烦:嵌入模型选型、切块策略、索引重建、检索调参。为了几页 PDF 背这些运维负担,不划算。具体到你的场景值不值,可以先到 /tools/token-price-calculator 用当时的单价粗算一遍上下文成本和检索成本的对比。
写进代码里长得完全不一样
两者的代码改动面差别很大。Prompt 工程的改动集中在字符串和少量参数上:系统提示词的内容、温度、最大输出长度。改完就能跑,影响面小,回滚也快。RAG 的改动是数据管线层面的:切块大小与重叠、嵌入模型、向量库配置、召回条数、重排序策略,任何一项动过,都得跑一遍全量重建才能验证。
- Prompt 侧的关键字
- system 提示与温度参数,改的是每次请求发出去的那段文本
- RAG 侧的关键字
- 检索调用,一次问答里多出一次外部请求,也就多一个超时点
- 失败处理
- 检索失败要有兜底,是直接报错、降级到无检索回答,还是提示用户重试,得事先定好
- 排查顺序
- 先看检索回来的片段对不对,再看拼进提示词的位置和长度,最后才怀疑生成模型
上面那个排查顺序值得记住,很多人是从最后一步往回查的,白白在生成侧调参数。实际线上问题里,相当一部分是检索根本没召回正确片段,模型再强也变不出来。把检索返回的原文先看一眼,往往几分钟就能定位。
# 排查时的最小日志,务必把实际发给模型的完整提示词落盘
cat /var/log/llm/request.log | tail -n 20
# 重点看两段:检索返回的片段原文、拼接后的最终提示词长度成本与延迟:一个看 token,一个看链路
Prompt 工程的主要开销是输入 token 一路涨。上下文塞得越满,每次请求越贵越慢,而且这个成本是按请求次数线性叠加的。RAG 的开销分两段:入库的一次性成本(嵌入计算和存储),以及每次问答的检索加生成。两段的账要分开算,不然容易高估或低估。
| 对比项 | Prompt 工程 | RAG |
|---|---|---|
| 成本结构 | 按每次请求的输入输出 token 计 | 入库一次性成本 + 每次检索与生成 |
| 延迟来源 | 上下文越长越慢 | 检索耗时 + 生成耗时,两段可分别优化 |
| 可优化点 | 精简提示词、减少无关上下文 | 检索结果缓存,命中即跳过向量查询 |
| 扩容方式 | 换更便宜的模型或压缩上下文 | 控制召回条数、分层索引 |
| 估算口径 | 到 /tools/model-cost-calculator 按当时数字核 | 到 /tools/token-price-calculator 按当时数字核 |
延迟上有一个 Prompt 侧没有的优化点:检索可以加缓存。高频问题命中缓存后直接跳过向量查询,只留下生成那一段耗时。这个做法在 FAQ 类场景里效果明显,但要注意缓存失效策略——源文档更新后不失效,就会一直返回旧答案。
线上出问题,两边的排查方向不一样
Prompt 侧的典型故障是顾此失彼:为了修某类问题改了提示词,另一类问题反而变差;或者模型开始自行补全格式,输出看起来规整但字段是编的;再或者拒答边界悄悄漂移,原来会拒的问题现在开始答了。这些问题不会报错,只能靠用例回归发现。
RAG 侧的典型故障更偏数据:召回为空、召回一堆不相关片段、切片把一句话劈成两半、源文档更新了但库里还是旧版本。后两种最隐蔽,因为模型会拿着错误的片段一本正经地作答。
- 第一步:落盘完整请求把实际发给模型的完整提示词写进日志,包含检索片段和拼接后的全文。这一条能省掉大半扯皮。
- 第二步:检查召回片段单独看检索返回的 top 几条原文,判断答案是否在里头。不在,问题在检索侧。
- 第三步:检查拼接位置片段是否被截断、是否排在提示词末尾被忽略、是否和指令部分混在一起互相干扰。
- 第四步:才怀疑生成前三步都正常才调生成侧参数。跳过前三步直接调温度,通常白费功夫。
运维上还有一件事容易被漏掉:RAG 需要一个重建索引的触发机制。文档一变就得重跑,可以是定时任务,也可以是文档系统变更后发消息通知。忘了这步,系统会一直答旧内容,而且答得很自信。检索环节的常见调法,站内 /guides/rag-retrieval 有更细的说明,可以对着排查。
一张对照表帮你定路线
把前面的判断收拢成一张表,照着对号入座即可。核心原则是:两者不是二选一,RAG 检索出来的片段最终还是要靠 Prompt 组织成答案,所以顺序上先写好提示词,再决定要不要加检索这一层。
| 你的需求 | 走哪条路 |
|---|---|
| 只要求输出格式、语气、流程稳定 | Prompt 工程 |
| 要求引用原文、覆盖大量私有资料 | RAG |
| 资料小且静态,几个月才改一次 | Prompt 里直接贴 |
| 资料大或持续更新,多入口共用 | RAG |
| 既要格式规范又要引用来源 | 两者一起用,先 Prompt 后 RAG |
还有一种情况值得单独说:资料规模不大但问题类型很杂。这种场景下,先把 Prompt 打磨到位,往往能覆盖大部分需求,剩下的边角问题再靠检索补。一上来就搭全套 RAG,很可能大部分精力花在了维护索引上,而不是提升回答质量。
上线前怎么验证:小样本评测就够用
不用等体系化评测平台,二十条左右真实问题就能开工。用例集要覆盖两类:该答对的(考准确性)和该拒答的(考边界)。两类混在一起测,才能看出改动有没有把拒答能力搞坏。
- 准备约二十条真实问题,一半该答对、一半该拒答,覆盖主要业务分支
- Prompt 改动只看输出格式与立场是否稳定,先不掺检索变量
- RAG 改动额外看一条指标:召回片段里是否包含标准答案
- 每轮改完跑全量用例,把通过率记下来做前后对比,别凭印象说「好像变好了」
- 用例本身的答案要人工确认过,否则评测基准就是错的
这个方法的适用边界也要说清:只有个位数用例时,结论不可靠,一次随机波动就能让你误判方向。先把覆盖面攒够,再谈优化。回归的具体做法和记录格式,站内 /guides/prompt-version-regression-testing 讲得比较细,可以直接照着搭一套最小的流程。
下一步想动手对比不同模型在你用例上的实际表现、或者想先摸清各家的单价口径再决定要不要上检索,可以先到 /tools/speed-test 跑一轮,再到 /models 看当时的模型范围和费用资料,两边的数字都以站内当时的页面为准。→常见问题
我有一份公司文档,是用 Prompt 还是 RAG?
先看体量和使用频率。几页、很少更新、问答不频繁,直接把内容贴进系统提示词就够;几十页以上、还在持续增补、需要指出答案出自哪一段,那就该上 RAG。中间地带可以先用 Prompt 试,撑不住了再补检索层。
做 RAG 就不用管提示词了吗?
不是。检索只负责把相关资料捞出来放进上下文,怎么组织这些片段、要求模型只依据片段回答、答不上来时要它明确说不知道,全靠提示词。检索烂加提示词好,还能救回一部分;反过来基本救不回来。
为什么我加了知识库,模型还是答错?
大概率是检索这一段出的问题,不是生成。先看日志里实际召回的片段有没有包含正确答案:没有就是切块或嵌入模型不合适;有但模型仍答错,才是拼装和提示词的问题。按这个顺序查,别一上来就调参数。
两者哪个开发成本更高?
Prompt 侧主要是反复试和改,人力密集但不重;RAG 侧多出一整套数据管线,还要管索引重建和检索调优,前期投入明显更大。资料规模不大的场景,先做提示词往往更划算。
改提示词会影响到已经在跑的检索问答吗?
会。检索回来的片段最终要拼进提示词模板里,模板一改,所有走这条链路的功能都受影响。所以提示词该集中管理,改动后跑一遍回归用例,别在生产上直接手改。