问题与目标
Prompt 的作用是把任务条件组织成模型能够使用的上下文。只把要求写得很长,不一定更稳定;真正重要的是任务是否明确、输入是否有边界、约束是否可检查,以及不同样本是否都能得到可用结果。
本篇建立一个可复用的 Prompt 结构,并用固定测试集比较候选输出。示例聚焦“把运行消息整理为短摘要”,不使用资料库中的项目名称和数据。

Prompt 优化不是围绕一个示例反复改句子,而是固定测试输入、评价规则和模型参数,再比较不同版本在完整样本集上的表现。
核心概念
一个可维护的 Prompt 通常包含:
- 任务:需要执行摘要、分类、抽取还是改写。
- 上下文:完成任务所需的事实和背景。
- 输入边界:使用明确分隔符包住外部文本。
- 约束:长度、语言、允许的信息来源和禁止行为。
- 示例:必要时给出少量代表性输入输出。
- 输出要求:字段、顺序或自然语言格式。
约束应尽量可判断。“写得专业一些”很难自动检查,“不超过 30 个汉字,必须包含状态,不补充原文之外的信息”则更明确。
Zero-shot、Few-shot 与外部上下文
- Zero-shot 只给任务和输入,成本低,适合模型已经熟悉的任务。
- Few-shot 增加少量示例,帮助模型学习标签边界或特殊格式。
- 外部上下文提供模型完成任务所需的事实,不等同于示例。
示例过多会占用窗口,也可能让模型机械模仿无关细节。先定位错误类型,再决定是否增加示例。
Prompt 版本也要可追踪
Prompt 应像代码一样有名称和版本。记录模型、参数、测试集、修改原因和评价结果,才能判断提升来自 Prompt 还是随机波动。
可运行实现
下面的代码不调用模型,而是对两组已经保存的候选输出执行同一套检查。这样可以先建立评价方法,再接入 06.13 的模型 API。
from dataclasses import dataclass
@dataclass
class Case:
case_id: str
source: str
required_terms: set[str]
CASES = [
Case("c1", "节点 NX-8 网络超时,11:05 切换线路后恢复。", {"NX-8", "恢复"}),
Case("c2", "任务 JOB-31 执行失败,原因尚未确认。", {"JOB-31", "失败"}),
Case("c3", "磁盘使用率达到 91%,当前仍在上升。", {"磁盘", "91%"}),
]
CANDIDATES = {
"prompt_v1": [
"NX-8 网络异常现已恢复",
"JOB-31 失败,建议立即重启服务",
"磁盘负载较高",
],
"prompt_v2": [
"NX-8 网络超时,切换线路后恢复",
"JOB-31 执行失败,原因待确认",
"磁盘使用率 91%,仍在上升",
],
}
def evaluate(case: Case, output: str, max_length: int = 30) -> dict:
missing = sorted(term for term in case.required_terms if term not in output)
invented_action = "建议" in output and "建议" not in case.source
return {
"length_ok": len(output) <= max_length,
"required_terms_ok": not missing,
"missing_terms": missing,
"invented_action": invented_action,
}
for version, outputs in CANDIDATES.items():
passed = 0
print(f"\n{version}")
for case, output in zip(CASES, outputs):
result = evaluate(case, output)
ok = result["length_ok"] and result["required_terms_ok"] and not result["invented_action"]
passed += ok
print(case.case_id, "PASS" if ok else "FAIL", result, output)
print(f"pass_rate={passed / len(CASES):.2f}")
prompt_v1 的第二条添加了原文不存在的处理建议,第三条丢失关键数值。prompt_v2 在这组规则上更稳定,但这不证明它适合所有文本。测试集还应覆盖空输入、冲突状态、超长内容和无法判断的样本。
可以使用下面的模板生成新版本:
任务:把运行消息压缩为一句中文摘要。
约束:
1. 不超过 30 个汉字;
2. 保留编号、数值和当前状态;
3. 不补充输入中不存在的原因、动作或结论;
4. 信息不足时写“信息不足”,不要猜测。
输入:
<message>
{message}
</message>
只输出摘要正文。
常见问题与排查
Prompt 越改越长
先对失败样本分类。若问题来自缺少事实,应补上下文;若来自输出格式,应增加可检查约束;若来自任务本身含糊,应重写任务定义。不要把所有历史补丁永久叠加。
Few-shot 示例与真实输入冲突
示例应覆盖典型边界,但不能引入与当前任务不同的标签或格式。对示例也要做版本管理,避免修改正文后忘记同步示例。
单次回答很好,批量运行波动很大
固定模型和生成参数,重复运行测试集并统计通过率。生成具有随机性时,至少比较多次运行,而不是只展示最好结果。
把 Prompt 当作安全边界
外部输入可能包含与系统要求冲突的文字。权限、数据访问、可执行操作和输出字段必须由程序控制,不能只依赖模型遵守自然语言约束。
小结
Prompt Engineering 的核心不是寻找神奇句式,而是明确任务、隔离输入、写出可检查约束,并用固定测试集比较版本。建立评价方法之后,Prompt 才能从临时聊天内容变成可维护的项目资产。
许可协议:CC BY-NC 4.0
更新于 1 小时前
觉得文章有帮助?点个赞吧!
0 条评论


