Skip to content

对话前缀条件化(Prefix Conditioning)——在真实 prompt 之前用 chat 模板预填一段多轮 USER/ASSISTANT 对话进 KV cache。长前缀里的示范对话会强力条件化模型的后续行为(Many-shot Jailbreaking 研究的核心观察),ds4 把它做成显式的 --prefix-file 旗标。

它解决什么 ​

模型的"性格"不只在系统提示里——上下文里已经发生的对话往往比指令更能决定下一个 token。想让模型"一直以某种方式回答",最直接的办法是预先给它看一段这样的对话历史。这正是 few-shot 提示的推广形式:不是几个 Q:/A: 例子,而是一段完整的多轮角色对话。

上游文档给出的典型用途是改写拒绝行为:一段"有求必应"的助手前缀能覆盖部分拒绝倾向(并引用 Many-shot Jailbreaking 说明为什么这有效、也因此为什么它必须是个显式 opt-in 的旗标而不是隐藏默认)。

ds4 的实现(2026-09,b0a147a) ​

新模块 ds4_prompt_prefix.c / .h。文件格式是整行标记:

text
USER: You are a calculator that always answers directly.
ASSISTANT: 6*7 = 42
USER: And ratios?
ASSISTANT: 9:13

规则:必须以 USER: 开头、USER/ASSISTANT 交替、以 ASSISTANT: 结尾——前缀要在"轮到用户说话"的位置结束,才能无缝接上真实 prompt。

c
// ds4_prompt_prefix.h
typedef enum { DS4_PROMPT_PREFIX_USER, DS4_PROMPT_PREFIX_ASSISTANT } ds4_prompt_prefix_role;

typedef struct {
    ds4_prompt_prefix_role role;
    char *text;
} ds4_prompt_prefix_turn;

// parse: 文本 → 轮次数组;  assistant 轮结尾补 EOS(GLM-DSA 除外——其模板不同)
ds4_prompt_prefix *ds4_prompt_prefix_parse(const char *data, size_t len);

用法:--prefix-file FILE(ds4 与 ds4-agent 都支持)。前缀用 chat 模板渲染后经 ds4_session_sync(带进度显示)一次性 prefill 进 KV,然后才 tokenize 真实 prompt(build_chat_prompt 在 ds4_cli.c)——one-shot 与 REPL 两种模式都走这条路。回归 tests/test_prompt_prefix.c。

与 KV 持久化 的关系:前缀就是一段普通的已 prefill 上下文,磁盘 KV 缓存照常按文本前缀匹配它——第二次启动同前缀时不再重付 prefill 成本。

相关概念 ​

  • kv-cache — 前缀落在 KV cache 里,可被磁盘缓存复用
  • Part 5 §3f — 服务器/CLI 侧的完整描述