提示与上下文工程实操:模板、few-shot、格式约束

LLM 知识 · 使用 · 第 5 篇 更新于 2026-10-15

硬件前提

纯 API。这一篇决定你后面所有场景的质量上限,比换模型更值钱。

一个可复用的上下文骨架

按这个顺序拼,稳定且利于缓存:

[system]   角色 + 硬性规则 + 输出格式 + 拒答条件
[资料区]   检索到的片段,每段带来源标记
[示例区]   2~3 个「输入 → 期望输出」示例
[历史]     最近 N 轮(更早的换成摘要)
[本轮]     用户问题 + 一句格式重申

要点:固定部分在前,变动部分在后;关键约束在末尾重申一次(长上下文里中段最容易被忽略)。

提示写法:五条实操规则

  1. 说清「要什么」和「不要什么」:「只根据资料回答;资料里没有就回答『资料未提及』」比「请准确回答」有效得多。
  2. 给结构,不给形容词:「分 3 点,每点不超过 40 字」优于「简洁明了」。
  3. 拆任务:抽取 → 判断 → 生成,三步分开调用。一步到位的长提示最容易在中途跑偏。
  4. 让它可核查:要求「每个结论标注来源片段编号」,随后你可以程序化校验编号是否真的存在。
  5. 别用否定式堆叠:一堆「不要…不要…」会互相干扰,改成「只做 X」。

few-shot:给几个、给什么样的

任务类型示例数注意
分类 / 抽取 / 格式转换2~5必须包含边界样本和「空结果」样本,否则它会硬凑
风格模仿2~3示例风格要一致,混风格等于没给
复杂推理1~2给推理过程容易带偏(它开始模仿格式而非结论),谨慎用

示例的格式一致性比数量重要:示例用了 JSON,输出就会是 JSON;示例里有一个错格式,就会污染输出。

格式约束:从弱到强

强度做法可靠性
弱提示里写「请输出 JSON」常出多余文字、注释、代码围栏
中给严格 schema + 示例 + 停止串多数情况可用,仍需解析容错
强使用 API 的结构化输出 / 工具调用模式高,字段级保证
最强强约束 + 解析失败自动重试一次(把报错回喂)生产可用

解析侧永远要写容错:剥掉代码围栏、截取第一个合法对象、字段缺失时重试而不是崩溃。

import json, re

def parse_json(text):
    text = re.sub(r"^```(?:json)?|```$", "", text.strip(), flags=re.M).strip()
    start, end = text.find("{"), text.rfind("}")
    if start == -1 or end == -1:
        raise ValueError("no json object")
    return json.loads(text[start:end + 1])

上下文预算:先算再塞

塞资料之前,先分配额度(示例值,按你的窗口调整):

部分预算
system + 工具说明5%~10%
资料片段40%~60%(宁少勿多)
历史20%~30%(超出换成摘要)
预留输出15%~25%

塞得多不等于答得好:无关片段会主动制造错误答案。加资料后如果质量下降,先减资料而不是加模型。

常见失败与排查

现象原因处理
输出带解释文字,解析失败只给了弱约束上结构化输出 + 解析容错 + 重试
它开始自问自答示例里出现了类似模式检查示例,删掉多余轮次
忽略某条规则规则太多或在中段规则砍到 5 条以内,关键规则放末尾
资料给了不用片段太远/太多减少片段、把最相关放最后、要求标注来源
换模型就崩提示过拟合某个模型保留提示回归测试集,换模型必跑

完成标志

你有一份提示模板文件(版本化)+ 一组回归样例(输入 → 期望输出),改提示或换模型时跑一遍就知道有没有变差。没有回归样例,所有提示优化都是碰运气。