ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

提示工程不是玄学:从少样本到思维链的稳定输出实践指南

2026/9/25 23:32:55 拓冰建站 浏览量
提示工程不是玄学:从少样本到思维链的稳定输出实践指南 简介面向数据科学家、机器学习工程师及应用开发者的《Google AI 提示工程指南中文版》PDF 正式分享。文档以大型语言模型为对象系统讲解提示工程核心概念与工作流首先介绍温度、Top-K、Top-P 等输出配置如何影响生成质量随后从零样本、少样本、系统提示等基础技巧讲起逐步深入到退步提示、思维链CoT、自我一致性、思维树ToT、ReAct 等高级策略并针对代码生成、代码调试、文本摘要、信息提取等任务给出可直接参考的提示模板与最佳实践。同时涉及多模态提示与自动提示工程前沿方向强调通过记录、试验和配置调整不断迭代优化提示。资源为 1 个 PDF 文档大小 7.12MB内容结构完整、示例丰富适合个人自学或团队内部分享。目前已有 409 人学习下载对于希望进一步提升 LLM 输出可控性和准确性的技术人员具有明显参考价值。1. 别再说提示工程是玄学先把手头这份指南读完提示工程这几年被说得越来越玄好像谁能写出一句“咒语”谁就能让大模型干出奇迹。但等你实际把大型语言模型接进业务系统、做代码生成、跑自动化测试就会发现真正决定效果上限的不是某一句神奇话术而是你对“模型怎么读提示”这件事的理解深度。我最近重新拆了手头这份《Google AI 提示工程指南中文版》它把零样本提示、少样本提示、思维链、温度参数、自动提示优化这些概念整理成了一条完整的决策链路。适合两类人刚接触大模型应用开发、想避开直觉坑的新手以及已经被结果方差折磨了一阵子、想建立稳定输出流程的工程师。这份PDF不是教你怎么把话说得更漂亮而是教你怎么把“和模型沟通”变成一件可设计、可验证、可回滚的事。读完之后你会回来承认之前的翻车多数不是模型的锅是提示的设计有问题。2. 提示不是玄学四个底层概念决定你与模型的对话质量2.1 模型读提示靠的是条件概率不是“理解”很多人在翻车之后的第一反应是“模型太笨了”但实际上大语言模型处理提示的方式和你理解“人话”的方式完全不同。它拿到你的整段文本后先做分词把文字切成token序列然后基于当前已有的token逐步预测下一个token的概率分布。你写进提示的每个词、每个标点、每个示例都会影响这个分布的走向。这也是为什么同样的需求措辞换一下就得到完全不同的结果。理解了这一点“提示工程”就不再是话术包装而是上下文设计你写下的每一句话都是在为模型指定“回答问题的先验条件”。你在提示里塞入的背景、约束、示例越多模型的生成路径就越被收窄输出就越接近你想要的形态。常见做法里一个高质量的提示词往往比问题本身长得太多原因就在这里。2.2 少样本提示Few-shot三个好示例比一百字规则更管用指南里反复出现的一个观点是与其用抽象的自然语言描述规则不如给模型直接看几个“输入-输出”对的示例。少样本提示的核心原理是模型能从示例对中推断出你的期望格式和推理方式这比让它理解“请严格按照以下格式输出”要可靠得多。我的一般做法是每个任务准备3到5个示例示例要覆盖边界情况而不是只放最简单的正常情况。例如做意图分类两个示例分别是买机票和退票第三个示例就放一个模糊表达“航班能改吗”。这个模糊示例几乎起决定性作用它告诉模型“遇到边界时要倾向于给出某种处理方式”。示例放得太多反而会稀释注意力尤其是当示例之间风格不一致时模型学到的是“混乱”而不是“规则”。任务对用户输入做意图分类只输出以下三类BOOKING、CANCEL、CHANGE。 示例1 输入帮我订一张明天从北京去上海的机票 输出BOOKING 示例2 输入这张机票我不想要了能退吗 输出CANCEL 示例3 输入航班时间能往后改两天吗 输出CHANGE 示例4边界 输入票已经出了还能改吗 输出CHANGE 用户输入帮我看看我那张票还能不能换时间 输出这个模板里示例4特意用了“还能改吗”这种接近取消语义的问法但正确定义是改签于是模型必须区分“退”和“改”。这种边界示例比任何一句“请区分取消和修改”都更有效因为它直接给出了模型在语义模糊时该怎么抉择的信号。2.3 思维链CoT让模型把推理过程摊开给你看少样本解决的是“格式和风格”思维链解决的是“推理深度”。对于数学计算、逻辑判断、代码调试这类需要多步推导的任务直接问一句“这段代码为什么报错”得到的结果往往很浅。但如果让模型把中间推理步骤写出来准确率会有明显提升这就是思维链提示。原因在于生成中间步骤相当于把推理结果也当作上下文的一部分模型每写一步下一步的条件概率就多了一重信息约束于是后续生成更不容易跑偏。指南里给出的常用写法是“先逐步分析再给出最终结论”这在逻辑类任务上效果显著。我的落地习惯是要求模型把分析步骤控制在3步以内并且明确让最终结论放在最后一行方便程序解析结果。使用思维链也有代价输出变长token消耗增加且模型有可能在中间步骤里“编出一套自洽但错误”的解释。所以后面第5章我会专门说什么时候不该用思维链。2.4 温度和Top-p改两个参数往往比重写提示更划算提示工程最容易忽略的一步是采样参数。同一个提示词在温度temperature等于0.2时是稳定输出在0.8时可能彻底放飞自我。指南里把温度定义成“生成随机性的控制旋钮”数值越低概率分布越集中在最可能的token上输出更稳定数值越高低概率token被选中的机会越大文本更多样幻觉也更容易出现。温度范围适用场景常见副作用0 ~ 0.3代码生成、SQL生成、数据抽取、配置生成输出偏机械灵性不足但稳定0.4 ~ 0.7文案总结、邮件起草、内容改写质量与随机性平衡较好0.8 ~ 1.0头脑风暴、创意发散、故事生成幻觉明显增多格式容易跑偏Top-p核采样是另一个约束旋钮它表示“只从累计概率达到该阈值的token里抽样”。常见做法是把温度设置为0.2左右、Top-p设置为0.8而不是两个参数同时调大否则你的输出会随机到没法看。参数调整顺序上我通常先固定温度再微调Top-p最后才考虑重写提示词。很多情况是提示词没问题纯粹是采样参数设得太激进。3. 把提示词拆成六个要素从“会说话”到“会写Prompt”3.1 六要素模板角色、任务、上下文、示例、约束、格式提示词写不好的一大原因是结构不完整。多数人写提示只有一个句子“帮我写个登录接口。”这种提示给模型的上下文太少输出必然发散。把PDF里的方法论落地我一般会把提示词拆成六个要素角色、任务、上下文、示例、约束、输出格式。这六个要素不一定要全部出现但缺任何一个都可能引发对应问题。角色你是一名有十年经验的Java后端工程师。 任务根据下面的需求生成一个Spring Boot的登录接口。 上下文项目使用Spring Security JWT数据库是MySQL用户表叫sys_user。 约束只用标准库和Spring生态组件密码使用BCrypt加密不校验验证码。 输出格式给出完整的Controller与Service代码注释要写中文不要写测试代码。 需求支持用户名和密码登录登录成功返回token。这个模板的关键在于“约束”那一行。它限定了依赖范围、加密方式和需要忽略的点模型就不会自作聪明去引入一套Redis验证码逻辑。输出格式里写“不要写测试代码”能直接省掉一段冗长无用的信息。我给这个结构起名叫“框架优先写法”角色定立场约束定边界格式定出口。3.2 代码生成把“目的事先写进代码”比单独说明更稳代码生成时模型对注释的敏感度远超对额外指令的敏感度。同样的需求写在提示词末尾和写在代码注释里命中率完全不同。原因是注释紧挨着代码上下文模型生成下一个token时更容易把注释内容当作局部条件来参考。这是我在实际使用中回报率最高的一个技巧。# 目标文件UserController.java - 接口路径POST /api/user/login - 接收参数username, password - 校验失败统一返回 401 和错误码 LOGIN_FAILED - 成功时返回 jwt tokentoken 有效期 24 小时 # 请基于上面的注释生成完整的 Spring Boot Controller 方法体注意注释写法路径、参数、异常约定、有效期各占一行单一且明确。然后用“请基于上面的注释生成代码”这句话收尾。我不想在这里展示“完整结果”因为不同模型的生成结果各有差异想强调的是这个结构的稳定之处在于把需求放在了“天然应该被参考”的位置而不是放在一段会被模型忽略掉的对话尾巴里。如果你试过把需求写在一长段提示的最后结果代码里缺东少西不妨改成这种注释先行结构。3.3 让模型学会自纠错两轮对话加一次强制复查大模型一次生成的代码很少能直接跑通。与其反复重写整个提示不如在流程上增加一轮强制复查。常见做法是第一轮让模型正常生成代码第二轮把生成结果原样塞回给模型同时要求它扮演代码评审员指出问题并输出修正版本。原理很简单第二轮的输入包含了第一轮输出模型能够把第一轮结果当作分析对象而不是凭空猜你要什么。import os def generate_with_review(client, prompt, modelgpt-4o, temperature0.2): first client.chat.completions.create( modelmodel, messages[{role: user, content: prompt}], temperaturetemperature, ) code first.choices[0].message.content review_prompt ( 上面这段代码是上一步生成的。请扮演代码评审员 逐行检查空指针、边界处理和资源释放问题 如果发现问题给出修正后的完整代码 如果没有问题只回复 OK。\n\n f{code} ) second client.chat.completions.create( modelmodel, messages[{role: user, content: review_prompt}], temperature0.0, # 复查阶段必须锁死温度 ) return second.choices[0].message.content复查阶段的温度一定要设为0或接近0否则评审员自己也发散。这个两轮结构在我实际项目里把代码生成的一次通过率提高了不少代价是多一次API调用换来的却是更少的返工时间整体成本算下来还是划算的。4. 自动提示优化与评估让效果可测量而不是靠感觉4.1 从手动试错到自动搜索AutoPrompt与OPRO的底层逻辑人工调提示本质上是在一个巨大的组合空间里做手工搜索效率低且没有上限。指南里提到的自动提示工程方向是想把这件事变成算法问题把提示词当作搜索变量把验证集上的得分当作优化目标。AutoPrompt的核心思路是维护一个候选token池通过迭代替换提示中的某些词观察验证集损失的变化方向逐步找到更优组合。OPRO的思路则更进一步让大语言模型本身充当优化器由它“提议”下一步要尝试的新提示再用验证集评估打分。我在实际项目里的判断是这些方法的方向正确但多数团队用不上完整版。原因很简单自动搜索需要稳定的评估集和足够多的API调用次数一次实验消耗的成本不是小数目。更务实的做法是借用它们的核心思想手动维护候选提示池每次只改一个变量用一套固定测试用例快速打分。你不需要让算法替你搜索只需要让评估过程变得可重复。这就是提示工程区别于“话术比赛”的关键分水岭——有评估才叫工程没评估只能叫感觉。4.2 搭一个最小的提示评估脚本把回归测试引入提示迭代我整理了一份最小可用的评估骨架它把提示词从对话里抽出来变成独立文件再配合一组测试用例做回归验证。结构分三层prompts目录放提示模板test_cases.jsonl放测试用例evaluate_prompt.py负责跑分。# evaluate.sh遍历所有提示模板并输出得分 for p in prompts/*.txt; do echo 当前模板: $p python evaluate_prompt.py \ --prompt-file $p \ --test-set test_cases.jsonl \ --temperature 0.2 \ --num-runs 3 done# evaluate_prompt.py最小可用的提示回归评估骨架 import argparse import json def main(): parser argparse.ArgumentParser() parser.add_argument(--prompt-file, requiredTrue) parser.add_argument(--test-set, requiredTrue) parser.add_argument(--temperature, typefloat, default0.2) parser.add_argument(--num-runs, typeint, default3) args parser.parse_args() prompt open(args.prompt_file, encodingutf-8).read() test_cases [json.loads(line) for line in open(args.test_set, encodingutf-8)] total 0 passed 0 for case in test_cases: for _ in range(args.num_runs): response call_model(prompt \n\n case[input], temperatureargs.temperature) total 1 if eval_answer(response, case[expected]): passed 1 print(f{args.prompt_file}: {passed}/{total} 通过通过率 {passed / total:.2%}) def call_model(prompt, temperature): # 伪代码替换成你自己的模型接口比如 openai、qwen、本地 vLLM 服务 raise NotImplementedError(请在这里接入你的模型服务) def eval_answer(response, expected): # 最朴素的判定核心关键词是否都出现 return all(k in response for k in expected[keywords]) if __name__ __main__: main()这个脚本有几个参数直接决定评估质量--num-runs设为3是为了让随机性现形单次运行通过说明不了任何问题--temperature按场景固定代码类任务用0.2test_cases.jsonl每行一个测试用例input是触发提示expected.keywords是判定通过的关键词。判定逻辑是最朴素的关键词命中这在早期足够用。等用例集变丰富以后再逐步换成规则匹配、结构校验或LLM评审但骨架不需要变。记住一个原则评估指标的粒度宁可粗糙也不能没有。有了这套脚本你改提示词时会有底气得多。4.3 提示版本管理一份不后悔的命名规范提示迭代次数多了之后常见的痛点是“这个版本效果最好但我忘了是第几次改的”。提示词本质上和代码一样会演进但多数人的管理方式还停留在聊天记录里翻找。我现在的做法是把每个提示存成独立文件并按版本号命名。文件命名含义prompt_login_v01.txt登录场景第一版prompt_login_v02_fewshot.txt加入少样本示例版本prompt_login_v03_no_cot.txt去掉思维链的版本prompt_login_v03_verified.txt在测试集上验证过的版本版本号后缀里记录“改了什么”文件名里记录场景这样一个prompt目录就是一个可回滚的历史树。改坏一个版本时git revert就是后悔药。每次提示词改动都要跑一遍第4.2节的评估脚本记录得分后再决定是否保留。这个方法不复杂但能让你在反复试错中保住可复现的基线。5. 中文场景落地与避坑五个真实翻车点5.1 token消耗中文提示的隐形成本比想象中高中文提示词在绕圈子上有天然劣势。同样表达“请对以下代码进行解释”中文措辞往往比英文多出一截而不同模型的分词器对中文的处理差异也很大有的模型一个字几乎就占一个token。当提示词逐渐堆积到上千字时一次请求的token开销就会明显上涨尤其在批量跑评估脚本时费用是按token计数的一个提示词里冗余的客套话都会变成账单上的数字。我的做法是开工前先用tokenizer把提示模板测算一遍目标是让整段上下文控制在合理范围内。能塞进示例的就不要用重复描述能放到系统提示里的就不要每次请求都重复携带。提示工程做到后期优化目标不只是效果还包括成本。5.2 中文模型与英文模型的提示习惯差异同样的提示词模板换一个模型可能直接失效。这是中文场景落地时最常碰到的问题。从我的使用经验来看英文模型更吃“示例”给几个输入输出对就能稳定住格式而多数中文模型对“指令约束”式的显式说明更敏感你直接告诉它“不要输出解释直接给代码”比放一堆示例更管用。这背后的原因和训练数据的分布差异有关但工程师不需要深究只需要记住适配新模型时默认要重跑评估脚本而不是默认提示词通用。另外同一个模型的不同版本之间也可能存在差异指南里的建议与最新版本模型的效果未必一致。所以第4章的回归脚本不是一次性的它是每一次更换模型、升级版本时的必跑流程。5.3 代码注释用中文还是英文不同模型反应不同代码生成任务里注释是用中文还是英文影响的并不只是代码风格。英文模型对中文注释的敏感度偏低偶尔会把注释里的语境忽略掉生成一段和你意图不太相关的代码中文模型则相反中文注释对它有更强的引导作用。我一般会按模型阵营来选注释语言如果在GPT类英文模型上跑代码生成就用英文注释配英文约束如果在中文模型上跑就用中文注释并且在注释里少用指代词多用明确的动作描述。还有一个更隐蔽的坑注释里写“不校验验证码”有些模型反而会拼命生成验证码逻辑。原因是“校验”这个词触发了它的联想。解决方法是把注释改成正面向上的表达“只校验用户名和密码”而不是写一个带否定的句子。指令里的否定句经常被模型忽略这是提示工程里最常见也最让人头疼的现象。5.4 隐私与合规提示词本身就是数据处理过程把生产环境的真实代码、用户手机号、公司内部数据结构直接拼进提示词等于把这些数据发送给了第三方模型服务。这个风险在提示工程里被讨论得最少但后果最严重。我现在的处理习惯是所有进入提示的数据先在本地脱敏手机号变成占位符真实库表名改成别名非必要不给模型看完整业务上下文。更安全的组合是让提示模板与数据分离模板里写“用户名是占位符”运行时再把数据填进去。这样即使提示词模板被泄露也不会带出业务数据。这不只是流程规范是提示工程里一个很容易被忽略但必须守住的底线。5.5 避坑四个高频翻车点的现象、原因与解决翻车点一提示词写了一长串要求结果输出完全没按格式来。现象是约束写了三四行模型仍然自由发挥输出里混着解释、客套话还带markdown标题。原因是自然语言里同级别的指令会被模型当成弱约束它分不清“请尽可能”和“必须”的强制力差异。解决方案是把输出格式单独放一段用明确的“只输出以下格式……”句式并且在示例里直接给出你要的成品格式。示例本身就是最强的格式约束。翻车点二温度调到0.6生成代码变量名每次都不一样注释还带文学色彩。现象是同样需求跑两次代码风格完全不同甚至出现不存在的库。原因是代码生成根本不适合高温度采样随机性会让模型在token选择上偏离正常路径。解决方式是把代码生成类任务的温度压到0到0.3之间复查轮次直接设0。这是一个凡是做生成式代码的人都应该养成的习惯。翻车点三要求“请一步一步思考”结果模型输出了一长段自我辩解没有结论。现象是思维链提示词加上了模型却从头到尾都在解释自己的“思考”最后没有明确答案。原因是思维链不等于自由发挥它需要限定步骤数量和结论位置。解决方案是把提示改成“先列三个关键步骤然后给出唯一结论结论以‘最终答案’开头”。这既保留了推理质量又限定了输出结构后续解析也不会被中间的废话干扰。翻车点四改了提示词的一个词整体效果突然崩了。现象是上一版还能稳定输出的模板只换了个措辞就大面积出错。原因是提示词本身就是敏感的参数空间某些词的变化会改变token层面的概率分布而且这类影响几乎没有直观可解释性。这也是我觉得提示工程里最“玄学”的地方。解决方案是永远保留改动前的版本改动后立刻跑回归脚本一旦分数下降马上回滚。第4章的版本管理在这里就是救命用的。6. 把提示工程做成一条可回归的流水线最后一个救命的技巧前五章的内容如果拆开来用效果都会打折。真正让我从提示工程泥潭里走出来的是把它们串成一条固定流水线提示模板放在目录里管理每次改动都跑同样的回归脚本所有实验结果留痕。这套流程你不需要完整复刻只需要抓住一个核心动作——给每次提示改动留后悔药。具体落地可以很简单。我有一个prompts/目录里面每个文件就是一个提示模板文件名带场景和版本。我还有一个test_cases.jsonl文件里面长期维护着几十条固定用例覆盖正常输入、边界输入、错误输入。只要我改了任何提示词不管改多小都强制跑一遍评估把通过率记录下来。这个习惯最开始只是为了防止自己改坏提示但坚持一段时间以后它变成了我优化提示的数据库哪个版本在什么场景下效果好全部有数据支撑不再靠“我记得”。# run_regression.sh先备份、再评估、再记录 cp prompts/login.txt prompts/login.bak.$(date %s).txt bash evaluate.sh | tee regression_result_$(date %s).csv就这两行足够让一次提示改动从“不可回溯”变成“随时可回滚”。尤其是当你同时在多个模型之间切换、或者某个模型深夜悄悄更新了版本导致提示词集体失效时这套流水线能让你在十分钟内定位是提示的问题还是模型的问题。从那以后我每次改提示都强制走一遍回归脚本哪怕只改了一个标点因为我知道一个标点也能让模型的输出方向彻底跑偏。希望这个习惯也能帮到你。本文还有配套的精品资源点击获取