Skip to content

第 3 章 提示词起步与最佳实践原则 ​

第一次写 Prompt 的经历大多相似,敲下一行字,收获一堆陈词滥调。问题多半不在模型,而在于把编程错当成了聊天。这一章就来完成这个认知纠偏,先做从聊天思维到工程思维的切换,立起清晰度原则,再走进摘要、翻译、改写三个看似简单的实战场景,最后把方法论收拢成六条黄金法则。读完这一章,写 Prompt 时手里有原则可依,出了问题也知道从哪里查起。

3.1 Hello World 的陷阱与误区 ​

这就开始。很多人都有过这种经历,满怀期待地打开 ChatGPT、Claude,或者豆包、通义千问的输入框,敲下一行字:“帮我写个文案,关于咖啡的。”

然后盯着屏幕,看着光标一闪一闪。几秒钟后,屏幕上吐出来一段充满了“浓郁香气”、“唤醒清晨”、“生活格调”这种陈词滥调的废话。读了两遍,无名火就上来了,忍不住骂一句:“这 AI 也不行啊,写得跟小学生作文似的。”

其实这真不赖模型,赖提问的方式。

多数人第一次接触大语言模型(LLM)时,都犯了一个致命错误,把它当成了人。跟同事说“麻烦帮我看下这个”,跟朋友说“随便吃点啥”,这是人的社交习惯,模糊在这里是礼貌,给对方留出余地。但在工程里,模糊会直接造成 Bug,甚至让人半夜爬起来修数据。

这就是最典型的误区,自然语言交互的幻觉。

虽然用的是自然语言(Natural Language)去控制模型,看起来像在聊天,但本质上这是在编程。编译器从 GCC 换成了 GPT-4,编程语言从 C++ 换成了英语或中文。输入“Hello World”级别的提示词时,模型内部做的是一次概率计算。

给的约束越少,模型可选择的续写方向就越多,概率分布就越平坦。只说“写个咖啡文案”,模型面对的未知就有一串:“这人是要卖速溶咖啡?还是精品手冲?是发朋友圈?还是印在广告牌上?”它不知道,也没法问。于是,它只能选一条最“安全”、概率最高的路径,也就是讲废话。因为废话永远不会错,但也永远没用。

交互体验像在跟人聊天,但对面是一台拥有全人类知识却没有任何常识的机器。它没有直觉,只有对下一个字出现概率的计算。

所以,礼貌可以收起来了。不要说“能不能请你...”,不要说“也许可以...”,更不要说“我觉得...”。在提示工程里,客气话就是噪音,每一个多余的“请”字、每一个毫无意义的感叹词,都在消耗宝贵的 Token,都在稀释核心指令的权重。

要做的,是从聊天切换到下指令,写 Prompt 时每一个字都有明确目的。这跟日常说话的习惯相反,但习惯了这种写法,模型就会按照指令稳定输出,效果是实实在在的。

3.2 从闲聊切换到工程思维 ​

很多初学者卡在瓶颈期,怎么写 Prompt 效果都不稳定,核心原因就是没分清 对话(Chat) 和 指令(Task) 的区别。这不仅仅是应用场景的不同,更是两种完全背道而驰的思维模式。

拆开看。把 LLM 当聊天机器人用时,追求的是“有来有回”,容错率极高,它说错一句纠正一下就行,甚至觉得它“蠢萌”,截图发朋友圈大家乐呵乐呵。但在企业级系统里,Prompt 系统要的是确定性。

设想一个场景,某电商后台要开发一个自动提取用户评论情感的脚本,老板要求把每天几万条评论分类成“正面”、“负面”和“中性”,然后存进数据库。

如果 Prompt 写得像是在聊天:“嘿,读一下这条评论,告诉我用户开不开心”,那就等着半夜接到运维电话吧。因为模型可能会回答“用户看起来挺开心的”,也可能回答“这是一个正面评价”,甚至可能心情好发个笑脸符号 :)。

这时代码解析就断了。Python 脚本里写的是 if result == "Positive",模型回一句 Sure, the user seems happy!,程序直接抛出异常,数据流中断,当天的报表就是空的。

这就是“闲聊思维”带来的恶果。

工程化的 Prompt 设计,要求把自然语言“结构化”,把原本发散的对话强行收敛成一个封闭的函数调用。Prompt 就是一个函数 f(x),输入是用户的原始需求,输出必须是可预测、可解析,甚至可执行的结果。

这中间的差距,要用技术手段补上。不能抱着跟模型“商量”的心态,得换成严谨的语言风格。

比如,同样是电商评论分析任务,工程师思维的 Prompt 应该是这样的:

“你是一个情感分析引擎。你的任务是分析输入文本的情感倾向。你只能输出以下三个单词之一:‘POSITIVE’、‘NEGATIVE’、‘NEUTRAL’。严禁输出任何其他文字、标点或解释。如果无法判断,输出 ‘NEUTRAL’。输入文本:[这里是用户的评论]”

与其说这是在聊天,不如说是在下指令。这里定义了角色(引擎),定义了任务(分析),定义了输出空间(三个单词),甚至定义了异常处理(无法判断的情况)。

这种思维切换对很多非计算机背景的人是痛苦的,因为人习惯了语言的模糊美,习惯了“只可意会不可言传”。但在 Prompt Engineering 里,不可言传就是不可执行。意图要拆成一条条明确的要求摆在模型面前,不给它任何误解的空间。

这种切换还带来一个更有意思的视角,把模型当成一个不可靠的组件。

在传统的软件工程里,调用的函数通常是确定的,1 + 1 永远等于 2。但 LLM 是一个概率模型,1 + 1 在它那里有 99.9% 的概率等于 2,还有 0.1% 的概率它会回答“等于王二麻子”,或者讲一个关于数学的历史故事。

所以写 Prompt,其实是在做“概率工程”,通过各种约束条件,把正确答案的概率从 80% 提升到 95%,再提升到 99%,剩下的 1% 用代码逻辑兜底。这才是工程视角的真相,不是在寻找一条完美的提示词,而是在构建一个鲁棒的系统来应对这种不确定性。

3.3 清晰就是消除歧义 ​

既然要严谨,那核心就是清晰(Clarity)。这两个字说起来容易,做起来不容易。

人类语言天生就是充满歧义的,这是语言的特性,也是诗歌和幽默的来源。但在和 AI 交互时,歧义会直接造成错误输出。举个经典的例子,跟模型说:“把这个句子改短一点。”

这是一个典型的糟糕指令。什么叫“短”?

在模型那里,“短”这个词对应着无数种可能的解读。是字数减少?是意思精简?是把长句拆成短句?还是把复杂的词换成简单的词?甚至,它可能会理解成“把字体调小一点”(虽然它做不到,但它可能会试图描述这种变化)。

不明确给出定义,模型就会随机选一种做法,这次删掉形容词,下次直接砍掉半句话。结果忽好忽坏,还让人纳闷模型怎么时好时坏,其实是话没说清楚。

要消除这种歧义,就得把形容词换成数量词,把抽象概念变成具体约束。

别说“改短一点”,要说“将文本缩减至 50 个字以内,保留核心的主谓宾结构,删除所有修饰性的形容词和副词”。

这就叫清晰,没有“一点”、“大概”、“稍微”这种模糊的字眼。50 个字是量化指标,主谓宾是结构要求,删除形容词是操作指南。模型看到这个 Prompt,不需要再猜“短”的标准是什么,直接执行就行。

这里有个技巧,叫“杠精测试”。写完 Prompt 自己读一遍,专挑最不利的理解去曲解它。

比如写“不要输出无关信息”,杠精会问:“什么是无关信息?打招呼算不算?解释原因算不算?换行符算不算?”只要能找到一种曲解的方式,模型大概率也会找到同一条路。

来看一个经典的客服机器人翻车案例。

假设在开发一个自动回复差评的客服 Bot,Prompt 写的是:“请礼貌地回答用户的问题,安抚用户情绪。”

听起来没毛病。但如果用户发来一句:“你们的产品真是垃圾,退款!”

模型为了“礼貌”和“安抚”,很有可能会顺着用户的话说:“尊敬的先生/女士,您好!听到您这么说我感到非常遗憾,我们的产品确实可能存在不足,正如您所说的垃圾一样,我们深表歉意...”

结果呢,模型确实很“礼貌”,甚至礼貌地承认了自己是垃圾。这就是“礼貌”这个词的歧义,在模型的理解里,顺从也算礼貌的一种。

为了避免这种公关事故,得把 Prompt 改成:“你是一个专业的客服代表。面对用户的辱骂或负面评价,保持不卑不亢的态度,不要顺着用户的侮辱性词汇进行回复,而是专注于解决具体的售后问题。使用敬语,但不要过度谦卑。”

这一改,效果立马就不一样了。

所以,清晰度原则的核心不在于说了什么,而在于排除了什么。好的 Prompt 会把所有可能导致误解的说法逐一排除掉。这需要对词汇敏感,对每一个动词反复推敲,用“总结”还是“提取”,用“分析”还是“推断”。

在 LLM 的高维向量空间里,“总结”和“提取”这两个词的向量距离可能很远。 “总结”意味着模型可以重新组织语言,可以加入自己的理解,甚至可以遗漏细节。 “提取”则意味着必须忠实于原文,把信息原样拿出来,不能有丝毫的篡改。

要从合同里拿付款金额,用“总结”,模型可能会回答“合同约定了付款事宜”;用“提取”,它才会给出“100,000 元”。一词之差,结果完全不同。这就是清晰度原则的功夫所在,也是提示工程师的核心功力。

3.4 简单任务并不简单 ​

光说不练没用。理论讲得再多,一上手还是会遇到问题。拿几个最基础的任务,摘要、翻译、改写,来看看它们看着简单、实际处处是坑的一面。这些任务在很多教程里都是一笔带过的,但在实际工程中,每一个都有不少坑。

场景一:摘要(Summarization) ​

设想在为一家互联网公司公关团队开发一个“舆情晨报”系统,任务是把每天成千上万条社交媒体帖子和新闻报道扔给模型,让它生成简报。

最初的 Prompt 可能就一句:“总结这条新闻。”

这时候模型不知道该往哪个方向写:“这人是谁?他想看什么?是给官方微博小编看的素材汇总?还是给公关总监看的舆情简报?是侧重用户投诉?还是侧重媒体风向?”

结果就是,模型一会儿写成流水账,一会儿又漏掉关键的负面投诉,甚至有时候会把网友的吃瓜玩梗当成重点。拿这样的简报给公关总监看,是要出事故的。

问题的根源在于,没告诉模型“视角”。摘要不是压缩,摘要是基于特定视角的筛选。

把 Prompt 改成这样: “你是一名互联网公司的资深公关专员,正在为公关总监撰写舆情晨报。请从以下文本中提取关键的舆情信号(产品负面反馈、用户投诉热点、媒体质疑点),并以列表形式呈现。忽略所有情绪化的网络玩梗和毫无信息量的跟风吐槽。如果文中未提及具体风险,请直接标注‘无风险点’。不要发表你自己的看法,只陈述事实。”

效果立竿见影。模型不再把材料写成故事,而是按指令逐条提取信息。

这一步把“摘要”这个原本模糊的动作拆成了五个明确的部分,分别是角色设定(公关专员)、目标受众(公关总监)、信息提取(舆情信号)、格式限定(列表)以及异常处理(无风险点)。这样得到的摘要才是可用的工业级产品,而不是一篇读后感。

场景二:翻译(Translation) ​

很多人觉得翻译最简单,直接 Translate A to B 不就完了?大错特错。翻译的本质是文化重构。

让它把一句中文的“意思意思”翻译成英文,它可能回一个 meaning meaning;或者把“他走了”(去世)翻译成 He walked away,这在严肃的讣告里就是重大事故。

工程实践中处理翻译任务,最头疼的不是词汇,而是风格(Style)和语境(Context)。

假设正在做一款硬核科幻游戏的本地化。原文是“Jack in!”。如果只说“翻译成中文”,模型可能会译成“杰克在里面!”或者“插进去!”,完全不能用。

必须引入背景上下文,Prompt 得这么写: “你正在翻译一款赛博朋克风格的科幻游戏台词。原文充满了黑客术语和街头俚语。‘Jack in’ 在这里指的是通过神经接口连接到网络空间。请将以下文本翻译成中文,保持冷峻、科技感强的风格,多使用双字词,避免使用正式的书面语。参考译法:‘接入’、‘潜入’、‘连线’。”

这就不只是语言转换,而是在做“风格迁移”。不告诉它风格,译文就会很平。

还有一个大坑是术语一致性。在长文档翻译里,模型很容易前后不一致。第一页把 User Interface 翻译成“用户界面”,第十页可能就变成了“使用者介面”。为了解决这个问题,通常会在 Prompt 里附一个“术语表(Glossary)”: “在翻译过程中,必须严格遵守以下术语对照表:

  • User Interface -> 用户界面
  • Home Page -> 首页
  • Login -> 登录(注意不是登陆)”

有了这张表,不管上下文怎么变,这些核心词汇的译法就固定下来了。

场景三:改写(Rewriting) ​

这个坑最深。假设产品经理提了个需求,帮用户把大白话润色成“专业邮件”,待改写的原文是:“那个,老板,我把那个功能做完了,你看看行不行。”

直接扔进模型,说“润色一下”。结果出来一篇之乎者也的文言文,或者是一篇充满了“致以最崇高的敬意”这种翻译腔的公文。用户看了只会觉得尴尬。

改写任务的核心在于锚定(Anchoring),必须给模型一个参照物。

“专业”这个词太主观了。在律师眼里,专业意味着严谨、无漏洞;在销售眼里,专业意味着热情、有感染力;在程序员眼里,专业意味着简洁、直击要害。

常用的一招是提供“样本”。 “请模仿以下示例的语气改写这段话: [示例 1]:关于那个 Bug,我已经修复了,代码提交到了主分支,麻烦 Review 一下。 [示例 2]:服务器负载有点高,我加了两台机器,现在观察看平稳了。 待改写文本:那个,老板,我把那个功能做完了,你看看行不行。”

样本的作用就在这里,直接给一个符合要求的成品,模型对照着它,就能明白这里所谓的“专业”其实是“简洁、客观、不带情绪”。

这三个实战案例的共同点是,所谓的“简单任务”,其实都是因为人的大脑自动补全了大量的背景信息。而面对 AI 时,必须把这些背景信息显式地、一点不漏地写出来,缺了一条,模型就可能做错。

3.5 提示工程的六大黄金法则 ​

讲了这么多反面教材和具体案例,这一节把核心方法整理成六条。这六条法则来自大量工程实践,它们不是死板的教条,而是构建鲁棒 Prompt 的基础。掌握了这六条,绝大多数新手会踩的坑都能绕开。

法则一:指令置顶(Put Instructions at the Beginning) ​

这件事有实证研究支持,利用的是模型对开头信息的偏重。

虽然现在的模型上下文窗口(Context Window)越来越大,从早期的 128k 已经普遍推到 20 万、100 万的级别,但注意力机制(Attention Mechanism)在处理长文本时,并不是均匀分布的。斯坦福 Liu 等人 2023 年的实验(arXiv:2307.03172)就发现,模型对开头和结尾的信息最敏感,中间的信息在上下文挤爆(上下文腐化,Context Rot)时很容易出现“迷失中间(Lost in the Middle)”的现象。

设想给模型发了一篇 5000 字的长文,让它总结。如果“请总结这篇文章”这句话写在文章的最末尾,模型处理完前面 5000 字之后,注意力可能已经停在文章中间的某些段落上,根本没注意到最后那句指令。

所以,务必把任务指令用大白话写在最前面,甚至可以用 ### 这种分隔符把它高亮出来。

把指令放在最前面,模型是带着明确任务去读后面那 5000 字的,读到相关内容时更容易对上号。

在 Prompt 里,这通常长这样:

markdown
### 核心指令
你是一个资深编辑。请阅读下方的文章,并为其撰写三个不同风格的标题。

### 输入文本
[这里是那篇 5000 字的长文...]

先把任务定调,再给数据。这样模型在处理后续的大段文本时,就会带着“我要写标题”这个任务去读,它的注意力权重就会自动聚焦在那些能提炼标题的关键信息上。这是在直接利用模型的注意力机制。

法则二:细节明确(Be Specific, Not Just Descriptive) ​

这一条其实是对前面“清晰度原则”的升华。在 Prompt Engineering 里,细节就是参数。

别说“写一篇短文”,要说“写一篇 300 到 500 字的文章”。 别说“风格活泼”,要说“使用感叹号,多用反问句,每段不超过 3 句话,可以使用‘哈哈’、‘哎哟’等语气词”。 别说“输出数据”,要说“输出为 JSON 格式,包含 id, name, value 三个字段,其中 value 必须是浮点数”。

写 Prompt 的时候,要求可以更苛刻一点:每一个形容词,都应该能对应到一个具体的量化指标或者明确的执行动作。

一个词如果没法量化,那就别用,换个可以量化的词。

比如“有趣”,这个词就很难定义。但如果说“在文章中插入两个关于程序员的冷笑话”,这就可执行了。模型会去它的笑话库里检索,然后插进去。虽然插进去的笑话可能不好笑,但它至少执行了命令。

这里还有一个小技巧,角色扮演(Persona)其实也是一种细节参数的打包。 告诉模型“你是一个拥有 20 年经验的 Python 架构师”,其实是在隐式地设置一大堆参数,代码风格要规范、变量命名要清晰、要考虑异常处理、要关注性能优化。这比一条条列出这些要求要高效得多。因为在模型的训练数据里,“资深架构师”这个概念已经和这些高质量的代码特征强绑定了。

法则三:示例引导(Few-Shot Prompting is King) ​

如果只挑一个立竿见影的技巧,那就是少样本提示(Few-Shot Prompting)。用好了它,同一个任务的效果常常会有质的飞跃。

学规则不如看例子。抽象大道理讲得再多,看的人不一定能落到实际操作上;直接给两段符合规范的代码对照着看,要求立刻就具体了。

模型也一样。它读过海量语料,但没有示例时,它不确定该用哪部分知识来处理眼前的任务;给出输入和输出的配对示例,这个选择就定下来了。

比如要让模型做情感分析,与其费劲解释什么是“正面情绪”,不如直接写:

text
任务:判断评论情感。

示例 1:
评论:这就很棒,物流超快。
情感:正面

示例 2:
评论:真是服了,包装都烂了。
情感:负面

示例 3:
评论:还行吧,习惯好评。
情感:中性

请分析以下评论:
评论:这东西简直就是智商税。
情感:

注意看示例 2,“真是服了”。如果只看字面意思,“服了”好像是佩服,是正面。但这个例子等于告诉模型,在这个语境下,“服了”是反语,是负面。

这种通过数据而非规则来传达意图的方式,往往比写一千字的说明文档都管用。

而且,示例还能起到格式锁定的作用。在上面的例子里,没有明确说“不要输出任何解释”,但三个示例都只有“情感:XX”这一行,模型会倾向于模仿这个格式,只输出这一行,不再附加废话。示例本身就完成了格式约束。

法则四:任务拆解(Split Complex Tasks) ​

不要试图用一个 Prompt 解决所有问题。这是很多工程师的通病,总想写一个“万能 Prompt”,一次解决所有问题。结果往往是写出一个几千 token 的超长 Prompt,逻辑混乱,顾此失彼。

如果任务很复杂,比如“读取财报,分析数据,对比去年同期,然后写一段评语,最后翻译成英文”,请把它拆开。

把这一整串直接扔给模型,任务链条一旦太长,模型很容易“丢三落四”。可能分析得很好,但忘了翻译;可能翻译得很好,但数据对比错了。这是模型的“工作记忆”在长任务链下的天然瓶颈,需要靠分步拆解、外部状态(如 CoT/Scratchpad)、中间校验来兜住。

正确的做法是流水线作业(Pipeline)。

写一个 Prompt 专门负责提取数据,再写一个把第一步的数据拿来做计算对比,接着写一个根据对比结果写评语,末了再写一个把评语翻译成英文。

这就是思维链(Chain of Thought)的工程化体现。思维链的本意,是让模型把复杂推理分解成多步、把思考过程显式写出来,第 9 章会专门展开。这里先取它“分步”的思路,让模型一步一步来,不仅能降低每一步的难度,还能让问题更容易定位。

如果最后结果不对,可以检查是数据没提取对,还是翻译出了问题。如果混在一起,连 debug 都没法下手,只能对着那个巨大的 Prompt 发呆。记住,软件工程的核心思想之一就是解耦,Prompt Engineering 也不例外。

法则五:格式限定(Format Constraints) ​

这一点对把 LLM 集成到软件系统里至关重要。模型默认按对话习惯输出,答案前后常会带上“好的,这是您的结果”、“希望能帮到您”、“如果您还有其他问题请随时问我”。

这些废话对于人类来说是礼貌,对于代码解析器(Parser)来说就是杂质和噪音,会导致 JSON.parse 失败。

得用明确的输出规则把它限制住。

明确告诉它:“只输出 JSON,不要包含任何解释性文字。” 或者使用定界符:“将结果包裹在 json 和 之间。”

还有一些更“狠”的写法,比如: “你是一个 JSON 生成器。你不是聊天机器人。不要对我说‘好的’。直接输出 JSON 数据。如果输出包含任何非 JSON 字符,系统将崩溃,你会受到惩罚。”

虽然不会有人真的惩罚模型,但这种严厉的语气通常能提高它遵守规则的概率。

在更高级的玩法里,会利用 Prefilling(预填) 技巧。就是在 Prompt 的最后,替模型写好开头。 比如: User: 请输出 JSON。Assistant: {

当把 { 作为一个 token 喂给模型、放在开头时,模型就被迫进入了 JSON 的补全模式。它没法再说“好的”了,输出已经从 { 开始,只能接着往下补全。

不过这个技巧有明确的时效边界,部分新模型已经不再支持它。比如 Claude 4.6 及之后的版本,就不再接受预填的 assistant 消息,这类请求会直接报错。具体到手头的模型还灵不灵,动手前查一眼它的最新文档,第 2 章讲交互机制时交代过细节。

法则六:迭代优化(Iterate, Iterate, Iterate) ​

最后这一条,是心态上的修炼。

从来没有哪个完美的 Prompt 是一次写成的。写完第一个版本发现效果不好,千万别灰心,这太正常了。Prompt Engineering 本质上是一门实验科学,靠试错和测量推进,而不是靠一次设计到位。

要像调参一样去调 Prompt。改个词,跑一遍测试集;换个例子,再跑一遍。观察模型的坏案例(BAD Case),分析它为什么会理解错,然后针对性地加补丁。

有时候,仅仅是把“请”字去掉,或者把“不包含”改成“排除”,效果就会天差地别。有时候,把 Prompt 从英文改成中文,或者从中文改成英文,逻辑能力也会波动。

要建立起一套“编写 -> 测试 -> 分析 -> 修正”的闭环流程。

建议维护一个测试用例集。每次修改 Prompt,都要跑一遍这个集合,确保修复了一个 Bug 的同时,没有引入新的 Bug。这叫回归测试。

别指望照抄网上流传的“大神 Prompt”,换到具体业务场景里可能完全不灵。最好的 Prompt 永远是在具体数据里、在具体业务逻辑里,一点一点改出来的。这需要耐心,也需要观察力。

六条法则到这里就走完了。前三条讲一条指令怎么写,放在哪、写多细、拿什么做示范;后三条讲一个任务怎么组织,拆开干、定好格式、写完再改。它们不是六选一的单选题,真实的 Prompt 里往往同时用得上好几条。


本章总结 ​

从最开始的打破“聊天”幻觉,到建立“工程化”的思维,再到具体的六大黄金法则,这一章的主线就是完成这个切换。

其实千言万语汇成一句,把 LLM 当作一个极其强大但需要精确指令的函数解释器,而不是一个懂心意的人类助理。

哪天发现自己会为一个动词的选择纠结半小时,会对着模型的输出日志逐字分析,习惯用 JSON Schema 约束自然语言,甚至不再期待模型给“惊喜”、只追求“枯燥的稳定”,那就是迈过提示工程师门槛的时刻,再也不是一个单纯的 ChatGPT 用户。

到这里,清晰度、细节明确、格式限定、任务拆解这几件工具都已经上手了。

参考资料 ​

  1. Liu, N. F., Lin, K., Hewitt, J., et al. Lost in the Middle: How Language Models Use Long Contexts(TACL 2023,arXiv:2307.03172). https://arxiv.org/abs/2307.03172
  2. OpenAI. Prompt engineering(官方文档,含上下文窗口规模与指令前置、少样本示例等策略). https://platform.openai.com/docs/guides/prompt-engineering
  3. DAIR.AI. Prompt Engineering Guide - Tips(分隔符与指令位置建议). https://www.promptingguide.ai/introduction/tips
  4. Anthropic. Prefill Claude's response(官方文档,预填 { 生成 JSON 的用法). https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/prefill-claudes-response