资讯动态

从提示词工程到RAG与Agent:大模型实战进阶指南

发布时间:2026/10/20 11:42:47 来源:尧图企业网站定制
这篇笔记是系列的第二篇。第一篇讲的是从零开始感受AI能力边界聊了聊大模型能做什么、不能做什么。这篇换个角度直接从“会聊天”走向“能干活”把提示词工程、上下文管理、检索增强生成RAG、Agent雏形这些概念串起来用一套完整的实战案例告诉大家怎么把一个只会对话的模型变成能帮你处理实际任务的工具。如果你是那种已经用完各类AI助手、觉得“AI不过如此”的朋友这篇笔记可能是你需要的转折点。因为我会直接给你一套可以复现的工程思路让你看到所谓“进阶用法”到底在解决什么问题——本质上就是在管理模型的上下文、约束模型的输出、给模型外挂知识库、最后让它自己决定调用什么工具。1. 先从一次真实的“翻车”聊起为什么AI总在关键时候掉链子前一阵我帮一位做运营的朋友搭了一个“产品文案助手”需求非常朴素输入产品名称和卖点AI自动生成三版不同风格的朋友圈文案。第一天跑通的时候效果惊艳输出质量吊打市面上多数模板工具。结果第二天一上班朋友发来消息“它抽风了写的文案驴唇不对马嘴。”我跑过去看了一眼发现问题出在一个特别不起眼的地方朋友在对话历史里粘贴了一张产品截图然后继续追问新产品的文案需求。模型看得到前面的截图就会同时参考截图中的旧产品和命令里的新产品两个信息源相互冲突输出自然飘了。这个场景听起来很初级但它背后藏着一个核心概念——模型本身没有记忆。它每一次回答都在读取完整的上下文然后根据这些文字预测下一个最可能的词。你以为它在和人聊天其实它在做一场高难度的“接龙”游戏。你把什么喂进上下文它就基于什么来写下文。这也是为什么AI进阶的第一课不是学什么花哨算法而是学会管理上下文。很多人用不好AI根本原因就是不会“喂”信息。要么一股脑把几万字资料塞进去要么挤牙膏一样一句一句问模型的输出质量当然不稳定。我打个比方你把一个新人员工叫进会议室他能不能给出靠谱的答案取决于你给的背景资料是否完整、问题是否明确、期望的输出格式是否清晰。模型也一样。因此这次笔记我搭了一个小项目名字叫“某跨平台知识问答系统”用来验证一套可复现的AI应用构建流程。整体思路并不复杂拆开看就四层上下文构造层决定喂给模型什么内容以什么顺序、什么格式喂。指令约束层定义模型的角色、任务、输出格式和禁忌事项。知识增强层让模型在回答时先检索你的私有资料而不是凭空编造。工具调用层让模型在需要的时候主动去查数据、算逻辑而不是硬着头皮“编”。下面每一层都是这次笔记的重头戏。我用实际代码和踩坑记录来讲尽量做到你能直接复制去用。2. 上下文构造先学会和模型“对齐”2.1 为什么上下文结构比模型参数还重要有个说法我很认同同样的模型会喂上下文的人和不会喂的人用出来的效果差距可能比换一个更大参数的模型还明显。这不是玄学是有工程依据的。主流大模型大多采用Transformer架构核心机制是自注意力。模型在生成每一个词的时候都会回看整个输入序列计算输入中哪些词和当前词最相关。你的上下文越长模型需要关注的潜在相关点就越多注意力被稀释的概率就越大。所以在构造上下文时要把握一个原则信息密度优先长度其次。我自己在项目里验证过同样是问“帮我总结这份季度报告”以下两种上下文的输出质量差距巨大。第一版信息低密度用户这是一份季度报告帮我总结一下。 系统请总结以下季度报告{整篇报告复制粘贴进来8000字}第二版信息高密度系统你是一名资深商业分析师擅长从报告中提炼关键结论。请阅读报告内容并以“重要结论、关键数据、风险提示”三部分输出。报告正文如下。 用户{只粘贴报告中包含核心结论、关键数据的片段约1500字}第二版的输出稳定很多因为系统消息把模型的“角色”锁定在了分析师位置用户消息里又做了一个粗糙的降噪只留下最有价值的信息。模型不需要在一堆口水话里大海捞针自然更容易输出高质量结果。2.2 一套实用的上下文组织模板在“某跨平台知识问答系统”里我用了一套固定模板这里分享出来。如果只记住这一条笔记建议记住这个。def build_context(question, retrieved_chunks, history): context { system: ( 你是一个严谨的智能助手。请严格依据参考资料回答用户问题。 如果参考资料中没有相关信息请明确回答资料库中未找到相关内容 不要编造事实。回答控制在300字以内使用简洁的中文。 ), history: history[-4:], user: { question: question, reference: \n\n.join(retrieved_chunks), format_instruction: ( 请按以下结构输出\n1. 直接答案\n2. 依据说明\n ) } } return context这个模板做了几件事给模型框定了角色和边界你是“严谨的智能助手”意味着不太需要额外解释。限制输出长度300字以内避免模型放飞自我写小作文。强制引用来源让回答有迹可循把凭空编造的概率降下来。截断历史对话只保留最近4条防止过长的历史干扰模型对当前问题的判断。第4条是我在项目里临时加的。一开始没做截断跑了一周后发现一个典型问题历史消息越翻越多模型开始“过度参考”旧对话里偶尔出现的错误信息甚至出现用户已经改口了新问题、模型还在延续旧话题的情况。加上截断后这个问题基本消失。2.3 关于上下文窗口的执念可以放下了这一两年各家模型都在拼参数动辄几百K的上下文窗口听起来很唬人。但我实际测试下来的感受是上下文窗口大不等于你该把它用满。就像一个大冰箱你可以塞进一整头牛但如果你只是想煎块牛排没必要把冰箱塞满。窗口越大注意力分散的可能性越大处理延迟也会变高更重要的是很多模型在中长文本上的表现存在“迷失在中间”的现象——开头和结尾的信息容易被模型关注中间夹着的重要信息往往被忽略。因此我给自己定的策略是能用精简摘要解决的绝不塞原文能用取片段解决的绝不整个文件丢进去。3. 提示词工程从“会问问题”到“会下指令”3.1 为什么同一件事换个问法效果天差地别我知道很多人都看过那种“神仙提示词”合集用的人觉得玄不用的人觉得扯。但提示词工程的存在是合理的只是市面上很多传播版本把它包装得过于玄学。拆开来看所有高级提示词的底层逻辑就那么几条。先说最容易被忽略的一条模型是基于概率生成内容的你的指令越模糊它的输出概率空间越大结果就越不可控。你问“怎么写好一篇文章”模型可以给你一万种答案你问“请以产品运营的身份为一场面向新用户的活动写三段不同风格的邀请文案每段不超过50字”模型能够输出的范围就被大大压缩了质量自然提升。那为什么很多人用了结构化提示词还是效果不好因为大部分人只学会了“堆砌指令”却没有理解指令之间的优先级。当你的提示词里同时出现“语言生动有趣”和“保持专业严谨”这类互相矛盾的指令时模型只能随机选择一个方向执行结果就是两种风格都不太像。3.2 一个亲测有效的提示词四层结构我在项目里把提示词拆成了四层按优先级从高到低排列角色锚点你是谁你的立场是什么。任务指令你要做什么不要做什么。约束条件输出格式、长度、语气、引用规则。示例引导很少量但高质量的示例比大段文字描述有效得多。这四层有一个明显的好处每一层都在给模型“缩小搜索空间”。角色锚点决定口吻任务指令圈定内容范围约束条件卡死输出框架示例引导给出参照系。层与层之间不冲突模型执行起来负担也小。来一个直观对比。同样是“让模型改写一段话”。低质量提示词用户帮我把这句话改得更吸引人。 原文本产品是一款智能保温杯具备长效保温功能。其实这个写法不算差但模型输出的“吸引人”理解会非常随机。同一段话有人改成夸张广告体有人改成文艺抒情体有人改成硬核参数体。高质量提示词系统你是一位擅长社交媒体文案的编辑文风犀利喜欢用具体细节代替抽象描述。 用户请改写以下产品介绍目标是吸引25-35岁通勤上班族。 要求 1. 避免使用“智能”“长效”这类抽象词。 2. 用具体使用场景贴合目标人群。 3. 总字数不超过60字。 原文本产品是一款智能保温杯具备长效保温功能。后者的输出基本可以稳定落在“通勤路上想喝口热的”这类场景化表达上不仅含混度低而且读者代入感更强。3.3 少样本示例最被低估的提示词手段文本描述再详细都不如直接给模型看一段“正确输出”来得直观。我在项目里专门维护了一个examples.json文件里面存了五六组“问题—标准输出”对每次调用模型前挑两组最相关的拼进提示词里。示例数量不需要多多了反而干扰模型对核心规则的抓取。我实测下来两三组高质量示例的效果远胜于十组参差不齐的示例。因为示例的本质是在告诉模型“目标分布长什么样”你给的示例之间如果风格相互冲突模型会学到错误的规律。另外注意一点示例里的占位信息要足够通用避免模型只学会模仿字面结构而不是理解语义。我之前写过一组示例里面统一用了“某款产品”结果模型在正式回答里好几次把用户的问题误解成“某款产品”指代的对象折腾了半天才发现是示例惹的祸。4. 知识增强打造一个会查资料的AIRAG实现4.1 为什么模型需要外挂知识库大模型最容易被人诟病的一点就是它天生自带“一本正经胡说八道”的属性。随便问一个它的训练数据里没有的冷门问题它大概率会编一个听起来合理但经不起推敲的答案。这就是业内说的“幻觉”。幻觉的根源在于模型的目标不是“告诉你真相”而是“生成看起来合理的文本”。如果你只有这一个模型、没有别的信息来源那它只能靠自己的“大脑”硬编。所以你一旦需要AI回答私有文档、最新数据、垂直领域问题就必须给它一个外挂的知识库让它在回答前先查资料而不是凭记忆直接作答。这个方案有个专业名字检索增强生成简称RAG。它的核心流程可以用一个很朴素的话总结先生成答案前先把相关资料捞出来喂给模型当参考再让模型基于这些参考作答。4.2 最小可用的RAG全流程附代码我在“某跨平台知识问答系统”里实现了一个最小版本的RAG用了不到150行Python代码。流程分四步第一步加载文档按固定长度切块。第二步把每块文本转成向量。第三步把用户问题转成向量在库里做相似度检索。第四步把命中的文本块拼进上下文交给模型生成最终回答。切块是第一个要注意的细节。太长会包含太多噪声检索不精准太短会破坏语义完整性。我实验下来按200到400个字符左右切块配合20%左右的重叠效果比较均衡。为什么要有重叠因为一个完整语义单元可能恰好被切在边界上重叠可以在一定程度上缓解这个问题。向量化部分我用的是一个开源嵌入模型。嵌入模型的作用是把一段自然语言变成一组几百维的浮点数数组。这样“今天天气怎么样”和“今日气候如何”这两句话在向量空间里就会靠得很近即使字面表达完全不同。检索部分用到了最简单的余弦相似度计算把用户问题和所有切片向量逐一比较取最相似的前3条作为候选。为什么是3条而不是10条因为候选太多拼接进上下文后会把模型的注意力撑散生成质量反而下降。import numpy as np from sklearn.metrics.pairwise import cosine_similarity def retrieve(question_embedding, chunk_embeddings, chunks, top_k3): # 把二维数组转成统一形状逐条计算余弦相似度 scores cosine_similarity([question_embedding], chunk_embeddings)[0] top_indices np.argsort(scores)[-top_k:][::-1] return [chunks[i] for i in top_indices], [scores[i] for i in top_indices]代码很简陋但意思到位了。真实生产环境下有很多更花哨的检索策略比如混合检索、粗排精排两阶段、查询改写等等。但对一个从零起步的工程项目来说先让最小流程跑通比一上来就堆高级算法重要得多。4.3 RAG里最容易被忽略的三个坑第一个坑切块策略直接影响检索质量而且没有万能参数。我一开始默认用了500字符切块结果问答准确率只到70%左右。把切块长度改成动态切分按照自然段落边界来分段之后准确率明显上升。建议在切块上多花一点时间这决定了RAG系统的上限。第二个坑检索回来的内容不一定和问题相关。相似度检索只能保证“看起来像”不能保证“意思对”。所以我在拼接参考内容时会顺手把每条切片的相似度得分也传给模型让模型在低分切片面前保持警惕。指令里会加一句“若参考资料与问题相关性不高请说明依据来源。”第三个坑每条历史记录都必须干净。RAG最怕用户之前在对话里吐过一口“毒奶”——比如聊到一半把某个数字说错了这个错数字混进上下文后续所有的检索结果都会带着错误的引导。所以对话历史入库之前要做一个简单的清洗和只保留“用户问题和最终回答”的预处理。5. Agent雏形让AI从“回答者”变成“执行者”5.1 什么是Agent以及它和普通对话的区别如果说RAG解决的是“AI不懂的怎么办”那Agent解决的是“AI不能做的怎么办”。大模型本身没有行为能力的它只能吐文字。但文字也可以变成指令模型通过输出一段特殊格式的内容就能触发一个外部动作。比如模型输出“调用天气查询API参数北京”程序解析到这行字后自动去调用天气接口。这个东西就是Agent的雏形你给模型装上了手和脚。从工程实现上看Agent并不神秘。核心就两步模型根据用户问题决定需要调用哪个工具。程序解析模型的“工具调用请求”执行对应函数把结果再喂回给模型。这就像一个公司里的文员领导让他订机票他先写出一张审批单交给行政去执行执行完再拿着结果回来向领导汇报。5.2 一个10分钟能跑通的工具调用Demo在项目里我实现了一个最简Agent只有一个功能在本地CSV文件里查指定商品的价格并计算折扣价。这个功能不需要联网也不需要额外API只需要让模型学会输出一段结构化指令。我让模型输出的不是自然语言而是标准JSON{ tool: query_price, params: { product_name: 某型号保温杯 } }程序收到这段JSON后进行两步操作第一步解析JSON识别工具名第二步调用对应的Python函数得到查询结果。模型看到查询结果后再生成最终回复。整个流程串起来之后用户端的体验就是我说“帮我查一下那个保温杯打折后的价格”AI先查了库再回答“原价159元限时8折折后127.2元”。关键代码思路如下def run_agent(question): # 第一步让模型决定调用哪个工具 decision llm.chat( userquestion, system判断是否需要查询数据库。如果需要输出包含tool和params的JSON如果不需要直接回答。 ) # 第二步解析JSON并执行 if tool in decision: result execute_tool(decision[tool], decision[params]) return llm.chat(userquestion, systemf工具返回结果如下请基于结果回答{result}) return decision粗看只有十几行代码但已经足够跑通“模型决策—函数执行—结果回填”这一整条Agent链路。5.3 Agent设计中最关键的系统消息写法做Agent时系统消息的重要性比普通问答场景高一个量级。因为你不仅要告诉模型“怎么回答问题”还要告诉它“什么时候该调用工具”“什么时候不该调用工具”。我给Agent写系统消息时有一个固定的规则块你有以下工具可用 1. query_price查询商品价格参数product_name。 使用工具的唯一条件是用户问题涉及价格、折扣、库存等数据库信息。 如果用户只是聊天、提问常识请直接回答不要调用工具。这里面有一个很关键的约束“使用工具的唯一条件”。如果不加这句话模型很可能在用户随便提一句“你好”的时候也去调用工具因为模型的默认倾向是“尽量表现得有用”。你给了它工具它就想用。加了这条约束之后问题基本解决。模型开始学会“区分意图”——哪些问题需要动工具哪些问题动嘴就行。这其实是Agent产品化过程中一个非常基础但必要的设计决策。5.4 Agent比普通问答多出的三个麻烦第一个麻烦错误传播被放大了。普通问答模型答错了后果止于一段文本。Agent答错了可能触发一次不该触发的工具调用比如查了错误商品、扣了不该扣的库存。所以我在调用工具前加了一个确认逻辑当工具参数置信度不高时向用户输出一个确认问题“你是在问某型号保温杯的价格吗”而不是直接执行。这个确认步骤拉低了自动化程度但大幅提升了安全性。第二个麻烦工具名称和参数容易混淆。模型容易把相似工具搞混特别是工具数量超过3个之后。我在项目里做了一次小实验工具从1个增加到4个时模型选错工具的比例明显上升。如果工具很多要给每个工具写清晰使用说明并在工具之间做明显的边界描述。第三个麻烦模型会试图“绕过”工具返回的结果去编造答案。比如工具返回“商品不存在”模型为了不让用户失望可能会自己编一个相近的价格出来。这种问题在测试阶段容易被忽略因为在开发环境里你往往预先知道正确答案。所以Agent的系统消息里要专门加一句“当工具返回结果为不存在时必须如实告知不得自行推测参数。”宁可多提示一点也不能让模型用幻觉去填肚子。6. 实战中的排查清单与优化记录6.1 我遇到过的四个高频问题这套系统跑了一个多月我遇到过的坑不算少挑几个最典型的记录在这里给后来者排雷。问题一模型输出不是合法JSON。原因通常是约束不够强。解决办法是冻结解码参数或加一步格式校验更稳妥的做法是用正则从纯文本里抽离出JSON片段而不是要求模型“只输出JSON”。问题二检索出来的相关内容看着相关但关键实体对不上。比如用户问“A型号手机保护壳”检索命中的却是“B型号手机保护壳”。原因是切块太短实体信息不完整。把切块长度调到300并引入20%重叠后明显改善。问题三长对话过程中系统逐渐“忘掉”最初指令。这种现象跟上下文窗口扩大有关开头角色指令被后续对话素材稀释了。我的处理办法是把系统消息重发一次并放在最新一轮用户问题之前。让关键指令保持在最近的位置时效性优先。问题四成本随调用量线性上涨。排查之后发现很多工具调用是“冗余”的。模型在不需要调用工具的时候也调了。调整系统消息之后工具调用数量下降近四成费用也跟着下来了。问题类型表现排查方向解决参考JSON解析失败工具调用无法执行模型输出混入解释文字用正则抽取或约束模型输出检索不精准答案答非所问切块策略不合理调整切块长度加入重叠指令漂移模型忘记原始约束系统指令被长对话稀释关键指令位置前移并重发冗余工具调用成本上升模型意图识别不准确限定调用条件并加示例6.2 两个我认为比较高级的调试技巧第一给每一步中间输出留一个调试开关。我在代码里加了一个DEBUG环境变量打开之后系统会在控制台打印每一个中间环节的结果用户原始问题、检索到的文本块、打分、拼好的上下文、模型原始输出。排查问题的时候这一步价值极高。很多人遇到的问题其实直接在“中间输出”环节就能发现根本不用拿到最终回答去猜。第二用一个固定“测试集”做回归验证。AI应用改了一次提示词经常是这个问题修好了另一些问题却变差了。所以我在项目里专门准备了一个包含30条不同难度问题的测试集每次调整完就批量跑一遍用输出对比来确认改动到底有没有改善整体效果。这个方法在普通开发里非常常规但在AI原生应用开发里很多人反而会偷懒跳过我建议大家不要省这几步。6.3 成本控制的基础经验跑AI应用很多人最大的心理落差不是效果不够好而是账单涨太快。作为业余项目我没法像大厂那样烧钱做实验所以摸索出一套省钱姿势。每次都带上结构化指令宁可用更长的系统提示词也别让模型用“试错式”的回答来理解你的需求。检索召回数量不要贪多。默认3条即可召回10条效果不提升百分之一成本却显著增加。能本地跑的环节绝不调云端API。嵌入模型、切块、相似度检索全部本地化处理只有最后的“理解与生成”才花钱调大模型。模型回答设置合理上限。输出端的token数量直接和成本挂钩而且经验证明多数任务100到300个输出token完全够用。7. 后续还可以延伸哪些方向这套系统做完之后我琢磨过一阵还能往哪里走。这里列几个我觉得有价值的方向后续可能单独开笔记聊。一个是把检索范围从纯文本扩展到多模态让图片、表格也参与检索。现在不少嵌入模型已经支持图文混合向量化做企业知识库的话这个扩展很有必要。另一个是把单一Agent升级成多Agent协作。比如让一个“编排者”模型负责拆解任务把“查价格”和“写推荐语”分别派给不同Agent去执行最后汇总。这个模式在复杂任务上表现会更好但调试复杂度也指数级上升不太适合新手一上来就碰。还有一个方向是把系统里的所有配置模板化做成一个可配置的控制台。这样非技术同学也能通过改配置文件来调整AI助手的性格、知识库和工具列表。目前这套东西的边界其实已经很清晰了真正把它做成一个能被别人使用的产品还需要花不少力气打磨。按照我个人的习惯这类笔记向来是以“踩坑记录”收尾的。这篇的最后我想分享一句这次实战里感触最深的话AI应用开发的瓶颈往往不是模型能力而是你对任务的理解深度。把一个问题拆得足够清晰AI就能表现得足够聪明如果你自己都搞不清楚想让模型做什么模型大概率会给你一个花团锦簇的废话。后面我计划把多Agent协作和图文检索这两个方向继续啃一遍如果跑出有价值的东西再来更新第三篇。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑