一份写出稳定、可预测的 AI 提示词的实用指南。


核心原则:降低不确定性

AI 模型每生成一个词,都在很多候选词中做选择。你的提示词结构直接决定了模型在关键节点是”犹豫”还是”确定”。

  • 确定性高 → 行为稳定
  • 确定性低 → 行为飘忽

下面所有技巧都在做同一件事:让模型在关键决策点更确定。

简单例子

你的提示词需要模型根据环境决定是否询问用户。

自然语言版本:

如果在 CI 环境中且没有参数,使用默认值。
如果在交互模式中有参数,直接运行。
如果在交互模式中没有参数,询问用户。

模型读完后,3 条规则同时争夺注意力。它需要回头扫描才能拼出答案。

决策树版本:

## CI 环境?
├─ 是
│  └─ 有参数?
│     ├─ 是 → 使用参数,执行
│     └─ 否 → 使用默认值,执行
└─ 否(交互模式)
   └─ 有参数?
      ├─ 是 → 使用参数,执行
      └─ 否 → 询问用户

模型判断 “CI = 是” 且 “参数 = 否” 后,注意力集中在这一行:

│     └─ 否 → 使用默认值,执行
              ↑ 注意力集中在这里

答案就在眼前,不需要回头看。确定性很高。

一句话总结

决策树让模型看几个附近的词就知道该做什么。自然语言让它扫一整段才能拼出答案。搜索范围越小,结果越确定。


模式 1:决策树替代自然语言

对有分支逻辑的指令,用可视化树结构替代文字描述。

不好:自然语言

如果在 CI 环境中且没有参数,使用默认值。如果在交互模式中有参数,
直接运行。如果在交互模式中没有参数,询问用户。

好:决策树

## $ARGUMENTS 非空?
├─ 是 → 解析参数,直接执行,不交互
└─ 否
   ## $CI 或 $CLAUDE_NONINTERACTIVE 已设置?
   ├─ 是 → 使用 <defaults> 的值,直接执行
   └─ 否 → 询问用户缺少的参数,然后执行

为什么有效: 缩进编码了层级关系。模型在训练中见过大量缩进结构(代码、YAML、目录树),学会了”缩进越深 = 子条件”。自然语言没有这种空间编码。


模式 2:锚定(给起点)

给模型一个具体的起点,不让它凭空发挥。

不好:无锚定

生成一个部署脚本。

好:用模板锚定

基于这个模板生成部署脚本:
<template>
#!/bin/bash
set -euo pipefail
ENV="${1:?Usage: deploy.sh <env>}"
# ... 你的步骤
</template>

为什么有效: 模板的内容直接参与模型的注意力计算。模型的输出会被”拉向”模板的风格,而不是从”部署脚本”这个笼统概念中随机生成。


模式 3:认知卸载(把思考步骤写出来)

把模型本来需要隐式推理的步骤显式地写出来。

不好:隐式推理

分析这段代码的性能问题并修复。

好:显式步骤

<analysis_steps>
1. 找出所有循环和递归
2. 标注每个的时间复杂度
3. 标记 O(n²) 或更高的
4. 为每个标记的部分提出优化方案
</analysis_steps>
按顺序执行这些步骤。

为什么有效: LLM 没有真正的工作记忆。把中间步骤写出来等于给了”外部记忆”——每一步只需要看上一步的输出,不需要从头推导。

决策树 = 分支逻辑的认知卸载。 思维链 = 推理过程的认知卸载。 同一个原理,不同应用。


模式 4:注意力局部性(把相关的放在一起)

相关信息在文本中应该靠近。越近的词获得越强的注意力。

不好:规则离目标太远

<rules>永远不要删除生产数据库</rules>
...(中间隔了 500 个词)...
<task>清理过期数据</task>

好:规则紧挨目标

<task>
清理过期数据
<constraint>永远不要删除生产数据库</constraint>
</task>

为什么有效: Transformer 的注意力理论上是全局的,但实际上有位置偏好——近的词注意力更强。把约束放在它约束的动作旁边,不要放在远处的”通用规则”里。


模式 5:指令-动作绑定(一条指令一个动作)

每条指令应该尽可能直接对应一个可执行动作。

不好:一句话多个动作

检查代码风格问题并修复,然后运行测试确保通过。

好:一条指令 = 一个动作

1. 运行:`eslint --fix src/`
2. 运行:`npm test`
3. 如果测试失败 → 读错误输出,修复问题,回到步骤 2

为什么有效: 模型把一条清晰指令映射到一个工具调用的可靠性,远高于从一个长句中提取多个隐含动作。


模式 6:输出格式预设(给输出一个”形状”)

给模型一个输出的结构,它来填内容。

不好:开放式

分析这个 PR 的风险。

好:结构约束

<output_schema>
- risk_level: high | medium | low
- affected_files: [列表]
- rollback_plan: [字符串]
- requires_review: true | false
</output_schema>

为什么有效: 结构定义就像”铁轨”。生成每个字段值时,模型的注意力被字段名强力引导,大幅减少偏离。


模式 7:负空间(说”不要”的同时说”要”)

告诉模型不该做什么时,永远同时告诉它该做什么。

不好:只说不要

不要直接修改数据库。
不要跳过测试。
不要用 sudo。

好:不要 + 替代方案

<boundaries>
- 数据库变更 → 生成迁移文件,不要执行原始 SQL
- 需要验证 → 运行完整测试套件再继续,不要跳过
- 需要提权 → 请求用户确认,不要用 sudo
</boundaries>

为什么有效: “不要做 X” 只压制了某些输出,但没有推动任何替代方案。模型知道不往哪走,但不知道往哪走。同时给出替代方案就能同时压制错误路径并推动正确路径。


模式 8:XML 标签做语义分区

Claude 的训练数据中包含 XML 标签。用它们来划分提示词的不同部分。

推荐的提示词结构

<context>
模型需要了解的背景信息。
</context>

<parameters>
输入参数,包含类型、默认值、来源。
</parameters>

<decision_tree>
可视化的分支逻辑,每个叶子有明确动作。
</decision_tree>

<examples>
<example>
<input>...</input>
<thinking>模型应该遵循的逐步推理</thinking>
<output>...</output>
</example>
</examples>

<boundaries>
不要做什么 + 应该做什么。
</boundaries>

<output_schema>
期望的输出格式。
</output_schema>

为什么有效: XML 标签创建硬性的语义边界。模型把不同标签内的内容当作独立的区块,减少指令、示例、约束之间的互相干扰。


模式 9:带推理过程的示例

让模型看到怎么想,不只是输出什么

不好:只有输入/输出

<example>
<input>deploy staging</input>
<output>已部署到 staging。</output>
</example>

好:输入 + 思考过程 + 输出

<example>
<input>deploy staging</input>
<thinking>
1. 提供了参数:"staging" → 非空 → 跳过用户交互
2. 环境 "staging" 有效(匹配 staging|production)
3. 未检测到 CI 变量 → 但有参数 → 静默执行
4. 执行部署到 staging
</thinking>
<output>已成功部署到 staging。</output>
</example>

为什么有效: 示例中的 <thinking> 模式会被泛化到模型自己的推理中。它学到的是推理方式,不只是输出格式。


各模式之间的关系

行为稳定性
    ↑
决策点的确定性高
    ↑
注意力分布集中
    ↑
提示词中的词语空间排列
    ↑
┌──────────┬──────────┬──────────┬──────────┐
│ 决策树    │ 注意力   │ 认知卸载  │ 输出格式  │
│          │ 局部性    │          │ 预设     │
├──────────┼──────────┼──────────┼──────────┤
│ 锚定     │ 指令-动作 │ 负空间    │ XML      │
│          │ 绑定      │          │ 标签     │
├──────────┼──────────┼──────────┼──────────┤
│ 带推理的  │          │          │          │
│ 示例     │          │          │          │
└──────────┴──────────┴──────────┴──────────┘

所有技巧都在做同一件事:
改变生成时注意力在各个词上的分布。

参考资料