mirror of
https://github.com/shareAI-lab/analysis_claude_code.git
synced 2026-09-20 12:13:38 +08:00
feat: consolidate course into 21 lessons
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md)
|
||||
|
||||
s01 → ... → s07 → s08 → `s09` → [s10](../s10_system_prompt/) → s11 → ... → s20 → s21 → s22
|
||||
s01 → ... → s07 → s08 → `s09` → [s10](../s10_system_prompt/) → s11 → ... → s20 → s21
|
||||
> *"圧縮は詳細を失う、失わない層が必要"* — ファイルストア + インデックス + オンデマンド読み込み。圧縮を越え、セッションを越えて。
|
||||
>
|
||||
> **Harness レイヤー**: 記憶 — 圧縮とセッションを越える知識の蓄積。
|
||||
@@ -146,8 +146,6 @@ def consolidate_memories():
|
||||
# Replace all files with consolidated results
|
||||
```
|
||||
|
||||
CC はこのプロセスを **Dream** と呼び、実際には 4 層のゲートがある:時間間隔、スキャンスロットル、セッション数、ファイルロック。教学版はファイル数閾値に簡略化。
|
||||
|
||||
### Memory に保存するもの
|
||||
|
||||
Memory はセッションを越えて有用な情報を保存する:ユーザーの好み、繰り返し出るフィードバック、プロジェクト背景、よく使う入口、調査の手がかりなど。「あとでまた使うもの」を対象にし、インデックス + オンデマンド読み込みで現在の会話に戻す。
|
||||
@@ -192,90 +190,5 @@ python s09_memory/code.py
|
||||
|
||||
s10 System Prompt → セグメント + 実行時組み立て。異なるプロジェクト、異なるツール、異なるプロンプト。
|
||||
|
||||
<details>
|
||||
<summary>CC ソースコードの詳細</summary>
|
||||
|
||||
> 以下は CC ソースコード `src/` 下の `memdir/`、`services/`、`utils/`、`query/` の分析に基づく。行番号はソースコードと照合済み。
|
||||
|
||||
### ソースコードパス
|
||||
|
||||
| ファイル | 行数 | 職責 |
|
||||
|------|------|------|
|
||||
| `memdir/memdir.ts` | 507 | 核心:MEMORY.md 定義(`34-38`)、記憶動作指示で memory/plan/tasks を区別(`199-266`)、`loadMemoryPrompt()` 3 パス(`419-490`) |
|
||||
| `memdir/findRelevantMemories.ts` | 141 | Sonnet side-query で記憶選択(`18-24` システムプロンプト、`97-122` 呼び出しロジック) |
|
||||
| `memdir/memoryTypes.ts` | 271 | 型定義、frontmatter フィールド |
|
||||
| `memdir/memoryScan.ts` | — | .md ファイルをスキャン、MEMORY.md を除外、frontmatter を読み取り、最大 200 ファイル、mtime 降順(`35-94`) |
|
||||
| `services/extractMemories/extractMemories.ts` | 615 | forked agent で記憶を抽出、制限付き権限、`skipTranscript: true`、`maxTurns: 5`(`371-427`) |
|
||||
| `services/autoDream/autoDream.ts` | 324 | Dream 整理、4 層ゲート(`63-66` デフォルト値、`130-190` ゲート、`224-233` forked agent) |
|
||||
| `services/SessionMemory/sessionMemory.ts` | 495 | セッションレベルの記憶管理 |
|
||||
| `services/compact/sessionMemoryCompact.ts` | — | session memory 軽量サマリ、閾値 10K/5/40K(`56-61`) |
|
||||
| `utils/attachments.ts` | — | 注入予算:200 行 / 4096 バイト/ファイル、60KB/セッション(`269-288`);query で関連記憶を検索(`2196-2241`) |
|
||||
| `query.ts` | — | memory prefetch を毎ターン開始時に起動(`301-304`)、非ブロッキング収集(`1592-1614`) |
|
||||
| `query/stopHooks.ts` | — | stop hook fire-and-forget で抽出と Dream をトリガー(`141-155`) |
|
||||
|
||||
### 記憶選択:embedding ではなく LLM
|
||||
|
||||
CC は **Sonnet 自身で選択**(`findRelevantMemories.ts`)、embedding ベクトル類似度ではない:
|
||||
|
||||
1. `memoryScan.ts` が `.memory/` 下のすべての `.md` ファイルをスキャン(MEMORY.md を除外)、最大 200 ファイル、mtime 降順
|
||||
2. `name` + `description` をカタログとしてリスト化
|
||||
3. Sonnet side-query に送信:「名前と説明から本当に有用な記憶を選択(最大 5 件)。不明ならスキップ。」
|
||||
4. Sonnet が `{ selected_memories: ["file1.md", ...] }` を返却
|
||||
5. 選択されたファイルの完全な内容を読み込み(≤ 200 行 / 4096 バイト/ファイル)、注入。セッション総予算:60KB
|
||||
|
||||
毎ターンのユーザー turn 開始時、`query.ts:301-304` が memory prefetch を起動(非同期);ツール実行後、`1592-1614` が非ブロッキングで結果を収集。
|
||||
|
||||
### 抽出タイミング:stop hook、autoCompact 後ではない
|
||||
|
||||
トリガー位置(`stopHooks.ts:141-155`):`handleStopHooks()` 内で、fire-and-forget で抽出と Dream をトリガー。教学版は `stop_reason != "tool_use"` 分岐に抽出を配置、方向は一致。
|
||||
|
||||
CC の抽出は forked agent で実行(`extractMemories.ts:371-427`):制限付き権限、`skipTranscript: true`、`maxTurns: 5`。重複保護もある:メイン Agent が既に記憶ファイルを書き込んだ場合、抽出をスキップ。
|
||||
|
||||
### 記憶ファイル形式
|
||||
|
||||
CC は Markdown + YAML frontmatter を使用、教学版と一致。4 種類:`user`、`feedback`、`project`、`reference`。
|
||||
|
||||
`memdir.ts:34-38` がインデックス制約を定義:`MEMORY.md` 最大 200 行 / 25KB。`memdir.ts:199-266` が記憶動作指示を構築、memory と plan と tasks を明確に区別。保存場所:`~/.claude/projects/<sanitized-git-root>/memory/`。
|
||||
|
||||
### Dream:4 層ゲート
|
||||
|
||||
「アイドル時にトリガー」や「数が足りたら統合」ではなく、4 層のゲート(`autoDream.ts`、デフォルト値 `63-66`、ゲートロジック `130-190`):
|
||||
|
||||
1. **時間ゲート**:前回の統合から ≥ 24 時間
|
||||
2. **スキャンスロットル**:頻繁なファイルシステムスキャンを回避
|
||||
3. **セッションゲート**:前回の統合以降 ≥ 5 セッションの transcript が変更された
|
||||
4. **ロックゲート**:他のプロセスが統合中でない(`.consolidate-lock` ファイル)
|
||||
|
||||
統合自体は forked agent で実行(`224-233`):定位 → 直近のシグナル収集 → 統合してファイル書き込み → 剪定してインデックス更新。ロックファイルの mtime が lastConsolidatedAt。クラッシュリカバリ:1 時間後にロックが自動期限切れ。
|
||||
|
||||
### User Memory vs Session Memory
|
||||
|
||||
| | User Memory | Session Memory |
|
||||
|---|---|---|
|
||||
| 永続性 | セッション間 | 単一セッション |
|
||||
| ストレージ | `memory/` 下の複数 .md ファイル | `session-memory/<id>/memory.md` |
|
||||
| 注入先 | system prompt | compact サマリ |
|
||||
| 目的 | セッション間の知識蓄積 | compact を越えたコンテキストの連続性 |
|
||||
|
||||
sessionMemoryCompact(s08 で触れた仕組み)は Session Memory を活用:autoCompact の前に session memory ファイルを読み込み、内容が十分であれば(≥ 10K token、≥ 5 テキストメッセージ、≤ 40K token、`sessionMemoryCompact.ts:56-61`)、LLM を呼び出さずにサマリとして使用。
|
||||
|
||||
### 実際の実装が教学版より複雑な点
|
||||
|
||||
- **Feature flags**:記憶関連機能には複数の feature gate 層がある
|
||||
- **Team memory**:チーム共有記憶、`loadMemoryPrompt()` に専用パスあり(教学版では未カバー)
|
||||
- **KAIROS**:タイミング認識型の記憶抽出戦略、`loadMemoryPrompt()` の daily-log モード
|
||||
- **Prompt cache**:記憶注入は prompt cache の TTL を考慮する必要があり、毎ターン system prompt の大部分を書き直すことを避ける
|
||||
- **ファイルロック**:マルチプロセス時の並行制御
|
||||
- **Memory prefetch**:非同期プレフェッチ、メインフローをブロックしない
|
||||
|
||||
### 教学版の簡略化は意図的
|
||||
|
||||
- LLM side-query → LLM side-query + キーワードフォールバック:教学版は LLM 選択を維持し、フォールバックパスを追加
|
||||
- 記憶 JSON → Markdown + frontmatter:教学版は CC と一致
|
||||
- stop hook トリガー → `stop_reason != "tool_use"` 分岐:方向は一致
|
||||
- 4 層ゲート → ファイル数閾値:教学版には transcript システムやマルチセッションの概念がない
|
||||
- forked agent + 制限付き権限 → 直接呼び出し:教学版にはサブプロセス分離がない
|
||||
|
||||
</details>
|
||||
|
||||
<!-- translation-sync: zh@v1, en@v1, ja@v1 -->
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md)
|
||||
|
||||
s01 → ... → s07 → s08 → `s09` → [s10](../s10_system_prompt/) → s11 → ... → s20 → s21 → s22
|
||||
s01 → ... → s07 → s08 → `s09` → [s10](../s10_system_prompt/) → s11 → ... → s20 → s21
|
||||
> *"Compression loses details, keep a layer that doesn't"* — File store + index + on-demand loading, across compactions, across sessions.
|
||||
>
|
||||
> **Harness Layer**: Memory — knowledge that survives compaction and sessions.
|
||||
@@ -146,8 +146,6 @@ def consolidate_memories():
|
||||
# Replace all files with consolidated results
|
||||
```
|
||||
|
||||
CC calls this process **Dream**, with four gates in practice: time interval, scan throttle, session count, file lock. The teaching version simplifies to a file-count threshold.
|
||||
|
||||
### What Memory Stores
|
||||
|
||||
Memory stores information that remains useful across sessions: user preferences, recurring feedback, project background, common entry points, and investigation clues. It focuses on "what will be useful later" and brings that information back through an index plus on-demand loading.
|
||||
@@ -192,90 +190,5 @@ Memory, compression, and tools are all in place. But the system prompt is still
|
||||
|
||||
s10 System Prompt → segments + runtime assembly. Different projects, different tools, different prompts.
|
||||
|
||||
<details>
|
||||
<summary>Deep Dive Into CC Source Code</summary>
|
||||
|
||||
> The following is based on analysis of CC source code under `src/` in `memdir/`, `services/`, `utils/`, `query/`. Line numbers verified against source.
|
||||
|
||||
### Source Code Paths
|
||||
|
||||
| File | Lines | Responsibility |
|
||||
|------|-------|---------------|
|
||||
| `memdir/memdir.ts` | 507 | Core: MEMORY.md definition (`34-38`), memory behavior instructions distinguishing memory/plan/tasks (`199-266`), `loadMemoryPrompt()` three paths (`419-490`) |
|
||||
| `memdir/findRelevantMemories.ts` | 141 | Sonnet side-query memory selection (`18-24` system prompt, `97-122` call logic) |
|
||||
| `memdir/memoryTypes.ts` | 271 | Type definitions, frontmatter fields |
|
||||
| `memdir/memoryScan.ts` | — | Scan .md files, exclude MEMORY.md, read frontmatter, max 200 files, sorted by mtime desc (`35-94`) |
|
||||
| `services/extractMemories/extractMemories.ts` | 615 | Forked agent extraction, restricted permissions, `skipTranscript: true`, `maxTurns: 5` (`371-427`) |
|
||||
| `services/autoDream/autoDream.ts` | 324 | Dream consolidation, four-layer gating (`63-66` defaults, `130-190` gating, `224-233` forked agent) |
|
||||
| `services/SessionMemory/sessionMemory.ts` | 495 | Session-level memory management |
|
||||
| `services/compact/sessionMemoryCompact.ts` | — | Session memory lightweight summary, thresholds 10K/5/40K (`56-61`) |
|
||||
| `utils/attachments.ts` | — | Injection budget: 200 lines / 4096 bytes per file, 60KB per session (`269-288`); find relevant memory by query (`2196-2241`) |
|
||||
| `query.ts` | — | Memory prefetch at start of each user turn (`301-304`), non-blocking collection (`1592-1614`) |
|
||||
| `query/stopHooks.ts` | — | Stop hook fire-and-forget triggers extraction and Dream (`141-155`) |
|
||||
|
||||
### Memory Selection: LLM, Not Embedding
|
||||
|
||||
CC uses **Sonnet itself to select** (`findRelevantMemories.ts`), not embedding vector similarity:
|
||||
|
||||
1. `memoryScan.ts` scans all `.md` files in `.memory/` (excluding MEMORY.md), max 200 files, sorted by mtime descending
|
||||
2. Lists all memory files' `name` + `description` as a catalog
|
||||
3. Sends to Sonnet side-query: "Select truly useful memories by name and description (max 5). Skip if unsure."
|
||||
4. Sonnet returns `{ selected_memories: ["file1.md", ...] }`
|
||||
5. Selected files' full contents are read (≤ 200 lines / 4096 bytes per file) and injected. Total session budget: 60KB
|
||||
|
||||
At the start of each user turn, `query.ts:301-304` starts memory prefetch (async); after tool execution, `1592-1614` collects completed results non-blocking.
|
||||
|
||||
### Extraction Timing: Stop Hook, Not After autoCompact
|
||||
|
||||
Trigger location (`stopHooks.ts:141-155`): inside `handleStopHooks()`, fire-and-forget triggers extraction and Dream. The teaching version places extraction in the `stop_reason != "tool_use"` branch, matching the direction.
|
||||
|
||||
CC's extraction runs via forked agent (`extractMemories.ts:371-427`): restricted permissions, `skipTranscript: true`, `maxTurns: 5`. Also has overlap protection: if the main Agent already wrote memory files, extraction is skipped.
|
||||
|
||||
### Memory File Format
|
||||
|
||||
CC uses Markdown + YAML frontmatter, consistent with the teaching version. Four types: `user`, `feedback`, `project`, `reference`.
|
||||
|
||||
`memdir.ts:34-38` defines index constraints: `MEMORY.md` max 200 lines / 25KB. `memdir.ts:199-266` builds memory behavior instructions, explicitly distinguishing memory from plan and tasks. Storage location: `~/.claude/projects/<sanitized-git-root>/memory/`.
|
||||
|
||||
### Dream: Four-Layer Gating
|
||||
|
||||
Not "triggered when idle" or "consolidate when count is enough", but four gates (`autoDream.ts`, defaults `63-66`, gating logic `130-190`):
|
||||
|
||||
1. **Time gate**: ≥ 24 hours since last consolidation
|
||||
2. **Scan throttle**: Avoid frequent filesystem scans
|
||||
3. **Session gate**: ≥ 5 session transcripts modified since last consolidation
|
||||
4. **Lock gate**: No other process currently consolidating (`.consolidate-lock` file)
|
||||
|
||||
The merge itself runs via forked agent (`224-233`): locate → collect recent signals → merge and write files → prune and update index. Lock file mtime serves as lastConsolidatedAt. Crash recovery: lock auto-expires after 1 hour.
|
||||
|
||||
### User Memory vs Session Memory
|
||||
|
||||
| | User Memory | Session Memory |
|
||||
|---|---|---|
|
||||
| Persistence | Cross-session | Single session |
|
||||
| Storage | Multiple .md files in `memory/` | `session-memory/<id>/memory.md` |
|
||||
| Loaded into | system prompt | compact summary |
|
||||
| Purpose | Cross-session knowledge accumulation | Cross-compact context continuity |
|
||||
|
||||
sessionMemoryCompact (mentioned in s08) uses Session Memory: before autoCompact, it reads the session memory file and, if sufficient (≥ 10K tokens, ≥ 5 text messages, ≤ 40K tokens, `sessionMemoryCompact.ts:56-61`), uses it as a summary without calling the LLM.
|
||||
|
||||
### Where the Real Implementation Is More Complex
|
||||
|
||||
- **Feature flags**: Memory features have multiple feature gate layers
|
||||
- **Team memory**: Shared team memories, `loadMemoryPrompt()` has a dedicated path (not covered in teaching version)
|
||||
- **KAIROS**: Timing-aware memory extraction strategy, daily-log mode in `loadMemoryPrompt()`
|
||||
- **Prompt cache**: Memory injection must account for prompt cache TTL, avoiding full system prompt rewrites each turn
|
||||
- **File locks**: Concurrency control for multi-process scenarios
|
||||
- **Memory prefetch**: Async prefetch, non-blocking main flow
|
||||
|
||||
### Teaching Version Simplifications Are Intentional
|
||||
|
||||
- LLM side-query → LLM side-query + keyword fallback: teaching version keeps LLM selection, adds fallback path
|
||||
- Memory JSON → Markdown + frontmatter: teaching version matches CC
|
||||
- Stop hook trigger → `stop_reason != "tool_use"` branch: same direction
|
||||
- Four-layer gating → file-count threshold: teaching version lacks transcript system and multi-session concepts
|
||||
- Forked agent + restricted permissions → direct call: teaching version has no subprocess isolation
|
||||
|
||||
</details>
|
||||
|
||||
<!-- translation-sync: zh@v1, en@v1, ja@v1 -->
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md)
|
||||
|
||||
s01 → ... → s07 → s08 → `s09` → [s10](../s10_system_prompt/) → s11 → ... → s20 → s21 → s22
|
||||
s01 → ... → s07 → s08 → `s09` → [s10](../s10_system_prompt/) → s11 → ... → s20 → s21
|
||||
> *"压缩会丢细节, 要有一层不丢的"* — 文件仓库 + 索引 + 按需加载,跨压缩、跨会话。
|
||||
>
|
||||
> **Harness 层**: 记忆 — 跨压缩、跨会话的知识积累。
|
||||
@@ -147,8 +147,6 @@ def consolidate_memories():
|
||||
# Replace all files with consolidated results
|
||||
```
|
||||
|
||||
CC 把这个过程叫 Dream,实际有四层门控:时间间隔、扫描节流、会话数、文件锁。教学版简化为文件数阈值。
|
||||
|
||||
### Memory 适合保存什么
|
||||
|
||||
Memory 保存跨会话仍然有用的信息:用户偏好、反复出现的反馈、项目背景、常用入口和排查线索。它关注“以后还会用到什么”,并通过索引 + 按需加载把这些信息带回当前对话。
|
||||
@@ -193,90 +191,5 @@ python s09_memory/code.py
|
||||
|
||||
s10 System Prompt → 分段 + 运行时组装。不同项目、不同工具,拼出不同的 prompt。
|
||||
|
||||
<details>
|
||||
<summary>深入 CC 源码</summary>
|
||||
|
||||
> 以下基于 CC 源码 `src/` 下 `memdir/`、`services/`、`utils/`、`query/` 的分析,行号已对照核实。
|
||||
|
||||
### 源码路径
|
||||
|
||||
| 文件 | 行数 | 职责 |
|
||||
|------|------|------|
|
||||
| `memdir/memdir.ts` | 507 | 核心:MEMORY.md 定义(`34-38`)、记忆行为指令区分 memory/plan/tasks(`199-266`)、`loadMemoryPrompt()` 三条路径(`419-490`) |
|
||||
| `memdir/findRelevantMemories.ts` | 141 | Sonnet side-query 选记忆(`18-24` 系统提示、`97-122` 调用逻辑) |
|
||||
| `memdir/memoryTypes.ts` | 271 | 类型定义,frontmatter 字段 |
|
||||
| `memdir/memoryScan.ts` | — | 扫描 .md 文件,排除 MEMORY.md,读 frontmatter,最多 200 个,按 mtime 降序(`35-94`) |
|
||||
| `services/extractMemories/extractMemories.ts` | 615 | forked agent 提取记忆,受限权限,`skipTranscript: true`,`maxTurns: 5`(`371-427`) |
|
||||
| `services/autoDream/autoDream.ts` | 324 | Dream 整理,四层门控(`63-66` 默认值、`130-190` 门控、`224-233` forked agent) |
|
||||
| `services/SessionMemory/sessionMemory.ts` | 495 | 会话级记忆管理 |
|
||||
| `services/compact/sessionMemoryCompact.ts` | — | session memory 轻量摘要,阈值 10K/5/40K(`56-61`) |
|
||||
| `utils/attachments.ts` | — | 注入预算:200 行 / 4096 字节每文件,60KB 每 session(`269-288`);按 query 找相关 memory(`2196-2241`) |
|
||||
| `query.ts` | — | memory prefetch 每轮启动(`301-304`),非阻塞收集(`1592-1614`) |
|
||||
| `query/stopHooks.ts` | — | stop hook fire-and-forget 触发提取和 Dream(`141-155`) |
|
||||
|
||||
### 记忆选择:LLM 选,不是 embedding
|
||||
|
||||
CC 用 **Sonnet 本身来选**(`findRelevantMemories.ts`),不是 embedding 向量相似度:
|
||||
|
||||
1. `memoryScan.ts` 扫描 `.memory/` 下所有 `.md` 文件(排除 MEMORY.md),最多 200 个,按 mtime 降序
|
||||
2. 把 `name` + `description` 列成清单
|
||||
3. 发给 Sonnet side-query:"根据名称和描述选出真正有用的记忆(最多 5 个)。不确定就不要选。"
|
||||
4. Sonnet 返回 `{ selected_memories: ["file1.md", ...] }`
|
||||
5. 选中文件读取完整内容(每文件 ≤ 200 行 / 4096 字节),注入上下文。单 session 总预算 60KB
|
||||
|
||||
每轮用户 turn 开始时,`query.ts:301-304` 启动 memory prefetch(异步);工具执行后 `1592-1614` 非阻塞收集结果,不卡主流程。
|
||||
|
||||
### 提取时机:stop hook,不是 autoCompact 后
|
||||
|
||||
触发位置(`stopHooks.ts:141-155`):在 `handleStopHooks()` 中,fire-and-forget 触发提取和 Dream。教学版把提取放在 `stop_reason != "tool_use"` 分支里,方向一致。
|
||||
|
||||
CC 的提取通过 forked agent 执行(`extractMemories.ts:371-427`):受限权限、`skipTranscript: true`、`maxTurns: 5`。还有重叠保护:如果主 Agent 已经写入了记忆文件,跳过提取。
|
||||
|
||||
### 记忆文件格式
|
||||
|
||||
CC 用 Markdown + YAML frontmatter,和教学版一致。四种类型:`user`、`feedback`、`project`、`reference`。
|
||||
|
||||
`memdir.ts:34-38` 定义索引约束:`MEMORY.md` 最多 200 行 / 25KB。`memdir.ts:199-266` 构建记忆行为指令,明确区分 memory、plan、tasks。存储位置:`~/.claude/projects/<sanitized-git-root>/memory/`。
|
||||
|
||||
### Dream:四层门控
|
||||
|
||||
不是"空闲时触发"或"数量够了就合并",而是四层门控(`autoDream.ts`,默认值 `63-66`,门控逻辑 `130-190`):
|
||||
|
||||
1. **时间门控**:距上次合并 ≥ 24 小时
|
||||
2. **扫描节流**:避免频繁扫描文件系统
|
||||
3. **会话门控**:自上次合并以来修改了 ≥ 5 个会话 transcript
|
||||
4. **锁门控**:没有其他进程正在合并(`.consolidate-lock` 文件)
|
||||
|
||||
合并本身通过 forked agent 执行(`224-233`):定位 → 收集近期信号 → 合并写文件 → 剪枝更新索引。锁文件 mtime 就是 lastConsolidatedAt。崩溃恢复:1 小时后锁自动过期。
|
||||
|
||||
### User Memory vs Session Memory
|
||||
|
||||
| | User Memory | Session Memory |
|
||||
|---|---|---|
|
||||
| 持久性 | 跨会话 | 单会话 |
|
||||
| 存储 | `memory/` 下多个 .md 文件 | `session-memory/<id>/memory.md` |
|
||||
| 加载到 | system prompt | compact 摘要 |
|
||||
| 用途 | 跨会话的知识积累 | 跨 compact 的上下文连续性 |
|
||||
|
||||
sessionMemoryCompact(s08 中提到的机制)正是使用了 Session Memory:autoCompact 前先读 session memory 文件,如果内容足够(≥ 10K token、≥ 5 条文本消息、≤ 40K token,`sessionMemoryCompact.ts:56-61`),就用它做摘要,不调 LLM。
|
||||
|
||||
### 真实实现比教学版复杂的地方
|
||||
|
||||
- **Feature flags**:记忆相关功能有多层 feature gate 控制
|
||||
- **Team memory**:团队共享记忆,`loadMemoryPrompt()` 有专门路径(教学版未涉及)
|
||||
- **KAIROS**:时机感知的记忆提取策略,`loadMemoryPrompt()` 中 daily-log 模式
|
||||
- **Prompt cache**:记忆注入需要考虑 prompt cache 的 TTL,避免每次都重写 system prompt 的大段内容
|
||||
- **文件锁**:多进程并发时的锁机制
|
||||
- **Memory prefetch**:异步预取,不阻塞主流程
|
||||
|
||||
### 教学版的简化是刻意的
|
||||
|
||||
- LLM side-query → LLM side-query + 关键词降级:教学版保留了 LLM 选择,加了降级路径
|
||||
- 记忆 JSON → Markdown + frontmatter:教学版与 CC 一致
|
||||
- stop hook 触发 → `stop_reason != "tool_use"` 分支:方向一致
|
||||
- 四层门控 → 文件数阈值:教学版没有 transcript 系统和多会话概念
|
||||
- forked agent + 受限权限 → 直接调用:教学版没有子进程隔离
|
||||
|
||||
</details>
|
||||
|
||||
<!-- translation-sync: zh@v1, en@v1, ja@v1 -->
|
||||
|
||||
Reference in New Issue
Block a user