我用 TypeScript 从零手写了一个 Claude Code,然后发现它的核心只有 30 行
👇 关注公众号【前端小卒】,获取更多 AI 工程实战内容。
这个系列的文章会同步在公众号首发,包括:Agent 开发从零到一全流程、Node.js 全栈学习路线、Vibe Coding 实战踩坑。不贩卖焦虑,只给能上手的东西。
一、先问你一个问题
你每天都在用 Claude Code、Cursor、各种 AI 编程工具,那你能说清楚,当你打一句"帮我修一下这个 bug",它背后到底发生了什么吗?
大多数人的回答会停在"它调用了大模型"。再往下问:模型是怎么"读文件""跑命令""改代码"的?它怎么知道该先看哪个文件?聊久了为什么会变笨、变贵?它凭什么敢在你的机器上执行 rm?大部分人就答不上来了。
这不怪你。市面上讲 Agent 的内容,要么停在"你好世界"级别的 API 调用演示,要么直接甩给你一个封装好几层的框架,让你以为 Agent 是个高深莫测的黑盒。
我不信这个邪。于是我做了一件笨事:用 TypeScript,不借助任何 Agent 框架,从第一行 while 开始,把 Claude Code 这类工具的核心机制亲手复刻了一遍。写到最后,我手上有了一个几百行、但结构和真实产品高度接近的 Agent。
这就是《手搓 Claude Code》这个系列。这篇文章,我想把其中几个"拆穿黑箱"的瞬间讲给你听。看完你会发现,Agent 没有你想的那么神秘,但也远比"调个 API"深刻。
二、第一个反直觉的事实:Agent 的核心,是一个 while 循环
我第一次用 Claude Code 时,盯着控制台看了很久。一个月 20 美元的订阅,能自己读代码、改文件、跑测试,我默认它背后是一套庞大的系统:任务规划器、代码分析引擎、执行沙箱。结果从行为上看,它做的事情简单得可疑:调一次 API,读几个文件,再调一次 API,再读几个文件。循环往复。
后来我把这个循环自己写了一遍,确认了那个让人有点难以接受的事实:Agent 的核心不是什么新物种,就是一个 while 循环。
去掉所有工程细节,它的骨架是这样的:
ts
async function agent(task: string) {
const messages = [{ role: "user", content: task }];
while (true) {
// 1. 把整段对话历史 + 工具菜单发给模型
const res = await client.messages.create({ model, messages, tools });
messages.push({ role: "assistant", content: res.content });
// 2. 模型说"话说完了",收工
if (res.stop_reason !== "tool_use") break;
// 3. 模型想动手,你替它执行,把结果塞回历史,进入下一轮
const results = runTools(res.content);
messages.push({ role: "user", content: results });
}
}
本体不到 30 行。想通这段代码,很多东西会连锁地清晰起来。
关键在于:模型从来没有执行过任何东西。 大模型 API 的本质就是一个函数:输入一段对话历史,输出一段文字。它没有手,碰不到你的文件系统。所谓"AI 调用了工具",严格说是"AI 输出了一段结构化的文字说'我想读 package.json',然后被你的代码批准并代劳了"。
决策和执行是分离的:模型是大脑,你的代码是手脚。 这一条是整个系列的地基。第 1 期我把它总结成一句话:策略在模型里,机制在循环里。 循环是死的,每一轮里"读哪个文件、下一步干嘛"的判断是活的。
顺带一提,那个 messages 数组就是 Agent 的全部状态。没有隐藏会话、没有服务端存档,Agent 此刻知道什么、干到哪一步,全部等于这个数组的内容。想暂停明天接着干?序列化存盘。想回放调试?重放数组。状态即历史。
三、那为什么各家 Agent 的能力天差地别?
同一批模型,接到不同产品里,能力差得惊人。为什么?
因为能力的边界根本不在模型,而在你递给它的那张"工具菜单"。 你给它 read_file,它就能看代码;给它 bash,它就能跑命令;你什么都不给,它就只能陪聊。2026 年那些打得火热的编程 Agent,用的模型高度重合,拼的就是外面这圈工具和提示词。
这里藏着一个很反直觉的工程观念:你写工具,本质是在给一个"模型用户"设计 UI。 工具的 description 不是文档注释,而是模型做决策时唯一的依据。它没法看你的源码,你没写的它就不知道。真实 Claude Code 里单个工具的描述能到几百上千 token,写清楚什么时候用、什么时候别用、常见错误怎么办。那不是文档,是大量真实翻车换来的用户体验设计。
还有一个更颠覆的点:灵魂在系统提示词里。 同一个裸模型,默认是个"热情过头的实习生":好的!我很乐意帮您......(八轮之后)希望这对您有帮助!而 Claude Code 上来就是"跑测试→定位到 date.ts:42 时区处理→要我改吗?"。差别只在一段你看不见的文字。系统提示词的每一条约束,背后都是一次事故。民航条例说每一条都是用血写成的;系统提示词是软件业的温和版本。
四、一个真正有深度的问题:聊久了,AI 为什么会变笨、变贵?
这是我个人觉得整个系列最"有用"的一期。
先说个反直觉的事实:模型是无状态的,它一点记忆都没有。 每次请求都是一次全新的、无记忆的计算。所谓"它记得上文",是因为你把整段历史原样重发了一遍。你熟悉的前端里,HTTP 也是无状态的,"登录态"是 cookie 一次次重放伪造出来的会话感。模型 API 同理,只不过重放的是整个对话史。
那么代价来了。设每轮平均新增 k 个 token,第 n 轮要把全部历史重发,input 大约是 n×k。n 轮下来累计付费大约是 k · n(n+1)/2,也就是 n 的平方级增长。对话轮数翻一倍,总账单翻四倍。这就是为什么 Agent 跑一个大任务,成本比聊天贵一个数量级:不是它话多,是历史在滚雪球,每一层还被反复计费。
更隐蔽的是它真的会变笨。长上下文研究里有个反复复现的结论叫 lost in the middle:模型对开头结尾召回率高,对中间显著下降。你干到第 30 轮时,第 8 轮定下的关键决定正好沉在"中间",于是它忘了,甚至做出矛盾的决定。
所以这一期我最想留下的一句话是:上下文不是仓库,是工作台。 仓库求大求全,工作台只摆当前工序需要的东西。桌面越乱,手越慢。至于怎么收拾桌子(prompt caching 为什么能把账单打到一折、又反过来绑架你的架构;compact 怎么让模型给自己写交接摘要),我在视频里用真实的账单曲线一点点算给你看。
五、几个"原来如此"的瞬间
篇幅有限,剩下几期我只挑最颠覆认知的一句话,勾一下:
-
精确编辑(EP06) :让模型改一个 2000 行文件里的错别字,它会把整个文件重写一遍,又贵又慢,还会"顺手优化"你没让它碰的代码。业界最后收敛到的方案是让模型给出
old_string/new_string做精确替换。为什么这个看起来最笨的方案胜出?因为 old_string 是一段引用,而引用即校验:模型要是记错了文件内容,替换会在碰你磁盘之前就失败。匹配失败不是缺点,是安全机制。 -
权限系统(EP07) :想拦住危险命令,第一反应都是搞个黑名单。写两行你就发现这是场必输的军备竞赛,因为 危险根本不是命令的属性,是上下文的属性 :
rm -rf node_modules稀松平常,rm -rf ~/项目是灾难,两条命令长得几乎一样。正确的维度不是"危险程度",而是可逆性:可逆的放手,不可逆的把关。安全问题从"预测危险"变成了"匹配后悔成本"。 -
记忆(EP08) :怎么让 Agent 跨会话记住"我们项目用 pnpm"?工程师的第一反应是微调模型、上向量数据库,越靠前的越贵越复杂,越靠后的越对。正确答案朴素到欺负人:写一个 Markdown 文件,每次开工时读进系统提示词。 AI 的记忆不在模型里,在文件里。背后是 2026 年最值钱的一个认知:在应用层,上下文工程 > 模型训练。
-
子 Agent(EP09) :一说"多 Agent"大家都以为是并行提速。其实它的核心价值是上下文隔离 :把翻几十个文件的脏活丢给一个用完即弃的分身,只让它带一句结论回主线,主线的工作台始终干净。而它的实现会让你会心一笑:所谓"派一个分身",就是在一个工具函数里,再调用一次第 1 期那个
agent()循环。 递归。绕了九期,我们回到了起点。
六、这个系列到底是什么
《手搓 Claude Code》,10 期,用 TypeScript 从零写一个 Agent,不用任何框架。代码按 ep01~ep10 打了 tag,每一期都能独立跑通、都留一个钩子。
| 期 | 主题 | 一句话 |
|---|---|---|
| EP01 | Agent 循环 | 核心就是一个 30 行的 while 循环 |
| EP02 | 工具系统 | 能力边界,是你写的那几行工具代码 |
| EP03 | 系统提示词 | 同一个模型,换个壳就换了人格 |
| EP04 | 上下文经济学 | 聊久了为什么会变笨、变贵 |
| EP05 | 流式与打断 | 字是一个个蹦出来的,但那不是动画 |
| EP06 | 精确编辑 | 改一个错别字,为什么不该重写整个文件 |
| EP07 | 权限系统 | 别让它 rm -rf:信任是设计出来的 |
| EP08 | 文件记忆 | AI 的记忆不在模型里,在文件里 |
| EP09 | 子 Agent | 分身的秘密,是第 1 期那个循环 |
| EP10 | 终章 | 架构全景 + 和真实 Claude Code 的差距 |
它和市面上大多数教程不太一样的地方:
- 不用框架,从第一行 while 写起。 你学到的是原理,不是某个 API 的用法。框架会过时,这些本质认知不会。
- 每期都能真的跑起来。 不是 PPT 讲概念,是一个持续生长、你能改能扩的完整代码库。
- 诚实讲差距。 终章我没有吹"手写的能吊打 Claude Code",而是把它和真产品摆在一起,把剩下那道鸿沟拆成四层讲清楚:工程细节、提示词打磨、产品生态、模型本身。任何一个 Agent 产品,说白了都是「模型 × 工程 × 产品生态」的乘积。看懂这个乘法,市面上再没有哪个 AI 编程工具能唬住你。
七、谁适合看
- 会一点 JS/TS,想搞懂 AI Agent 到底怎么转的前端 / 全栈;
- 天天用 Cursor、Claude Code,但受够了把它当黑箱的人;
- 想做 AI 应用,却发现"调框架"和"理解原理"之间差着一层窗户纸的人。
不需要任何机器学习背景。我们不训练模型,只把模型当成一个会说话、会点菜的零件来用。
八、来看完整版
这篇文章只是把几个认知点摊开给你看,真正的干货------完整代码、逐行讲解、真实账单演示、故意"弄坏"再修好的实验------都在视频和仓库里。
- 📺 B 站 :从零手搓Claude Code
- 💻 抖音 :从零手搓Claude Code
2026 年,会调 Agent 框架的人越来越多,但真正理解它怎么转的人依然稀缺。跟着写完这十期,你就是后者。
如果这篇文章帮你捅破了一层窗户纸,点个赞、关注一下,别错过后面的深度内容。我们视频里见。