我用 TypeScript 从零手写了一个 Claude Code,然后发现它的核心只有 30 行

我用 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 的差距

它和市面上大多数教程不太一样的地方:

  1. 不用框架,从第一行 while 写起。 你学到的是原理,不是某个 API 的用法。框架会过时,这些本质认知不会。
  2. 每期都能真的跑起来。 不是 PPT 讲概念,是一个持续生长、你能改能扩的完整代码库。
  3. 诚实讲差距。 终章我没有吹"手写的能吊打 Claude Code",而是把它和真产品摆在一起,把剩下那道鸿沟拆成四层讲清楚:工程细节、提示词打磨、产品生态、模型本身。任何一个 Agent 产品,说白了都是「模型 × 工程 × 产品生态」的乘积。看懂这个乘法,市面上再没有哪个 AI 编程工具能唬住你。

七、谁适合看

  • 会一点 JS/TS,想搞懂 AI Agent 到底怎么转的前端 / 全栈;
  • 天天用 Cursor、Claude Code,但受够了把它当黑箱的人;
  • 想做 AI 应用,却发现"调框架"和"理解原理"之间差着一层窗户纸的人。

不需要任何机器学习背景。我们不训练模型,只把模型当成一个会说话、会点菜的零件来用。


八、来看完整版

这篇文章只是把几个认知点摊开给你看,真正的干货------完整代码、逐行讲解、真实账单演示、故意"弄坏"再修好的实验------都在视频和仓库里。

2026 年,会调 Agent 框架的人越来越多,但真正理解它怎么转的人依然稀缺。跟着写完这十期,你就是后者。

如果这篇文章帮你捅破了一层窗户纸,点个赞、关注一下,别错过后面的深度内容。我们视频里见。

相关推荐
大圣编程3 小时前
Python中continue语句的用法是什么?
开发语言·前端·python
yuhaiqiang3 小时前
随手 vibecoding 的浏览器插件已经 6000 多次下载,聊聊他的产品设计
前端·后端·面试
云烟成雨TD3 小时前
LangFlow 1.x 系列【5】可视化编辑页面功能说明
人工智能·python·agent
之歆3 小时前
Vue商品详情与放大镜组件
前端·javascript·vue.js
再吃一根胡萝卜4 小时前
如何把小米 MiMo 接入 CodeBuddy,打造私有 Agent
前端
阿拉斯攀登4 小时前
Agent 核心架构:思考-行动-观察循环(ReAct)
人工智能·ai·agent·react
负责的蛋挞5 小时前
异步HttpModule的实现方式
java·服务器·前端
8Qi86 小时前
HelloAgents:RAG——让 Agent 学会检索知识
人工智能·llm·agent·ai编程·vibecoding
Grapes6 小时前
没有魔法,只有循环:从 LLM API 到第一个 Agent
llm·agent