Claude Code源码分析(三):为什么系统提示词中需要有tools呢?

先回顾一下,getSystemPrompt 函数接收四个参数:

  1. tools:本轮对话可用的工具列表
  2. model:本轮对话所使用的模型,比如 "glm-5.2"
  3. additionalWorkingDirectories:用户用 --add-dir 添加的额外工作目录
  4. 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.6May 2025,而 glm-5.2 则匹配不上,两个函数分别返回 undefinednull

最终在 Environment 部分里,两种模型的结果差别很大。

claude-opus-4-6 时,getMarketingNameForModel 函数转得出展示名 Opus 4.6getKnowledgeCutoff 函数查得到 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-6glm-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.txtb.txtEnvironment 段:

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周瑜

相关推荐
爱勇宝1 小时前
Claude Code 被曝暗藏“隐形检测”代码:封代理不是最可怕的,可怕的是你根本不知道它在干什么
前端·后端·程序员
小牛不牛的程序员1 小时前
我用 Claude Code 半天撸完了一个完整网站,AI 编程到底提升了多少效率?
前端
东风破_1 小时前
JavaScript 面试常考的字符串算法:从反转字符串到回文判断
前端·javascript
ITOM运维行者2 小时前
从零搭建企业级服务器监控体系:踩坑实录与架构设计
前端·后端
monologues2 小时前
深入 Vue 3 源码:响应式系统的精妙设计与编译优化
前端
hunterandroid2 小时前
Paging 3 分页:从手动分页到声明式加载
前端
用户4099322502122 小时前
Vue状态管理入门第四章:组合式store和SSR风险
前端·vue.js·后端
用户34232323763172 小时前
SPI 通信与高速外设驱动详解
后端
Csvn2 小时前
CSS :has() 选择器实战:没有它之前我们写了多少冗余 JS
前端·css