feat: consolidate course into 21 lessons

This commit is contained in:
Haoran
2026-07-31 03:15:58 +08:00
parent 4bc33ec858
commit 2d69019342
200 changed files with 7338 additions and 10829 deletions

View File

@@ -2,7 +2,7 @@
[English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md)
s01 → ... → s12 → s13 → `s14` → [s15](../s15_agent_teams/) → s16 → ... → s20 → s21 → s22
s01 → ... → s12 → s13 → `s14` → [s15](../s15_agent_teams/) → s16 → ... → s20 → s21
> *"スケジュールに従って作業を生産、スケジューリングと実行を分離"* — cron スケジューリング、永続またはセッションレベル。
>
> **Harness 層**: スケジューリング — 独立スレッドが時刻を判定、キューがトリガーを配信。
@@ -21,7 +21,7 @@ s13 で Agent は遅い操作をバックグラウンドで実行できるよう
![Cron Scheduler Overview](images/cron-scheduler-overview.ja.svg)
教学版は S13 の簡易タスクシステム、バックグラウンド実行、プロンプト組み立てを踏襲。スケジューラに集中するため、完全なエラーリカバリ、メモリ、スキルシステムは省略。追加:独立した cron スケジューラスレッド、1 秒ごとにポーリング、時間が来たらタスク`cron_queue`投入し、queue processor が Agent のアイドル時に自動配信。
この章では独立した cron スケジューラスレッドを追加する。1 秒ごとに確認し、期限に達したジョブ`cron_queue`書き込み、queue processor が Agent のアイドル時に自動配信する
手動 vs スケジュール:
@@ -45,8 +45,6 @@ cron スケジューリングは 4 層に分かれる:
3. **Queue Processor**:キューが空でなく Agent がアイドルなら、一回の agent_loop を開始
4. **Consumer**agent_loop がキューから消費、messages に注入
教学版は最小の queue processor を実装する。`agent_lock` で Agent がアイドルかを判定し、キューに入った cron 作業を自動配信する。実際の CC の `useQueueProcessor.ts` はさらに UI ブロック、キュープライオリティ、メッセージモードを扱う。
### CronJob: データ構造
各 cron タスクは `CronJob` オブジェクト:
@@ -253,53 +251,5 @@ python s14_cron_scheduler/code.py
s15 Agent Teams → 一人の Agent では足りない、チームを組もう。永続的なチームメイト + 非同期受信箱。
<details>
<summary>CC ソースコード深掘り</summary>
> 以下は CC ソースコード `CronCreateTool.ts`、`cronScheduler.ts`、`cron.ts`、`cronTasks.ts`、`cronTasksLock.ts`、`useScheduledTasks.ts`139 行)の完全分析に基づく。
### 一、3 つの Cron ツール
CC はモデルに 3 つの cron ツールを公開:`CronCreate``CronDelete``CronList`。すべてコンパイル時ゲート `feature('AGENT_TRIGGERS')` とランタイム GrowthBook フラグ `tengu_kairos_cron` で制御。`CLAUDE_CODE_DISABLE_CRON` 環境変数でローカル上書きも可能。
### 二、ストレージ:`.claude/scheduled_tasks.json`
```json
{ "tasks": [{ "id": "abc12345", "cron": "0 9 * * *", "prompt": "...", "recurring": true, "durable": true, "createdAt": 1714567890000 }] }
```
durable タスクはディスクに書き込み。session-only タスクは `STATE.sessionCronTasks` メモリ配列に格納(プロセス再起動で消失)。`.scheduled_tasks.lock` ファイルで同じプロジェクトの複数セッション間の重複発火を防止。
### 三、スケジューラ1 秒ポーリング
`cronScheduler.ts` は毎秒チェック(`CHECK_INTERVAL_MS = 1000`)。ロックを保持しているセッションがファイルタスクをトリガー。すべてのセッションが session-only タスクをトリガー。`chokidar` ファイルウォッチャーが `scheduled_tasks.json` の変更を監視。
### 四、cron 式:標準 5 フィールド
分 時 日 月 曜日。`*``*/N``N``N-M``N-M/S``N,M,...` をサポート。`L``W``?` は非サポート。すべての時間はローカルタイムゾーンで解釈。day-of-month と day-of-week が両方制約されている場合は OR セマンティクス。
### 五、ジッター(サンダリングハード防止)
- 定期タスク:トリガー遅延は期間の最大 10%(上限 15 分)、タスク ID ベースの決定的ハッシュ
- 一回限りタスク:発火時刻が `:00` または `:30` の場合、最大 90 秒早く発火
- ジッター設定は GrowthBook でリアルタイム調整可能、60 秒ごとにリフレッシュ
### 六、自動期限切れ
定期タスクは 7 日後に自動期限切れ(設定可能、上限 30 日)。期限切れ前に最後の一回を発火、その後自動削除。
### 七、ジョブ数上限
`MAX_JOBS = 50``CronCreateTool.ts:25`)。超過時はエラーを返す:"Too many scheduled jobs (max 50). Cancel one first."
### 八、トリガー注入
発火後、`enqueuePendingNotification()``priority: 'later'` としてコマンドキューにエンキュー。`workload: WORKLOAD_CRON` タグ付き、API は容量が逼迫している時に cron 発信リクエストを低い QoS で処理。
### 九、Queue Processor自動配信
実際の CC は `useQueueProcessor.ts:48-60` により、アクティブな query がなく、UI がブロックされておらず、キューが空でない場合に自動的に処理をトリガーする。`queueProcessor.ts:52-87` がキュープライオリティに従ってコマンドを `handlePromptSubmit()` にディスパッチ。教学版は `queue_processor_loop` で核心動作を保つ:キューに作業があり Agent がアイドルなら、自動的に一回の agent_loop を開始する。
</details>
<!-- translation-sync: zh@v1, en@v1, ja@v1 -->

View File

@@ -2,7 +2,7 @@
[English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md)
s01 → ... → s12 → s13 → `s14` → [s15](../s15_agent_teams/) → s16 → ... → s20 → s21 → s22
s01 → ... → s12 → s13 → `s14` → [s15](../s15_agent_teams/) → s16 → ... → s20 → s21
> *"Produce work on a schedule, decouple scheduling from execution"* — Cron scheduling, durable or session-level.
>
> **Harness Layer**: Scheduling — Independent thread checks time, queue delivers triggers.
@@ -21,7 +21,7 @@ s13 lets the agent run slow operations in the background, but every operation is
![Cron Scheduler Overview](images/cron-scheduler-overview.en.svg)
Teaching code carries forward S13's simplified task system, background execution, and prompt assembly; to stay focused on the scheduler, it omits full error recovery, memory, and skill systems. Added: an independent cron scheduler thread that polls every second, queues matching jobs into `cron_queue`, and a queue processor that delivers them when the agent is idle.
This chapter adds an independent cron scheduler thread: it checks once per second, writes due jobs to `cron_queue`, and a queue processor delivers them when the agent is idle.
Manual vs Scheduled:
@@ -45,8 +45,6 @@ Cron scheduling has four layers:
3. **Queue Processor**: sees non-empty queue and idle agent, starts one agent_loop turn
4. **Consumer**: agent_loop consumes queue and injects into messages
The teaching version implements a minimal queue processor: `agent_lock` tells whether the agent is idle, and queued cron work is delivered automatically. Real CC's `useQueueProcessor.ts` also handles UI blocking, queue priority, and different message modes.
### CronJob: Data Structure
Each cron task is a `CronJob` object:
@@ -253,53 +251,5 @@ One agent can do a lot now: plan, compress, background, schedule. But some tasks
s15 Agent Teams → One agent isn't enough, form a team. Persistent teammates + async inboxes.
<details>
<summary>Deep Dive into CC Source</summary>
> The following is a complete analysis based on CC source code `CronCreateTool.ts`, `cronScheduler.ts`, `cron.ts`, `cronTasks.ts`, `cronTasksLock.ts`, `useScheduledTasks.ts` (139 lines).
### 1. Three Cron Tools
CC exposes three cron tools to the model: `CronCreate`, `CronDelete`, `CronList`. All controlled by compile-time gate `feature('AGENT_TRIGGERS')` and runtime GrowthBook flag `tengu_kairos_cron`. There's also a `CLAUDE_CODE_DISABLE_CRON` env var for local override.
### 2. Storage: `.claude/scheduled_tasks.json`
```json
{ "tasks": [{ "id": "abc12345", "cron": "0 9 * * *", "prompt": "...", "recurring": true, "durable": true, "createdAt": 1714567890000 }] }
```
Durable tasks write to disk; session-only tasks live in `STATE.sessionCronTasks` memory array (lost on process restart). A `.scheduled_tasks.lock` file prevents duplicate firing across multiple sessions of the same project.
### 3. Scheduler: 1-Second Polling
`cronScheduler.ts` checks every second (`CHECK_INTERVAL_MS = 1000`). Whoever holds the lock triggers file tasks; all sessions trigger session-only tasks. A `chokidar` file watcher monitors `scheduled_tasks.json` changes.
### 4. Cron Expression: Standard 5 Fields
Minute hour day month weekday. Supports `*`, `*/N`, `N`, `N-M`, `N-M/S`, `N,M,...`. Doesn't support `L`, `W`, `?`. All times interpreted in local timezone. Day-of-month and day-of-week use OR semantics when both are constrained.
### 5. Jitter (Thundering Herd Prevention)
- Recurring tasks: trigger delay up to 10% of period (max 15 min), deterministic hash based on task ID
- One-shot tasks: up to 90s early when firing time falls on `:00` or `:30`
- Jitter config adjustable via GrowthBook, refreshed every 60 seconds
### 6. Auto-Expiration
Recurring tasks auto-expire after 7 days (configurable, max 30 days). Fire one last time before expiry, then auto-delete.
### 7. Job Limit
`MAX_JOBS = 50` (`CronCreateTool.ts:25`). Returns error when exceeded: "Too many scheduled jobs (max 50). Cancel one first."
### 8. Trigger Injection
After firing, enqueued via `enqueuePendingNotification()` with `priority: 'later'` into the command queue. Tagged `workload: WORKLOAD_CRON` — API serves cron-initiated requests at lower QoS when capacity is tight.
### 9. Queue Processor: Automatic Delivery
Real CC auto-triggers processing through `useQueueProcessor.ts:48-60` when no query is active, UI isn't blocked, and queue is non-empty. `queueProcessor.ts:52-87` dispatches commands to `handlePromptSubmit()` by queue priority. The teaching version keeps the core behavior with `queue_processor_loop`: when queued work exists and the agent is idle, it starts one agent_loop turn automatically.
</details>
<!-- translation-sync: zh@v1, en@v1, ja@v1 -->

View File

@@ -2,7 +2,7 @@
[English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md)
s01 → ... → s12 → s13 → `s14` → [s15](../s15_agent_teams/) → s16 → ... → s20 → s21 → s22
s01 → ... → s12 → s13 → `s14` → [s15](../s15_agent_teams/) → s16 → ... → s20 → s21
> *"按时间表生产工作, 调度与执行解耦"* — cron 调度, 持久化或会话级。
>
> **Harness 层**: 调度 — 独立线程判断时间, 队列传递触发。
@@ -21,7 +21,7 @@ s13 让 Agent 能后台执行慢操作,但所有操作仍然是你手动触发
![Cron Scheduler Overview](images/cron-scheduler-overview.svg)
教学代码沿用 S13 的简化任务系统、后台执行和 prompt 组装;为了聚焦调度器,省略完整错误恢复、记忆和技能系统。新增独立的 cron 调度线程每秒检查一次,时间到了把任务塞进 `cron_queue`再由 queue processor 在 Agent 空闲时自动交付。
本章新增独立的 cron 调度线程每秒检查一次,把到期任务写入 `cron_queue`再由 queue processor 在 Agent 空闲时自动交付。
手动 vs 定时:
@@ -45,8 +45,6 @@ Cron 调度分四层:
3. **Queue Processor**:发现队列非空且 Agent 空闲,启动一轮 agent_loop
4. **Consumer**agent_loop 从队列消费,注入到 messages
教学版实现的是最小 queue processor`agent_lock` 判断 Agent 是否空闲,空闲时自动交付定时任务。真实 CC 的 `useQueueProcessor.ts` 还会处理 UI 阻塞、队列优先级和不同消息模式。
### CronJob: 数据结构
每个 cron 任务是一个 `CronJob` 对象:
@@ -253,53 +251,5 @@ python s14_cron_scheduler/code.py
s15 Agent Teams → 一个 Agent 不够,组队吧。持久队友 + 异步收件箱。
<details>
<summary>深入 CC 源码</summary>
> 以下基于 CC 源码 `CronCreateTool.ts`、`cronScheduler.ts`、`cron.ts`、`cronTasks.ts`、`cronTasksLock.ts`、`useScheduledTasks.ts`139 行)的完整分析。
### 一、三个 Cron 工具
CC 暴露了三个 cron 工具给模型:`CronCreate``CronDelete``CronList`。全部由编译时门控 `feature('AGENT_TRIGGERS')` 和运行时 GrowthBook 标志 `tengu_kairos_cron` 控制。还有一个 `CLAUDE_CODE_DISABLE_CRON` 环境变量做本地覆盖。
### 二、存储:`.claude/scheduled_tasks.json`
```json
{ "tasks": [{ "id": "abc12345", "cron": "0 9 * * *", "prompt": "...", "recurring": true, "durable": true, "createdAt": 1714567890000 }] }
```
Durable 任务写磁盘session-only 任务存于 `STATE.sessionCronTasks` 内存数组(进程重启丢失)。还有一个 `.scheduled_tasks.lock` 文件防止同项目的多个 session 重复触发。
### 三、调度器1 秒轮询
`cronScheduler.ts` 每秒检查一次(`CHECK_INTERVAL_MS = 1000`)。谁持有锁谁触发文件任务;所有 session 都触发仅 session 任务。还有一个 `chokidar` 文件观察者监视 `scheduled_tasks.json` 变更。
### 四、Cron 表达式:标准 5 字段
分钟 小时 日 月 星期。支持 `*``*/N``N``N-M``N-M/S``N,M,...`。不支持 `L``W``?`。所有时间以本地时区解释。Day-of-month 和 day-of-week 同时约束时用 OR 语义。
### 五、抖动(防惊群效应)
- 重复性任务:触发延迟最多可达期间的 10%(上限 15 分钟),基于任务 ID 的确定性哈希
- 一次性任务:当触发时间落在 `:00``:30` 时,最多提前 90 秒触发
- 抖动配置可通过 GrowthBook 实时调整60 秒刷新一次
### 六、自动过期
重复性任务 7 天后自动过期(可配置,上限 30 天)。过期前最后一次触发,触发后自动删除。
### 七、作业数上限
`MAX_JOBS = 50``CronCreateTool.ts:25`)。超限时返回错误:"Too many scheduled jobs (max 50). Cancel one first."
### 八、触发注入
触发后通过 `enqueuePendingNotification()``priority: 'later'` 入队命令队列。标记 `workload: WORKLOAD_CRON`API 在容量紧张时以更低的 QoS 为 cron 发起的请求服务。
### 九、Queue Processor自动交付
真实 CC 通过 `useQueueProcessor.ts:48-60` 在无 query、无阻塞 UI、队列非空时自动触发处理。`queueProcessor.ts:52-87` 按队列优先级把命令交给 `handlePromptSubmit()`。教学版用 `queue_processor_loop` 保留核心行为:队列有任务且 Agent 空闲时,自动启动一轮 agent_loop。
</details>
<!-- translation-sync: zh@v1, en@v1, ja@v1 -->

View File

@@ -678,8 +678,8 @@ def update_context(context: dict, messages: list) -> dict:
}
# ── Agent Loop (simplified, focused on cron scheduler) ──
# Teaching code keeps a basic agent loop. S11's full error recovery is omitted.
# ── Agent Loop (focused on cron scheduling) ──
# Error recovery remains the independent layer introduced in s11.
# cron_scheduler_loop produces work; queue_processor_loop wakes this loop when
# queued work exists and no other agent turn is running.