超详总结:从零搓出一个ClaudeCode
2026-02-17 00:25:28 · chineseheadlinenews.com · 来源: Datawhale公众号
一、为什么我要自己做一个 Code Agent
这两年 AI 编程助手火得一塌糊涂。
Claude Code、GitHub Copilot、Cursor、Codex……工具一个比一个强。用自然语言描述需求,它就能写代码、改 Bug、跑测试,甚至帮你排查那些以前要绞尽脑汁的线上问题。
有意思的是,Anthropic、OpenAI 这些前沿团队也在持续公开他们的 Agent 构建经验。虽然他们的模型在国内有门槛,但 Engineering Blog 我一直在追。每次读完都很上头——你会发现,真正拉开差距的不是"提示词写得多花",而是工程设计是否扎实。
看了这么多,手痒了。
正好,Datawhale 的 Hello-Agent 教程最后有一个毕业设计:用学到的知识,做一个自己的智能体应用。
我当时就想,既然日常高强度在用各种 Code Agent,不如就做一个自己的。
说白了,自己手搓一遍,才能真正理解这些产品为什么好用,以及它们到底在工程上做对了什么。

二、先跑起来!用 Hello-Agent 骨架搭出第一个能用的 Code Agent
有了方向,我没急着追什么"最优架构"。
先给自己定了一个很接地气的目标:用户说一句需求,Agent 能自己去仓库里找证据,给出改动方案,输出补丁,我确认后能真正落盘。
说白了,我要的不是一个会聊天的 Demo,而是一个能干活的 CLI。
Hello-Agent 的底子正好够用——ReActAgent、ToolRegistry、ContextBuilder 这些核心组件都是现成的。我的策略很简单:先复用,再改造。
最初版本的Code Agent代码仓库:
https://github.com/YYHDBL/HelloCodeAgentCli.git
1、起手式:先复用,再改造
我的动作很克制——直接复用 Hello-Agent 的主干,把最短链路先跑通。
核心组件就这几块:


为啥?工具输出一旦太长,下一步提示词就会变脏,模型很容易跑偏。这套配置后来肯定不够,但 V0 阶段,它让问题可复现、可调试。
3、单轮流程:土,但管用
我当时最担心:每轮都走完整流程会不会太慢、太贵、太容易失控?

路径必须在 repo_root 内,防逃逸;
临时文件 + 原子写入,不半写;
自动备份,能撤回;
限制单次改动规模;
解析失败直接中断,不瞎猜。
这让 V0 至少有个底线:改动是可追、可控、可撤回的。
5、兴奋和坑,一起来了
V0 刚跑起来那几天,确实挺爽。
"看结构 → 搜代码 → 给补丁 → 落盘"这条链路能通,而且通得挺顺。我看着它准确的分析了我的需求,使用Todo工具拆分任务,并开始行动的时候,感觉这玩意儿真的能干活。

但任务强度一拉高,诸多问题很快冒头:
终端命令越来越长,失败时只能看到最后报错,根本不知道哪步挂了;
ReAct 靠字符串解析,模型偶尔多说一句、少个标记,就解析失败;
长任务里上下文开始"变脏",噪声越来越多;
工具返回都是字符串,后续处理很难做强约束。
等等.....
这时候我才真正意识到:
V0 的价值不是"它已经很好",而是"它把问题暴露得足够早"。
没有这个能跑通的版本,后面的重构可能就是拍脑袋。有了它,我能拿着具体代码和复现场景去改,而不是靠感觉。
而第一个真正把我打醒的坑,就是 Terminal Tool。
三、自由是把双刃剑:我的 Terminal Tool 是怎么失控的
V0 刚跑起来那会儿,我最自豪的其实是 Terminal Tool。
因为它几乎等于把"人能在终端里做的事"直接交给了模型。我当时甚至觉得——只要白名单、沙盒、危险命令确认做好,模型就能像资深工程师一样操作仓库。
结果很快被现实教育了。
1、我的设计:放开自由度,效率优先

第一眼看,这就是老工程师常用的组合拳。但实际执行时,经常出现这些情况:
rg 搜出来太多,grep 过滤后什么都没剩
rg 因为权限或编码问题直接失败,管道输入是空的
sed 收到空输入,输出也是空的
最终模型看到"空结果",但它根本不知道哪一步出了问题
最坑的是:一条命令完成多步,错误被"压扁"了。
模型只能看到最终结果,看不到中间哪个环节挂了。它也没法修正策略,只能"重新拍一条命令赌运气"。
3、安全策略:越补越长的补丁战
我原以为白名单 + 沙盒 + 确认机制够安全了。但 shell 太灵活,管道、重定向、子命令全是"可绕过点"。







4、改造三件套:Schema → tool_calls → tool_call_id
Schema:参数被强约束
每个 Tool 的参数自动转成 JSON Schema,模型只能在 schema 里填值,而不是自由拼字符串。
tool_calls:模型输出变结构化
不再解析 Action 字符串,直接抽取 tool_calls。把"文本解析"变成"结构读取"。

每一次工具调用都能精确对应结果,链路不会再断。
回过头看,旧版为了"能跑"写的大量容错补丁,现在都被协议层替代了。ReAct 的稳定性不是靠"写更严的提示词",而是靠"让模型说协议话"——标准格式天然可控,省去无数补丁。
调用协议稳定之后,新的问题又冒出来了——长对话一多,模型开始"变笨"。上下文工程,成了下一个要解决的大问题。
六、长对话的困境:我的上下文工程改造
调用协议稳定之后,问题很快转移到了另一块:长对话一多,模型开始"变笨"。
症状挺明显的——明明刚确认过的约束,过几轮就忘;会话越长,越容易用错工具;工具输出堆成山,最终答案越来越水。
这其实就是业界讨论最多的上下文腐烂问题,在看了Manus、Anthropic、Langchain等分享的关于上下文工程的博文之后,我总结出了以下几点:上下文隔离+上下文卸载+上下文压缩。
上下文隔离就是主 Agent 将复杂任务拆分为子任务,派发给专属子 Agent 处理,每个子 Agent 拥有独立的上下文窗口,实现 “关注点分离。
上下文卸载借鉴虚拟内存思想,将大模型中非活跃、大体积、低价值的上下文数据从显存 / 核心内存迁移至磁盘 / SSD 等低速存储,仅保留轻量引用,供模型按需调取。在Code Agent中卸载掉内容便是工具的返回结果了。
上下文压缩是在不损失关键语义的前提下,通过算法剔除冗余信息、精简数据量,降低 Token 消耗和内存占用的技术,分为无损压缩(仅剔除无意义符号 / 连接词)和有损压缩(剔除低价值信息,保留核心语义,大模型场景主流),核心目标是提升上下文的信息密度。
我的改造思路是:从堆消息到分层治理,从工具输出堆积到统一截断,从无限历史到可控压缩。
1、先把上下文分层:L1 / L2 / L3 的稳定结构
参考上下文工程的分层思路,我把上下文拆成三层:
拼接顺序固定:L1 → L2 → L3 → 当前 user → Todo recap
L1/L2 稳定,L3 才能稳定,模型需要知道什么是永远不变的规则。
2、统一截断:Observation 进历史前必须"瘦身"
上下文膨胀的最大来源,不是用户说的话,而是工具输出。
一次 Grep / Read 打出来几千行,如果不截断,历史很快就被"证据垃圾"淹没。
为什么需要"统一"截断?
最初我给每个工具设计了特化的压缩策略——Read 怎么截、Grep 怎么截、LS 怎么截,各自有各自的逻辑。结果维护成本极高,新增一个工具就要重新设计一套规则,还容易遗漏。
后来我参考了 Opencode 的做法,决定完全替换为统一截断机制:
不再为每个工具设计特化压缩
所有工具输出使用同一套截断规则
完整输出落盘保存,随时可回溯

模型看到 partial 状态,就知道内容被截断了。如果它发现关键信息可能在被截掉的部分,会收到明确的提示去读取完整文件。


“保留完整轮次”非常关键:一轮必须从 user 发起到 assistant 完成,中间的工具调用链不能拆。这是保证 Agent 行为连贯性的底线。
4、Summary 归档:旧历史压缩成"记忆卡片"
压缩不是删除,而是归档。我用 Summary 把旧历史提炼成关键信息,让模型既能"看到过去",又不被"过去淹没"。
Summary 的核心定位
Summary 只用于旧历史归档,不包含当前任务进度。
这是个关键区分:
Todo Recap:告诉模型"现在正在做什么"(当前进度)
Summary:告诉模型"之前做过什么"(历史归档)
HistoryManager 把 Summary 作为 role=summary 的消息存入 L3,序列化时变成 system message 注入上下文。最重要的是:Summary 永远不再压缩——它是"旧历史的档案",一旦生成就是只读的"记忆卡片"。
Summary 生成机制
触发时机:当历史消息超过 token 阈值(默认 0.8 × context_window)时触发压缩。
生成方式:调用新的模型会话(可配置模型)来生成 Summary,输入是待压缩的历史消息 + 专用的 SUMMARY_PROMPT。
超时与降级:生成过程同步阻塞,用户会看到压缩进度提示。如果超过 120 秒还没生成完,就跳过 Summary 生成,仅保留最近 N 轮历史,并提示用户:"Summary generation timed out, keeping recent history only."
固定模板结构

这个模板的妙处在于:不同层次的信息分开存放,模型能快速定位需要的内容。想查改了哪些文件?看 File System State。想查当时为什么选这个方案?看 Key Insights & Decisions。
一个实际的 Summary 例子
假设用户让 Agent 实现一个登录功能,中间经过了多轮调试和重构,历史膨胀到需要压缩。生成的 Summary 可能是:

当这个 Summary 被注入上下文后,模型即使忘记了中间具体的调试过程,也能知道:"哦,登录功能已经做完了,用了 JWT,数据库 schema 也定好了,现在应该在搞其他模块。"
为什么 Summary 不再压缩?
这是个关键设计决策。
如果 Summary 还能被压缩,那就会出现"Summary 的 Summary",信息会层层失真,最后变成一堆没有上下文的碎片。
Summary 是压缩的终点。 它像是一本相册——你把几百张照片(历史消息)精选成一本相册(Summary),以后翻这本相册就够了,不需要再压缩相册本身。
这也解释了为什么 Summary 模板要固定结构:只有结构固定,才能在一次读取中高效提取信息,而不需要反复翻找。
与 Todo Recap 的配合

上下文里只留下"提醒",而不是"垃圾"。
这一轮改造的效果很明显:工具输出不会无限堆积,历史能在阈值时自动收敛,Summary 把旧历史压成"稳定记忆",@file 不再制造垃圾上下文。上下文不是塞得越多越好,而是要治理得清晰、可追溯。
但治理好上下文,还有一个更大的痛点——Agent 出错时,我完全不知道它经历了什么。可观测性,成了下一个坎。
七、把黑盒拆开:可观测性、日志与会话回放
工具、协议和上下文都稳定之后,我才真正遇到一个硬伤:Agent 出错时,我无法还原"它到底做了什么"。
有一次模型连续失败 3 步,最后干脆自己放弃了。我翻控制台日志,只看到一句:tool failed
没有完整参数、没有前后文、也看不到之前几步的决策链。我只能瞎猜:路径写错了?权限不够?还是工具本身有 bug?
那一刻我才意识到:没有审计轨迹的 Agent,就像没有行车记录仪的自动驾驶——出事了你只能干瞪眼。
于是我补上了可观测性这一层:Trace 轨迹 + 会话快照。
1、TraceLogger:会话级审计轨迹
我不再用"散乱的运行日志",而是做了一个会话级轨迹记录器:TraceLogger。
它只做一件事:把一次会话的每一步,按顺序完整记下来。
双格式输出:机器可读 + 人类可读
TraceLogger 同时输出两费棠件,放在 memory/traces/ 目录下:
JSONL 格式(面向机器处理):
路径:memory/traces/trace-s-20260103-201533-a3f2.jsonl
每一步一个 JSON 对象,便于流式追加与后处理
可以写脚本批量分析、统计 token 用量、检测异常模式

HTML 格式(面向人类审计):
路径:memory/traces/trace-s-20260103-201533-a3f2.html
可直接用浏览器打开,可视化展示每一步
支持点击展开/折叠,像在"逐帧回放"
文件名中的 s-20260103-201533-a3f2 是会话唯一标识(s-YYYYMMDD-HHMMSS-随机4位),方便按时间检索。
统一事件结构
所有事件都遵循统一结构:

字段说明:
ts:ISO8601 时间戳,精确到毫秒
session_id:会话唯一标识
step:ReAct 循环的 step 序号
event:事件类型
payload:事件数据体
关键事件类型
我定义了以下关键事件类型,覆盖 Agent 运行的完整生命周期:

有了统一结构,问题就不再是"有没有日志",而是"你想看哪一步"。
2、关键证据链:每一步都打点
Trace 的核心价值是"证据链"——每一步都有迹可循,调用和结果能精确对应。
tool_call_id:调用与结果的强绑定
在 Function Calling 架构下,每个 tool_call 都有唯一 ID。TraceLogger 用这个 ID 把"调用"和"结果"串成一条链:

在 HTML 可视化中,这两个事件会被渲染成一对可折叠的卡片,一眼就能看出调用和结果的对应关系。
model_output:记录 Token 用量
每次模型输出,Trace 都会记录 usage 信息:

这帮我解决了一个老大难问题:"为什么突然变慢 / 为什么 token 暴涨?"
打开 Trace 一看,就能定位到哪一步的上下文突然膨胀了。
3、HTML 可视化:把轨迹变成"可读回放"
JSONL 适合程序分析,但人类复盘需要"看得懂"。TraceLogger 会同步生成一份 HTML,可直接用浏览器打开。
HTML 界面结构
点开每一步,就能看到完整的 input / output / token / 截断提示,像在逐帧回放。
脱敏保护
生产环境中,Trace 可能包含敏感信息(API Key、Token、文件路径)。TraceSanitizer 默认开启(TRACE_SANITIZE=true):
API Key:sk-*** / Bearer ***
敏感字段:api_key、token、session_id、tool_call_id
路径脱敏:/Users/yyhdbl/... → /Users/***/...
排查问题够用,但不会把敏感信息原样写盘。
4、一个真实复盘案例:Trace 怎么救了我
还记得那次“编辑后结果不生效”的问题吗?
当时 Agent Read 完就去 Edit,但 Edit 一直失败,我在控制台只看到 tool failed,根本不知道原因。
后来我用 Trace 复盘,打开 HTML 一看:

Step 4- model_output:
模型没理解冲突原因,继续用旧的 mtime 重试……
这时我才明白:不是 Edit 工具出 bug,而是文件在 Read 后被格式化/自动保存改过了。
有了这条证据链,我在提示词里加了“遇到 CONFLICT 必须重新 Read”这一条,问题立刻消失。
这就是 Trace 的价值:你不是在猜错误,而是在看证据。
5、会话快照:断点续跑的秘密
Trace 解决"事后复盘",会话快照解决"断点续跑"。
CLI 操作

tool_schema_hash:工具的 JSON Schema 哈希,检测工具定义是否变化
read_cache:乐观锁元信息(mtime + size),确保恢复后能检测文件是否被外部修改
prompt_hashes:各种提示词的哈希,确保上下文环境一致
这保证了你恢复会话时,工具版本、上下文状态、读前约束都和之前完全一致。
6、配置与性能
Trace 是可配置的,不会成为性能负担:
# 开关控制
TRACE_ENABLED=true|false # 默认 true
TRACE_DIR=memory/traces # 输出目录
TRACE_SANITIZE=true|false # 脱敏,默认 true
TRACE_HTML_INCLUDE_RAW_RESPONSE=true|false # 是否包含原始响应,默认 false
性能考虑:
JSONL 追加写入,开销极低
默认开启脱敏,生产环境需配合权限控制
HTML 生成在会话结束时批量处理,不影响运行时性能
从"猜错误"到"看证据",这一层是工程化的分水岭。 V0 时 Agent 挂了只能瞎猜,现在打开 Trace 5 分钟就能定位问题。可观测性不是锦上添花,而是复杂系统必备的"行车记录仪"。
八、扩展期:让 Agent 从"单兵作战"变成"专业团队"
工具、协议、上下文、可观测性——这些都让 MyCodeAgent 成了一个"靠谱的员工"。但一个员工再靠谱,终究只有一双手。面对复杂任务时,单打独斗的效率总是有限的。
真正让我眼前一亮的是:如果 Agent 能像一个"专业团队"那样协作呢?
有人专门负责"向外看"——搜索外部信息
有人专门负责"向内看"——分析代码结构
有人专门负责"盯进度"——确保不偏离主线
还有人随时准备"传授经验"——特定领域知道怎么干
这就是 MCP / Task / Todo / Skills 的出发点。它们不是给 Agent 增加负担,而是帮它拆解负担、专注专长。
1、MCP:给 Agent 装上"外部触角"
MCP(Model Context Protocol)是 Anthropic 推出的开放协议,简单说就是让 Agent 能调用外部工具的通用插槽。
我第一时间集成它,是因为不想重复造轮子。比如要做竞品调研,自己写搜索工具太麻烦,直接用社区现成的 tavily-mcp 多好。
集成方式很简洁:

子代理启动时,会创建一个完全独立的会话:
干净的消息历史,只包含任务相关的上下文
受限的工具集,只能只读(LS/Glob/Grep/Read/TodoWrite)
严格禁止:Task/Write/Edit/MultiEdit/Bash,以及 MCP 工具
为什么限制这么严格?
DENIED_TOOLS = frozenset({"Task", "Write", "Edit", "MultiEdit", "Bash"})
# MCP 工具也不在 ALLOWED_TOOLS 中
ALLOWED_TOOLS = frozenset({"LS", "TodoWrite", "Glob", "Grep", "Read"})
禁止 Task:防止"子生子,孙生孙"无限套娃
禁止写操作:防止子代理"越界改代码"
禁止 MCP:外部搜索涉及网络调用和 API Key,子代理隔离失败可能导致密钥泄露
它只负责代码分析和信息整理,决策权牢牢握在主 Agent 手里。
子代理还支持四种专业角色:
general:通用型,处理常规任务
explore:探索型,擅长代码库分析
summary:总结型,擅长信息归纳
plan:规划型,擅长任务拆解
以及双模型路由:
light:轻量模型(默认),省 Token、速度快
main:主力模型,复杂任务用
一个典型的外包流程是这样的:
主 Agent 发现需要深入分析某个模块的代码
启动 Task,指定 subagent_type=explore,限定分析范围
子代理独立运行 10-20 步,只读相关文件,整理结构
返回结构化报告,主 Agent 继续主线决策
上下文隔离 + 工具限制 + 模型分级,这套组合拳让主 Agent 可以"用人不疑"地委派任务。
3、TodoWrite:给 Agent 一张"路线图"
人同时干多件事会手忙脚乱,Agent 也一样。
TodoWrite 不是简单的任务清单,它是一个状态机 + 进度追踪器。
核心约束:
声明式覆盖:每次提交完整列表,不是 diff
最多 1 个 in_progress:强制单线程专注
自动 Recap:把 [2/5] In progress: xxx. Pending: yyy; zzz. 压缩到上下文末尾
完成后自动持久化:写入 memory/todos/todoList-YYYYMMDD-HHMMSS.md
为什么强制单线程?因为我发现,一旦允许多个"进行中",Agent 就开始"东一榔头西一棒槌",最后啥都没干完。
Recap 的设计也很关键——它像一张贴在桌角的便利贴,时刻提醒 Agent "你现在该干嘛"。
4、Skills:给 Agent 装上"领域大脑"
工具给了 Agent "手",但光有手不知道咋干活。
Skills 解决的是"Know How"问题。它的核心思想是:把个人经验写成 SOP,让 Agent 按需调用。
Skills vs MCP:渐进披露 vs 急切加载
MCP 的问题是"急切加载"——一连接就把所有 Schema、文档塞进上下文。Skills 采用渐进式披露:
第一层:启动只加载元数据(name/description)→ ~100 Token/技能
第二层:命中时才加载完整 SOP → 1000-5000 Token
第三层:附加资源按需加载
Token 节省 90% 以上。
三层实现架构
文件层:SKILL.md
---
name: ui-ux-pro-max
description: UI/UX设计专家,提供50+风格、21+配色、字体搭配等
---
#### UI/UX 设计指南(示例)
**可用风格:**
- Glassmorphism(玻璃拟态)
- Claymorphism(粘土拟态)
- Minimalism(极简主义)
...
**使用方式:** 根据项目类型选择合适的风格,提供具体实现代码。
$ARGUMENTS
格式要求:
YAML frontmatter 定义元数据
Markdown 正文写 SOP
$ARGUMENTS 是参数占位符
加载层:SkillLoader

执行时解析 $ARGUMENTS,把用户参数注入 SOP,然后塞进当前上下文。Agent 瞬间拥有了"领域专家的记忆"。
5、实战:一个长程任务的完整协作流程
说了那么多,来看个真实例子。我给 MyCodeAgent 安装了 tavily-mcp,然后布置了一个任务:
任务:
基于对全项目的理解,输出一个“面对新人开发者的项目介绍网页”
要求:
1. 内容需包含:项目概览、核心能力、架构/流程、注意事项
2. 网页风格你自行决定(科技感/赛博科技等均可)
3. 若你有 UI/UX 相关 Skill 可用,建议调用
4. 可以使用 MCP 工具搜索同类产品的功能点,在网页上进行对比
这个任务横跨了所有扩展能力。来看 Agent 是怎么"团队协作"的:
Step 1:启动 Todo,规划路线
Agent 首先调用 TodoWrite,拆解任务:
好,路线图有了。
Step 2:探索项目 + MCP 搜索
主 Agent 首先进行:
外部搜索(MCP)
调用 tavily_search,搜索竞品
获取宝能对比信息
随后进行内部探索
用 LS、Read 扫描项目结构
读取 README.md、核心模块文档
建立整体认知
Step 3:外包分析(Task 子代理)
"深入分析架构细节"这个活儿,主 Agent 不想亲自干——太琐碎,而且需要遍历大量文件。
于是启动 Task:
主 Agent 拿到报告,上下文依然干净——这些技术细节没有污染主会话。
Step 4:加载 Skill,获取设计指南
Agent 发现自己有 ui-ux-pro-max 这个 Skill,果断调用:
Skill 返回 设计指南:
风格:Cyberpunk / Tech-Noir
字体:Rajdhani(科技)+ Share Tech Mono(终端)
配色:深黑底 + 霓虹绿/青/粉/蓝
特效:CRT扫描线、屏幕闪烁、故障艺术、霓虹发光
Agent 瞬间从"盲人摸象"变成"有设计规范可依"。
Step 5:统筹输出
现在主 Agent 手里有:
? 项目整体理解(自己探索)
? 竞品对比信息(MCP 搜索)
? 技术架构细节(Task 分析报告)
? 设计规范(Skill 加载)
开始写 HTML:
最终产出放在 demo/mycodeagent_intro.html。
成果展示
页面顶部的 Hero 区如同巨型霓虹灯牌:
"MYCODEAGENT" 标题采用 Rajdhani 字体,被青色霓虹光晕(text-shadow 三层叠加)包裹,hover 时触发故障艺术(Glitch)动画——文字像老式电视信号不稳定般微微抖动
副标题用等宽字体 Share Tech Mono 打出":: 可追溯 :: 可验证 :: 可扩展 ::",模仿系统启动日志的样式
底部两个 CTA 按钮采用玻璃态(Glassmorphism)设计:半透明黑底 + 青色边框发光,hover 时边框光晕扩散
四大核心能力以悬浮卡片形式呈现:
每张卡片顶部有一条渐变色条(绿→青→粉),默认收缩,hover 时横向展开
卡片边框采用赛博边框设计:四角有独立的装饰角标,hover 时角标延伸成完整边框
图标使用霓虹色 emoji,在深色背景上形成高对比度视觉锚点
同类产品对比(好像有点小bug,agent搜索的是agent开发框架):
扩展能力的真正价值
回顾这个任务,如果没有这些扩展能力:
没有 MCP:Agent 只能基于内部知识"拍脑袋"对比,信息过时且容易幻觉
没有 Task:主 Agent 亲自分析架构细节,上下文被技术琐碎塞爆,主线思路断裂
没有 Todo:Agent 可能在写到一半时突然去优化某个细节,最后忘了主线目标
没有 Skills:Agent 凭"感觉"设计网页,风格可能不统一、不专业
有了它们,Agent 才能:
MCP 提供外部信息
Task 实现代码分析外包(子代理只读,安全隔离)
Todo 保持专注与进度追踪
Skills 提供专业领域知识
合理的分工是:主 Agent 控制 MCP 和最终决策,Task 处理内部代码分析,Skill 提供专业指导,Todo 串联全程。
这才是"像团队一样协作"——不是让 Agent 变复杂,而是让复杂变得可控。
写在最后:一个初学者的碎碎念
回顾整个系列:V0 → 工具重构 → Function Calling → 上下文工程 → 可观测性 → 扩展能力 → Skills。
这八篇文章,记录了我从一个 Agent 开发小白,跟着 Datawhale 的 Hello-Agent 教程一步步摸索过来的全过程。
首先要特别感谢 Datawhale 的开源教程。 如果没有 Hello-Agent 这个扎实的入门项目,我可能到现在还在各种"智能体框架"的概念里打转,而不会真正动手去写一个能跑起来的 Agent。正是教程最后那个"毕业设计"的推动,让我有了这个项目,也有了这八篇学习笔记。
说实话,写完这八篇,我越发觉得自己的渺小。
Agent 开发这个领域发展太快了,我文中提到的很多方案——比如上下文压缩策略、Skills 的设计、MCP 的集成方式——可能都还有更好的做法。我只是一个初学者,在实践中踩坑、总结、记录,分享的更多是一个"小白视角"的踩坑实录,而不是什么"最佳实践"。
如果你发现文中有错误,或者有更好的实现思路,非常欢迎在评论区指出。 我很希望能和大家交流,也很期待能向各位大佬请教。
一点真心话:我们都是在给 LLM "擦屁股"
做完这个项目,我有个特别深的感触,可能听起来有点糙,但话糙理不糙:
Agent 开发的核心,不是让模型更自由,而是通过工程设计,把模型"不确定的能力"约束在"最小可控的范围"里。说白了,我们就是在给 LLM 擦屁股。
为什么这么说?
你看啊,LLM 很强,能写代码、能读文档、能推理。但它就像一个特别聪明但特别不靠谱的实习生——
你让它去打印文件,它可能把全公司的打印机都调用一遍;
你让它整理会议纪要,它可能把上周的会议也掺和进来;
你让它写个函数,它写得贼溜,但变量命名全是 a、b、c,还顺带改了你没让改的文件。
它的"强"是能力上的强,但"不靠谱"是确定性上的不靠谱。
而我们做 Agent 工程,本质上就是在解决这个矛盾。

你看这八章的内容,从工具原子化到上下文工程,从可观测性到子代理——每一层都是在给模型"打补丁",帮它收拾烂摊子。
但这恰恰是最有意思的地方。
以前我觉得,AI 时代工程师的价值会下降。现在我觉得恰恰相反:模型越强大,越需要工程能力来驾驭它。就像汽车引擎越来越强,但好的底盘、刹车、悬挂系统反而更重要。
我们不是在和模型竞争,而是在和模型协作——它负责"能做什么",我们负责"怎么让它稳定地做对"。
所以,如果你问我做完这个项目最大的收获是什么?
不是学会了什么高大上的架构,而是想明白了一个朴素的道理:优秀的 Agent 不是"让模型更自由"的产物,而是"把不确定性约束到最小"的结果。
讲真,这个认知转变,可能比所有代码都值钱。
未来的打算
MyCodeAgent 还只是一个"能跑"的玩具,离真正生产可用还有很长的路要走。接下来我想继续完善的方向:
多 Agent 协作——Task 只是简单的子代理,能不能做更复杂的多 Agent 编排?
视觉能力集成——让 Agent 能看懂 UI、能截图分析,这是我特别想做的方向
更完善的测试体系——现在的测试还比较简陋,需要补全协议合规性和行为测试