Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/06-SystemPrompt与OutputStyle注入.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 第 6 章:System Prompt 与 Output Style 注入 — 精密控制模型行为的提示词体系

> 本章是《深入 Claude Code 源码》系列第 6 章。我们将深入 `constants/prompts.ts`(914 行,commit `290fdc94`)这个核心文件,揭示 Claude Code 如何通过精心设计的 System Prompt 架构,在「精确控制模型行为」和「最大化 Prompt Cache 命中率」之间取得平衡。
> 本章是《深入 Claude Code 源码》系列第 6 章。我们将深入 `constants/prompts.ts`(914 行)这个核心文件,揭示 Claude Code 如何通过精心设计的 System Prompt 架构,在「精确控制模型行为」和「最大化 Prompt Cache 命中率」之间取得平衡。

## 为什么 System Prompt 值得单独一篇?

Expand Down
5 changes: 3 additions & 2 deletions docs/09-Thinking-Effort-与-Advisor.md
Original file line number Diff line number Diff line change
Expand Up @@ -935,10 +935,11 @@ export function shouldEnablePromptSuggestion(): boolean {

整个文件最值得划重点的是 `generateSuggestion()` 的实现策略(`promptSuggestion.ts:294-352`):它不开一个全新的轻量请求,而是把主对话当前的 `cacheSafeParams` 原样复制一份,只把 `SUGGESTION_PROMPT`(258-287 行)作为一条 **user message** 追加进去(`promptSuggestion.ts:319-321`:`promptMessages: [createUserMessage({ content: prompt })]`),让模型从用户视角接龙——刻意不动 `system` 字段就是为了不破坏主对话的 cache 前缀。

为什么这么绕?因为 Anthropic 的 Prompt Cache 是**前缀严格匹配**的——任何一个参数(包括 `system`、`tools`、`temperature`、甚至 `thinking` / `effort`)和主请求不一致,就会触发一次完整的 cache write 而不是 cache hit。代码注释里直接写了教训
为什么这么绕?因为 Anthropic 的 Prompt Cache 是**前缀严格匹配**的——任何一个参数(包括 `system`、`tools`、`temperature`、甚至 `thinking` / `effort`)和主请求不一致,就会触发一次完整的 cache write 而不是 cache hit。源码里的代码注释(`services/PromptSuggestion/promptSuggestion.ts:313`)直接写了教训,下面是它的中文转述

```typescript
// PR #18143 复盘:早期版本把建议请求的 effort 强行降到 'low' 节省成本,
// 改写自 services/PromptSuggestion/promptSuggestion.ts:313 的英文注释:
// 早期版本把建议请求的 effort 强行降到 'low' 节省成本,
// 结果 cache write 量飙升 45x,主对话的 cache hit rate 从 92.7% 跌到 61%。
// 节省的那点 effort 钱远抵不上 cache miss 多花的钱。
```
Expand Down
2 changes: 0 additions & 2 deletions docs/18-MCP协议实现.md
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,6 @@ Channel 通知的注册逻辑尤其值得关注——它经过多层门控(`ga

---

---

## 下一章预告

[第 19 章:权限系统与远程权限回灌 — AI 安全的最后一道防线](./19-权限系统与远程权限回灌.md)
Expand Down
2 changes: 0 additions & 2 deletions docs/19-权限系统与远程权限回灌.md
Original file line number Diff line number Diff line change
Expand Up @@ -945,8 +945,6 @@ async recheckPermission() {

---

---

## 下一章预告

[第 20 章:Hooks 系统 — 用 Shell 命令扩展 AI 行为](./20-Hooks系统.md)
Expand Down
2 changes: 0 additions & 2 deletions docs/27-组件与设计系统.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,8 +521,6 @@ interface Tool {

---

---

## 下一章预告

[第 28 章:Keybindings、Vim 模式与 Voice 输入 — 终端输入层的三种解释](./28-Keybindings-Vim与Voice输入.md)
Expand Down
2 changes: 0 additions & 2 deletions docs/28-Keybindings-Vim与Voice输入.md
Original file line number Diff line number Diff line change
Expand Up @@ -618,8 +618,6 @@ Keybindings 是按键派发的基础设施,但 Vim 的 Escape 故意绕过这

---

---

## 下一章预告

[第 29 章:Buddy 宠物 — 在 PromptInput 边上养一只随机生成的小动物](./29-Buddy宠物.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/29-Buddy宠物.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ case 'companion_intro':

发现入口的设计在 `useBuddyNotification.tsx`。`buddy/useBuddyNotification.tsx:12-21` 给出两个判断函数 `isBuddyTeaserWindow()` 和 `isBuddyLive()`,它们都先有一道 `if ('external' === 'ant') return true` 的字面量比较,然后用 `new Date()` 拿到当前时间,分别比较年月日。`isBuddyTeaserWindow` 返回 `d.getFullYear() === 2026 && d.getMonth() === 3 && d.getDate() <= 7`——2026 年 4 月 1 日到 7 日;`isBuddyLive` 返回 `d.getFullYear() > 2026 || (d.getFullYear() === 2026 && d.getMonth() >= 3)`——2026 年 4 月及之后。

两个判断都走 **本地日期**——`getFullYear() / getMonth() / getDate()`,不是 `getUTC*`。源码注释里把理由写明白了
两个判断都走 **本地日期**——`getFullYear() / getMonth() / getDate()`,不是 `getUTC*`。源码注释(`buddy/useBuddyNotification.tsx:9-10`)里把理由写明白了

> Local date, not UTC — 24h rolling wave across timezones. Sustained Twitter buzz instead of a single UTC-midnight spike, gentler on soul-gen load.

Expand Down
2 changes: 1 addition & 1 deletion docs/32-命令系统全景.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ switch (command.type) {

`commands.ts` 是整个命令系统的**聚合枢纽**。它将来自六个不同来源的命令合并为一个统一的列表。

聚合枢纽本身有多大?`commands.ts` 当前 754 行(`commands.ts:1-754`),向上挂接了 `commands/` 目录——这个目录在 commit `290fdc9` 上是 86 个一级子目录 + 15 个一级 `.ts/.tsx` 文件 = 101 个一级条目,合计 207 个源码文件。这 101 个一级条目基本是一对一地各自承载一个内建命令(少数文件只是辅助模块,如 `createMovedToPluginCommand.ts`)。换句话说,下面这套 `loadAllCommands()` 加载机制要把这 207 个文件、连同来自磁盘 Skill / Plugin / Bundled / Workflow 的命令,统一收编进同一份 `Command[]` 列表里(MCP Skill 不走 `loadAllCommands()`,而是由 SkillTool 在执行时通过 `AppState.mcp.commands` 并入,详见 §4.3 与 §6.1)。
聚合枢纽本身有多大?`commands.ts` 当前 754 行(`commands.ts:1-754`),向上挂接了 `commands/` 目录——这个目录在当前快照上是 86 个一级子目录 + 15 个一级 `.ts/.tsx` 文件 = 101 个一级条目,合计 207 个源码文件。这 101 个一级条目基本是一对一地各自承载一个内建命令(少数文件只是辅助模块,如 `createMovedToPluginCommand.ts`)。换句话说,下面这套 `loadAllCommands()` 加载机制要把这 207 个文件、连同来自磁盘 Skill / Plugin / Bundled / Workflow 的命令,统一收编进同一份 `Command[]` 列表里(MCP Skill 不走 `loadAllCommands()`,而是由 SkillTool 在执行时通过 `AppState.mcp.commands` 并入,详见 §4.3 与 §6.1)。

### 2.1 内建命令:静态导入 + Feature Gate

Expand Down
2 changes: 0 additions & 2 deletions docs/33-状态管理与跨进程桥.md
Original file line number Diff line number Diff line change
Expand Up @@ -814,8 +814,6 @@ export async function readBridgePointerAcrossWorktrees(

---

---

## 下一章预告

[第 34 章:架构模式总结 — 可迁移到你自己项目的设计模式](./34-架构模式总结.md)
Expand Down
Loading