先回顾一下,getSystemPrompt 函数接收四个参数:
- tools:本轮对话可用的工具列表
- model:本轮对话所使用的模型,比如 "glm-5.2"
- additionalWorkingDirectories:用户用 --add-dir 添加的额外工作目录
- mcpClients:当前连上的 MCP 服务器客户端列表
上一篇分析了参数 tools,这篇接着看第二个参数 model。
系列文章在工作号:IT周瑜
为什么Claude Code生成系统提示词时,需要model信息呢?
核心原理其实很简单,Claude Code会在系统提示词里生成一段关于当前环境的信息(Environment 段落),用来描述当前工作目录、操作系统、当前使用的模型名字、知识截止日期、模型版本号等信息,从而让模型掌握更具体的环境信息。
你可能会问,难道模型自己不知道自己叫什么名字?还需要Claude Code告诉它?
这是有可能的,比如你问某些模型它的版本号,或者知识截止日期,它是有可能回答错误的,所以Claude Code会把这些信息明确写到系统提示词里,从而让模型更准确的知道这些信息。
底层分析
model 参数在 getSystemPrompt 函数里,主要传给 computeSimpleEnvInfo 函数,由它生成上面说的 Environment 段,其中和 model 相关的是两部分:
ts
// 模型名字
const marketingName = getMarketingNameForModel(modelId)
const modelDescription = marketingName
? `You are powered by the model named ${marketingName}. The exact model ID is ${modelId}.`
: `You are powered by the model ${modelId}.`
// 知识截止日期
const cutoff = getKnowledgeCutoff(modelId)
const knowledgeCutoffMessage = cutoff
? `Assistant knowledge cutoff is ${cutoff}.`
: null
这两个函数的实现都很直白,核心就是「先把模型 ID 规范化,再一连串 includes 匹配」。
getMarketingNameForModel 函数命中哪个 Claude 型号,就返回对应的展示名:
ts
function getMarketingNameForModel(modelId) {
const canonical = getCanonicalName(modelId) // 先把 ID 规范化
if (canonical.includes('claude-opus-4-6')) return 'Opus 4.6'
if (canonical.includes('claude-sonnet-4-6')) return 'Sonnet 4.6'
if (canonical.includes('claude-haiku-4-5')) return 'Haiku 4.5'
// ...其他 Claude 型号
return undefined // 都没命中(比如 glm-5.2),转不出展示名
}
getKnowledgeCutoff 函数同一个套路,按型号查截止日期:
ts
function getKnowledgeCutoff(modelId) {
const canonical = getCanonicalName(modelId)
if (canonical.includes('claude-opus-4-6')) return 'May 2025'
if (canonical.includes('claude-sonnet-4-6')) return 'August 2025'
// ...其他 Claude 型号
return null // 都没命中,查不到
}
所以 claude-opus-4-6 能匹配上、拿到 Opus 4.6 和 May 2025,而 glm-5.2 则匹配不上,两个函数分别返回 undefined 和 null。
最终在 Environment 部分里,两种模型的结果差别很大。
用 claude-opus-4-6 时,getMarketingNameForModel 函数转得出展示名 Opus 4.6,getKnowledgeCutoff 函数查得到 May 2025:
csharp
- You are powered by the model named Opus 4.6. The exact model ID is claude-opus-4-6.
- Assistant knowledge cutoff is May 2025.
换成 glm-5.2,展示名转不出,知识截止也查不到,modelDescription 只用了 ID:
csharp
- You are powered by the model glm-5.2.
一对比就清楚:Claude 模型有展示名、有知识截止,非 Claude 模型这两项都没了,只剩一个光秃秃的模型 ID。
实操
和上一篇一样,可以用 --dump-system-prompt 把系统提示词导出来,来对比 claude-opus-4-6 和 glm-5.2 两种情况。
两种情况都要改 src/entrypoints/cli.tsx 里 dump 那行的 model,每改一次重新打包、导出一个文件。
第一种:claude-opus-4-6
把那行改成:
ts
const prompt = await getSystemPrompt([], 'claude-opus-4-6');
重新打包再导出:
bash
bun devkit/build.ts
bun dist/cli.js --dump-system-prompt > a.txt
第二种:glm-5.2
把那行的 model 换成 glm-5.2:
ts
const prompt = await getSystemPrompt([], 'glm-5.2');
再打包导出到另一个文件:
bash
bun devkit/build.ts
bun dist/cli.js --dump-system-prompt > b.txt
diff a.txt b.txt
对比 a.txt 和 b.txt 的 Environment 段:
csharp
# a.txt(claude-opus-4-6)
- You are powered by the model named Opus 4.6. The exact model ID is claude-opus-4-6.
- Assistant knowledge cutoff is May 2025.
# b.txt(glm-5.2)
- You are powered by the model glm-5.2.
a.txt 有展示名和知识截止信息,b.txt 只有模型 ID。
注意,两个实验都做完后,把 features 里的 DUMP_SYSTEM_PROMPT 去掉、cli.tsx 里那行改回原样,重新打包恢复默认。
系列文章在工作号:IT周瑜