核心内容摘要
探索“做受4777cos”的魅力:不止于角色扮演的深度体验
❝该系列文章基于github.com/shareAI-lab/learn-claude-code写就该仓库以大道至简的风格剖析了Claude Code的核心原理值得大家学习。
由于该仓库是基于Python语言为方便.NET开发者学习我已经将代码基于.NET 10的dotnet file重写源码已上传至github源码地址见文末。
v2: 用 Todo 实现自我约束❝本文是 Learn Claude Code (C# 版) 系列的
对应代码文件v2_todo_agent.cs。
问题上下文衰减v1 对简单任务很好用。
但试试这个You: 重构 auth 模块、添加单元测试、更新 API 文档观察模型的行为开始重构 auth...突然想起要写测试切换过去...写了一半测试想起还没看完 auth 代码...10 次工具调用后等等我在干什么来着这就是上下文衰减——计划只存在于模型的脑海中随着对话变长逐渐模糊。
解决方案让计划显式化v2 添加一个新工具TodoWrite从根本上改变工作方式Before (v
:模型内部我先做 A然后 B然后 C (不可见) 10 次工具调用后计划已模糊After (v
:[ ] 重构 auth 模块 [] 添加单元测试 - 当前正在做这个 [ ] 更新 API 文档 (1/3 completed)现在你和模型都能看到计划。
模型可以随时查看进度一次只做一件事完成后更新状态TodoManager 设计核心数据结构record TodoItem(string Content, string Status, string ActiveForm); class TodoManager { private ListTodoItem _items []; // Content: 任务描述如 添加单元测试 // Status: pending | in_progress | completed // ActiveForm: 现在进行时如 正在编写测试用例... }ActiveForm是个精妙的设计——当任务在进行中时显示模型正在做什么[] 添加单元测试 - 正在编写 AuthService 的测试用例...约束即护栏public string Update(JsonElement itemsJson) { // ...验证逻辑... if (validated.Count
throw new InvalidOperationException(Max 20 todos allowed); if (inProgressCount
throw new InvalidOperationException(Only one task can be in_progress); }约束原因最多 20 项防止无限任务列表一个 in_progress强制一次只做一件事必填 activeForm确保可见性这些不是限制是护栏——它们让复杂任务成为可能。
渲染输出public string Render() { // [x] Completed task // [] In progress task - Doing something... // [ ] Pending task // // (2/3 completed) }模型看到这个渲染结果就能理解当前状态。
TodoWrite 工具定义new Tool { Name TodoWrite, Description 更新任务列表。
用于规划和追踪进度。
, InputSchema new InputSchema { Type object, Properties new Dictionarystring, JsonElement { [items] JsonDocument.Parse( { type: array, items: { type: object, properties: { content: {type: string}, status: {type: string, enum: [pending, in_progress, completed]}, activeForm: {type: string} }, required: [content, status, activeForm] } } ).RootElement }, Required [items] } }注意模型每次发送完整列表不是增量更新。
这简化了状态管理。
软提示机制强制要求模型用 Todo 会很烦人。
v2 用软提示来引导初始提醒const string INITIAL_REMINDER reminder对于多步骤任务请使用 TodoWrite。
/reminder; // 在第一条用户消息前注入 if (firstMessage) { content.Add(ContentBlock.CreateText(INITIAL_REMINDER)); firstMessage false; }持续提醒int roundsWithoutTodo 0; const string NAG_REMINDER reminder10 轮未更新 todo。
请更新 todos。
/reminder; // 在 Agent 循环中 if (usedTodo) roundsWithoutTodo 0; else roundsWithoutTodo; if (roundsWithoutTodo
results.Insert(0, ContentBlock.CreateText(NAG_REMINDER));这是软约束——不强制但引导。
模型仍然可以选择不用 Todo但会收到温和的提醒。
实际工作流程You: 重构 auth 模块、添加测试、更新文档 reminder对于多步骤任务请使用 TodoWrite。
/reminder 好的我来规划这个多步骤任务。
TodoWrite [ ] 重构 auth 模块 [ ] 添加单元测试 [ ] 更新 API 文档 (0/3 completed) 首先标记第一个任务为进行中 TodoWrite [] 重构 auth 模块 - 正在分析现有代码结构... [ ] 添加单元测试 [ ] 更新 API 文档 (0/3 completed) 让我先看看 auth 模块的代码 read_file: {path:src/Auth/AuthService.cs} ... [分析后进行重构] edit_file: {...} Edited src/Auth/AuthService.cs 重构完成更新 todo TodoWrite [x] 重构 auth 模块 [] 添加单元测试 - 正在为 AuthService 编写测试... [ ] 更新 API 文档 (1/3 completed) ...继续下一个任务...深层洞察约束既限制又赋能这个模式在 Agent 设计中反复出现约束赋能max_tokens 限制可管理的响应工具 schema 限制结构化调用Todo 约束复杂任务追踪好的约束不是限制是脚手架。
外部化记忆TodoManager 本质上是把模型的工作记忆外部化内部记忆模糊、会衰减外部记忆Todo精确、持久这是一种认知卸载——让模型专注于当前任务不用担心忘记整体计划。
状态机视角每个 TodoItem 是一个简单状态机pending - in_progress - completed只能一个 in_progress 的约束确保了线性执行——这对于 LLM 来说是最容易处理的模式。
运行示例Mini Claude Code v2 (with Todos) - /path/to/project 输入 exit 退出。
You: 创建一个 REST API 项目添加用户管理、产品管理、订单管理 好的这是一个多步骤任务我来规划 TodoWrite [ ] 创建项目结构 [ ] 实现用户管理 API [ ] 实现产品管理 API [ ] 实现订单管理 API (0/4 completed) 开始第一个任务 TodoWrite [] 创建项目结构 - 正在初始化 ASP.NET Core 项目... [ ] 实现用户管理 API [ ] 实现产品管理 API [ ] 实现订单管理 API (0/4 completed) bash: {command:dotnet new webapi -n MyApi} The template ASP.NET Core Web API was created successfully. ...从 v2 到 v3v2 解决了单个 Agent 的规划问题。
但对于大型任务You: 探索整个代码库然后重构 auth 模块问题探索阶段产生大量输出cat20 个文件这些细节填满了上下文真正重构时关键信息已经被挤出去了这就是上下文污染。
v3 将引入子代理——通过上下文隔离来解决这个问题。
总结v2 的哲学❝让计划显式化。
约束赋能复杂性。
一个简单的 TodoManager 一个 TodoWrite 工具就让 Agent 能够处理多步骤任务。
这是外部化认知的典型应用。
点击阅读原文获取仓库地址