ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

提示工程实战指南:从上下文窗口到代码生成与自动优化

提示工程实战指南:从上下文窗口到代码生成与自动优化 简介《Goolge AI 提示工程指南中文版》是一份面向数据科学家、机器学习工程师、软件开发者及LLM使用者的技术文档系统讲解提示工程的基础概念与进阶技巧。内容从零样本、少样本、系统/角色/情境提示等基础方法延伸到思维链CoT、自我一致性、思维树ToT、ReAct、自动提示工程和代码提示并给出大量可落地的示例与最佳实践可帮助读者优化代码生成、文本摘要、信息提取、问答等场景的模型输出。资源为单个PDF文件约7.12MB便于离线查阅和随时对照练习文档强调提示的迭代调优提供了实用模板和调试建议适合希望提升提示设计与模型使用效率的技术人员系统学习。目前已有411人学习内容结构清晰从模型配置到高级策略覆盖完整是快速入门Google提示工程方法的一站式参考。1. 提示工程不是玄学这份中文指南到底帮你解决什么你有没有遇到过这种情况同一个大模型同事写的提示词能稳定输出可用代码你写的提示词让它满嘴跑火车。我第一次认真对待提示工程是拿 GPT-4 生成一段带鉴权的 Python 爬虫结果它一本正经地给我编了一个不存在的第三方库还附带了错误的使用文档。换成人这叫糊弄换成交互记录这叫提示词设计有问题。提示工程不是“会不会说话”它是一套可复用、可验证、可度量的输入设计方法。这份 Google AI 提示工程指南的中文版核心价值不是让你学会“哄模型”而是把大模型当成一个有输入输出约束的工程系统上下文窗口怎么分配、任务怎么拆解、输出格式怎么约束、失败怎么归因。它覆盖 Prompt 设计、代码生成、自动提示词优化等完整链路适合正在用 LLM 写业务代码、做 Agent 编排、或者天天和 JSON 输出打交道的从业者。往下读我会把这些方法拆成能直接抄作业的模板和参数配置。2. 上下文窗口视野下的提示词结构先把预算算清再动手写2.1 从 zero-shot 到 few-shot调优之前先决定提问策略提示词的第一个工程决策不是怎么措辞而是选哪种提问范式。zero-shot 就是直接问few-shot 就是先给几个输入输出样例再问。很多人一味堆样例以为“给得越多越好”其实每个样例都在消耗上下文窗口而上下文窗口的单位成本是真实存在的。在代码生成场景里上下文窗口被几千行示例吃掉后模型反而更容易把示例里的错误风格复刻出来。实操上我的习惯是先按任务复杂度和输出稳定性需求选一个初始范式。能做 zero-shot 就不上 few-shot能上 few-shot 就不上长指令。这不是省 token 那么简单——样例本身就是噪声源。比如你要让模型把一段 Python dict 转成 YAML给 2 个覆盖边界情况的样例效果远好于给 10 个结构大同小异的样例。下面这个对比规则我在团队里一直贴着用范式适用场景主要风险调优顺序zero-shot简单改写、格式转换、标准库代码生成输出格式漂移先改指令措辞再加格式约束few-shot复杂逻辑、风格模仿、边界情况多样例消耗窗口、错误复刻先删冗余样例再调样例顺序CoT 思维链数学推理、多步逻辑、代码调试输出冗长、幻觉伴随解释控制推理步数只保留关键中间结果选型之后再进入真正的内容设计。对于提问措辞我常用一个“角色 任务 约束 输出格式”的四段式结构让浮现稳定。角色是最容易被忽略的一层——同一段指令加上“你是资深 Python 工程师代码标准遵循 PEP 8”之后模型更倾向于写结构化代码。注意角色不能乱挂靠要和具体任务匹配不然模型会把知识库的风格权重拉偏。2.2 思维链输出让中间推导暴露出来而不是直接给结论代码调试是思维链性价比最高的场景。直接让模型解释“这段代码为什么报错”它往往会给出一个正确的反转写“因为有 bug”然后指出一个不相关的行。加上一句“先列出代码的执行路径再指出异常发生的可能位置”输出质量明显不一样。指南里给的核心建议是对于多步推理把“思考过程”设为显式输出而不是让模型默认输出最终答案。这里有个度的问题。日志、中间变量、条件分支判断这些关键步骤可以生成那些毫无信息量的“推理”要压掉。我在提示词里写 CoT 指令时一定附上输出格式约束把它变成半结构化的东西例如要求“推理内容放在reason标签内代码放在code标签内”。这是为了避免把思维链提示词写成一个无法解析的散文体输出后面拿到程序里没法用。陷阱是模型会为了展示完整的中间步骤而“补全”推理链生成一段没有实际根据的中间逻辑。遇到这种情况把温度参数拉低并且在提示词里加一句“只能使用输入中出现的变量和值做推导”。在自动评估时不要直接喂给 LLM 打分先做规则过滤——像未定义的变量名这种错误用静态检查一眼就能抓出来不用交给模型判断。2.3 结构化输出与 JSON Schema搞定格式比搞定内容更优先格式漂移是代码生成里最头疼的问题。模型往往能想明白逻辑但输出的 Markdown 代码块包了多余的反引号或者 JSON 里混入了注释。指南把这类问题单列为一条在提示词里显式约束输出格式而不是依赖模型“自觉”。我的做法是在提示词末尾固定追加一段格式约束要求只输出 JSON不输出解释并给出期望的 JSON 结构示例。下面是一个可以抄的模板{ refactored_code: 这里放重构后的完整代码使用 python 代码块不要用其他语言标注, changed_lines: [ {line: 12, change: 把魔法数字提取为常量} ], risk_points: [修改后的函数对空列表输入未做保护] }这段 JSON 示例放在提示词里有几个作用。一是约束了输出的顶层字段二是让模型知道代码放在哪个字段里三是在 field 层级给了填写示例——它就不太会跳出去写一套无关的散文。配合代码侧我会用 Python 的json包做二次校验解析失败就把原输出直接丢弃而不是硬解码。import json from typing import Any def parse_llm_json(raw: str) - dict[str, Any]: # 先剥离常见的代码块标记再尝试解析 cleaned raw.strip() if cleaned.startswith(): cleaned cleaned.split(\n, 1)[1] cleaned cleaned.rsplit(, 1)[0] try: data json.loads(cleaned) except json.JSONDecodeError as e: # 保留原始内容方便排查模型哪些字段污染了格式 raise ValueError(fLLM 输出不是合法 JSON: {e}\n原始内容: {raw[:200]}) from e if refactored_code not in data: raise KeyError(缺少 refactored_code 字段请检查提示词里的 JSON 示例是否被截断) return data这段代码的逻辑很直接先剥掉可能的 Markdown 代码块包裹再做 JSON 解析最后校验必填字段。注意rsplit(, 1)是倒着切避免正文里出现反引号时切错位置。很多人在第一步就翻车是因为直接从原始字符串json.loads遇到模型输出json关键字就会被卡住。参数层面如果模型频繁漏字段不要急着改温度先看是不是提示词里示例结构太复杂——复杂嵌套 JSON 漏字段的概率远高于扁平结构。3. 代码生成场景的落地实战把提示词当接口来调试3.1 固化一套代码生成模板降低每次对话的不确定性代码生成任务和闲聊的区别在于闲聊可以容忍随机代码不可以。同一个提示词在温度 0.7 下可能输出优雅的实现也可能输出一个except: pass。为了稳定复现我会把代码生成的提示词写成一个工程模板所有变量集中在开头的大括号里业务描述一旦定型就不再改动。code_gen_template 你是资深 Python 工程师代码风格遵循 PEP 8使用 Python 3.10 特性。 任务: {task_description} 约束: - 不依赖第三方库 - 标准库优先 - 输出必须包含完整 import不要省略 - 对边界输入空列表、None做防御性处理 请把代码和变更说明放在 JSON 里 {{code: 完整代码, imports: [模块名], edge_cases: [已处理的情况]}} 这个模板的特点是把“约束清单”放在任务之后、输出格式之前。模型是按顺序读提示词的越靠后的指令在生成时权重越高所以输出格式约束放最后就是让它最后遵循格式。用大括号占位符是为了方便后续用.format()拼接不同的任务描述让我能把模板当函数调。注意约束里“完整 import 不要省略”是血泪教训——模型经常在上下文窗口快满的时候默认你“知道”了它省掉的 import结果代码一跑就是NameError。3.2 先要求测试用例再要求实现把 TDD 的套路还给提示词代码生成最隐蔽的问题是“实现与需求错位”。你让模型写一段 HTML 表格提取函数它写了一版但th标签只提取了第一个原因是你没说清楚多个表头的情况。更稳妥的策略是交换生成顺序让模型先输出测试用例再输出对应实现。这个顺序变化看起来不起眼但它强制模型把需求翻译成可验证的行为。tdd_prompt 请先为下面的任务编写 pytest 测试用例再编写实现代码。 任务: {task} 要求: 1. 测试用例覆盖 正常输入、空输入、重复数据、类型异常 四类场景 2. 测试用例写在 test_xxx.py 代码块 3. 实现代码写在 impl_xxx.py 代码块 4. 测试中使用 assert 而非 print 只输出两类代码块不要输出解释文字。 测试用例先行本质上是把需求验证的职责下沉到模型侧。如果模型自己都写不出合格的测试用例那它的实现八成也不可靠。我在实操中会把第一轮输出的测试用例直接丢进 pytest 跑失败信息反馈给第二轮生成而不是对着生成结果干瞪眼。这个循环跑两次生成的代码质量会有明显上升因为模型看到失败反馈后会改写实现而不是在原有幻觉代码上打补丁。3.3 提示词之外的硬校验模型输出不要直接进主干把模型输出当成“候选提交”而不是“最终代码”这是代码生成落地时最重要的一条工程习惯。我用一个固定流程LLM 生成 → 格式化工具统一风格 → 静态检查 → 单测。模型写出的代码风格往往是混合的black格式化后至少能消掉无意义的空行和引号差异然后ruff抓未使用变量和语法问题最后跑单测。black --line-length 88 generated.py ruff check generated.py --select E9,F63,F7,F82 pytest test_generated.py -q这三个命令按顺序执行每一个都可能在模型代码上翻车。ruff的E9和F63是语法错误和索引问题属于硬伤模型代码里出现频率不低F82是未定义变量撞上就说明提示词里的“完整 import 不要省略”没被遵守要去改模板而不是改代码。black负责格式统一。做这些事的意义在于即使提示词写得不好硬校验也能兜住大部分低级问题让我有底气把生成代码放进项目仓库。4. 自动提示工程让模型自己迭代出更优提示词4.1 原理把提示词当作可优化的对象在提示词工程里有一个被低估的思路——把提示词本身当作需要被优化的参数而不是人类手工设计的文案。Google 的自动提示工程研究里核心观点是模型既能按照提示词完成任务也能生成新的提示词。这两件事可以递归让一个提词器模型生成多个候选提示词在验证集上跑分保留得分高者迭代下去。这种思路对参数调优很有用尤其在工程批次开发中。这意味着你不需要理解每个任务的语义细节只需要定好验证指标剩下的交给模型。它本质上是一种穷举 评估的搜索策略只是“搜索方向”由模型的语言知识提供。但这也带来一个硬边界自动提示工程能否收敛取决于评价指标是否可量化。如果任务本身是模糊的“写得更好一点”那它只会产出同样模糊的提示词。4.2 最小可复现的自动提示词迭代脚本自动提示词工程不是必须搭一套重型框架才能跑。下面是一个最小脚本适合在本地做实验验证import json import random from typing import Callable # 任务集每个样本包含输入输出是提示词的试金石 task_set [ {input: if x 3 else y, expected: condition}, {input: return a b, expected: operation}, ] # 这个函数是评估器给提示词和输入返回模型输出得分 def score_prompt(prompt: str, get_llm_output: Callable[[str], str]) - float: score 0.0 for sample in task_set: output get_llm_output(prompt \n sample[input]) # 用规则匹配关键词相等加 1 分越高代表提示词越稳定 score 1.0 if sample[expected] in output else 0.0 return score / len(task_set) # 迭代入口生成初始提示词循环优化 def auto_prompt(initial_prompt: str, iters: int 3): best_prompt, best_score initial_prompt, 0.0 for i in range(iters): # 用一个候选生成器模拟多提示词探索 candidates [ initial_prompt f (优化版{i}: 简洁措辞), initial_prompt (强调输出只含关键词), initial_prompt (保留原始措辞), ] for c in candidates: s score_prompt(c, lambda x: condition if in x else operation) if s best_score: best_prompt, best_score c, s return best_prompt, best_score这个脚本的核心是score_prompt里放一个规则化的评估器而不是交给 LLM 打主观分。候选生成部分我用了一个简单的列表推导实际项目中可以用模型批量生成新提示词。脚本有几个参数值得注意task_set决定了评估方向任务样本没有代表性整个迭代都会失真iters是迭代轮数不是越多越好——模型生成的候选提示词如果越长越复杂得分不升反降。最初一轮跑完我会打印每一轮的得分变化看它是否真的在收敛如果两轮得分都在原地晃说明评估器区分度不够先换任务集而不是继续加迭代轮数。4.3 自动迭代的边界什么时候该停下来自动提示工程不是银弹。它最适用的场景是输出可以被规则严格判定的任务比如“命名实体是否被识别出来”“是否包含指定关键词字段”不适用的是主观审美、内容创作、需要综合判断的任务。另外迭代过程中提示词往往会“过拟合”——它在你的小任务集上分很高换一个场景就退化。应对办法是留 20% 的任务样本不参与迭代只在最优候选上验证一次。我遇到过最典型的翻车是模型给某个提示词加了限制“只处理单数可数名词”标定集里分数上涨推广到真实数据后复数形式全部被过滤效果直线下滑。从那以后我在自动迭代跑完后一定手动看几遍最终提示词确认它没有包含某些“看运气加进去”的偏见性字眼。自动提示工程是在帮你提速搜索不是替你判断什么是对的语言。5. 避坑与排查提示词翻车的五个高频教训5.1 指令被模型“吸收”进答案现象提示词里写了“不要输出解释直接给代码”结果模型把整段“解释性文字”当作处理对象在输出里附带了一串关于这段指令的说明。原因指令和上下文没有区隔模型无法判定哪些文本是待处理数据哪些是元指令。解决用 XML 标签把指令和输入内容隔开。格式类似instruction只输出代码/instructioncontent.../content让模型明确“需要处理的文本”边界。5.2 温度拉高后代码输出飘了现象同样的提示词温度 0.7 时输出一版带额外装饰的代码0.2 时输出却是另一套结果没有统一规范。原因温度控制随机性但模型在代码生成时候的“随机采样”并不总是产生合理变化它会转向另一种风格。解决代码生成场景把温度固定到 0.2 以下top_p同步调到 0.9 或更小。需要多样性探索时去改提示词里的约束和样例别用温度冒险。5.3 CoT 反而让结果更差现象加了“请一步步思考”之后模型开始输出冗长的推理链结果里出现编造的执行路径和中间变量。原因代码生成和数学推理不同中间推导过程在无噪声环境里才有效模型强行“补全”推导反而引入了幻觉。解决只有在任务本身涉及多步逻辑判断时才启用 CoT并且限制推理步骤数量“最多列出三个中间步骤”。代码生成的单步任务直接用结构化输出。5.4 “不要输出解释”被无视现象提示词明显写了“不要输出任何解释”输出还是有大段开头语。原因模型对否定指令的遵循度天然低于肯定指令。“不要 X”这种表达在生成时往往先触发 X 相关的语义激活。解决改成肯定表达“直接输出 code 字段内容为 JSON”。如果不生效把输出格式的示例放进去模型会优先模仿示例结构而不是听一句抽象的“不要”。5.5 自动评估时模型给自己的提示词打高分现象用 LLM 给候选提示词打分时长得更像“人类总结”的措辞普遍拿高分和真实业务表现对不上。原因LLM 评估器自带文本风格偏好对流畅、完整的提示词有天然好感它不是在打分它是在“品味”。解决评估器优先用规则、正则、测试用例通过率等硬指标。只有结果无法规则化时候才用 LLM 打分并且同时提供正反两面的判断锚点比如“输出是否包含指定字段”“是否出现代码块标记”。6. 提示词质量怎么验证回归集与 A/B 切换保住下限6.1 先建一个最小可用的提示词回归集改提示词就像改代码没有回归测试就是裸奔。我在接手项目的第一个星期就会建一个十条左右的回归集覆盖三类用例正常业务输入、边界输入、历史翻车案例。每次调整系统提示词、修改模板、切换模型版本都先跑一遍回归集记录每条用例的通过率。哪怕这十条不够全面也足够帮我拦住“这次改动让之前的修复失效”的情况。6.2 用自动化得分做前后对比不靠感觉回归集建好后用脚本记录新旧提示词在同一批输入上的输出差异。核心指标是字段完整性、格式合法性、关键词覆盖率有测试用例的场景直接看测试通过率。AI Agent 场景里我还会加一条“工具调用参数是否合法”的检查因为 Agent 编排时提示词一改很容易让模型忘记输出正确的 tool call JSON。对比时一定要控制温度为固定值否则你分不清分数差异是来自随机采样还是来自提示词本身。每次拿到新的提示词我先跑一个多点温度下的输出对比例如温度 0.1 跑两次如果两次输出差异巨大说明提示词结构不够稳先别上线回去加固格式约束。从那以后每次改提示词我都强制自己走一遍这个流程——先跑回归集、再看结构化字段损坏情况、最后才看输出分数。模型能力是上限提示词和验证流程才是守住这个下限的工程手段。这份 Google AI 提示工程指南中文版作为参考资料的价值正在于此它不教你把模型当聊天对象而是教你把它当作一个行为可预测的系统。希望帮到你。本文还有配套的精品资源点击获取
返回列表