炸了!Claude Code 51.2 万行代码泄露,核心架构完整拆解:从 npm 包到 Ink 终端渲染的 TypeScript 全链路
1. 从 npm 包到终端 UIClaude Code 泄露代码到底能拆出什么Claude Code 是 Anthropic 推出的终端 AI 编程助手它能在命令行里直接读写文件、执行命令、跑测试把「对话」和「动手」合在一起。这次被讨论最多的是它 51.2 万行 TypeScript 源码因为一个 source map 配置失误在 npm 上被完整暴露。对普通用户来说这只是一条新闻但对想搞懂「终端 AI Agent 到底怎么搭」的开发者来说这是一份难得的工程样本。我关心的不是八卦而是它的分层方式最上面是 React Ink 渲染的终端界面中间是 Commander.js 解析命令再往下是 QueryEngine 驱动的 Agent Loop然后是工具与权限系统最底层才是对 Anthropic Messages API 的调用。这条链路里每一层都能单独拿出来复现。这篇文章会带你做三件事第一用几条命令把 npm 包结构拉下来看清目录树和模块划分第二拆解从 CLI 入口到 Ink 渲染的关键依赖第三在 TaoToken 统一 Key/API 通道下把终端交互效果本地跑起来。适合谁写过一点 TypeScript、用过 npm、对 Agent 架构好奇但还没亲手拆过一个完整终端 AI 工具的人。需要提前说明泄露源码本身涉及版权本文只做架构层面的学习性拆解不提供源码分发也不鼓励把泄露代码用于生产。我们要复现的是「同类终端 Agent 的搭建思路」而不是搬运别人的私有实现。2. TaoToken 前置准备统一 Key 与 API 通道怎么配在动手拆架构之前先把模型调用这条链路打通。Claude Code 这类工具的核心是 Agent Loop而 Loop 里每一步「模型思考」都要发一次 API 请求。如果你本地要复现终端交互就必须有一个稳定的模型入口。TaoToken 在这里扮演的角色是把你对多个模型的访问收敛成一套 Key 和一套 Base URL省得在每个工具里重复填配置。先注册并拿到 Key。打开官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 完成账号后进入控制台。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 在里面创建 API Key。创建完先复制保存页面刷新后通常不再完整显示。拿到 Key 之后去 API Keys 页面确认权限和额度https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。这里能看到你创建的 Key 列表、可用模型范围。如果你打算长期跑编码类 Agent建议同时了解 Coding Plan它的定位是给持续编码和 Agent 场景用的套餐https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。API 的基础地址统一用 https://taotoken.net/api 注意这个地址后面不加 UTM 参数直接作为 Base URL 填进工具即可。模型 ID 按你控制台里实际可用的填比如对话类模型和编码类模型分开选。配置时记住三件套Base URL、API Key、Model ID缺一个都跑不通。如果你只是想先验证模型能不能通不想装任何工具可以直接用模型对话页面测一条https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 。发一句「用 TypeScript 写一个读取目录树的函数」能正常流式返回就说明 Key 和通道没问题。这一步很关键因为后面拆 Claude Code 架构时任何 Agent Loop 的报错你都要先排除「是不是 Key 或 Base URL 填错了」。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有针对不同工具的填写示例。我建议你在这一步就把 Base URL 和 Key 写进一个本地.env文件后面所有配置都从这里读避免散落在各处。3. 可复制配置目录树梳理命令与 settings 片段这一节给你能直接粘贴的东西。先看怎么把 npm 包结构拉下来分析。Claude Code 发布在 npm 上包名是anthropic-ai/claude-code。即使不安装也可以用npm pack把 tarball 下载到本地解压看它的文件组织。# 建一个干净的实验目录 mkdir -p ~/cc-arch cd ~/cc-arch # 只下载 tarball不安装 npm pack anthropic-ai/claude-code # 解压 tar -xzf anthropic-ai-claude-code-*.tgz # 看顶层结构 ls -la package/解压后你会看到package.json、cli.js之类的入口文件。真正的 TypeScript 源码在 source map 里用source-map工具或直接看.map文件里的sourcesContent字段可以还原。这里只做结构观察不展开还原细节。看目录树用tree没有就装一个# macOS brew install tree # Ubuntu/Debian sudo apt-get install tree # 只看两层排除 node_modules tree -L 2 -I node_modules package/如果你想分析模块依赖用madge生成依赖图npm install -g madge madge --extensions ts,tsx --image deps.svg package/接下来是配置片段。Claude Code 的配置通常放在用户目录下的 settings 文件里。以~/.claude/settings.json为例把模型通道指向 TaoToken{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的TaoToken密钥, ANTHROPIC_MODEL: 你的模型ID }, permissions: { allow: [ Read, Bash(git status), Bash(npm run test) ] } }如果你用的是支持 TOML 的工具链等价配置可以写成[model] base_url https://taotoken.net/api api_key sk-你的TaoToken密钥 model_id 你的模型ID [permissions] allow [Read, Bash(git status)]注意ANTHROPIC_BASE_URL后面不要带斜杠也不要加 UTM 参数保持https://taotoken.net/api原样。Model ID 必须和控制台里显示的一致写错会直接 404 或 model not found。如果你用的是 Codex 类工具配置写在~/.codex/auth.json结构类似{ base_url: https://taotoken.net/api, api_key: sk-你的TaoToken密钥, model: 你的模型ID }三件套 Base URL、Key、Model ID 在任何工具里都是这套逻辑。配完先别急着跑 Agent用一条最小请求验证通道下一节讲。4. 验证请求从 CLI 入口到 Ink 渲染跑通一次配置写完先验证模型通道再验证终端渲染。两步分开出问题好定位。第一步用 curl 直接打 TaoToken 的 API确认 Key 有效curl https://taotoken.net/api/v1/messages \ -H x-api-key: sk-你的TaoToken密钥 \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: 你的模型ID, max_tokens: 128, messages: [ {role: user, content: 只回复两个字通了} ] }返回里能看到content数组和文本就说明通道没问题。如果这里就报 401先回去检查 Key 有没有复制全、有没有多余空格。第二步理解 Claude Code 的启动链路。它的入口是main.tsx用 Commander.js 解析命令然后挂载 React Ink 的终端 UI。Ink 是把 React 的组件模型搬到终端里的库你用Box、Text这些组件它负责渲染成 ANSI 字符。核心结构大致是这样import React from react; import { render, Box, Text } from ink; const App () ( Box flexDirectioncolumn Text colorgreenClaude Code 风格终端/Text Text dimColor输入你的问题回车发送/Text /Box ); render(App /);第三步把 Agent Loop 接上。QueryEngine 的核心是一个 while 循环组装 System Prompt、发请求、拿工具调用、执行、把结果塞回消息历史直到模型不再调工具。用伪代码表示async function agentLoop(messages: Message[]) { while (true) { const res await callModel(messages); messages.push({ role: assistant, content: res.content }); const toolCalls res.content.filter(c c.type tool_use); if (toolCalls.length 0) break; for (const call of toolCalls) { const result await executeTool(call); messages.push({ role: user, content: [result] }); } } return messages; }跑通的标准是终端里输入一句话模型返回一个工具调用比如读文件你本地执行后把结果回传模型基于结果给出最终文本。整个过程在 Ink 界面里流式刷新。如果模型一直循环调用工具不停止检查你的 System Prompt 里有没有明确「任务完成后返回纯文本」的约束。5. 常见报错排查401、local proxy failed 与 reading choices拆架构和跑 Agent 时报错基本集中在几类。下面按真实错误信息对照排查。401 Unauthorized。最常见。原因通常是 Key 没填、填错、或者 Base URL 写成了带路径的地址。检查ANTHROPIC_BASE_URL是不是https://taotoken.net/api不要写成https://taotoken.net/api/v1再加一层。Key 前后不要有空格和换行。如果用的是环境变量确认 shell 里echo $ANTHROPIC_API_KEY能打印出来。local proxy failed / connection refused。这类报错说明请求根本没发出去或者被本地某个代理拦了。先确认你没有在环境变量里设置HTTP_PROXY、HTTPS_PROXY指向一个不存在的本地端口。用env | grep -i proxy检查有就临时 unset 掉再试。另外确认网络能正常访问https://taotoken.net/api用 curl 那条命令测。reading choices of undefined。这是 OpenAI 格式和 Anthropic 格式混用导致的。TaoToken 的/api通道对 Anthropic 格式用/v1/messages返回结构是content数组如果你用 OpenAI SDK 去打它期望choices字段就会读到 undefined。解决办法是确认你用的 SDK 和接口格式匹配Anthropic SDK 配/v1/messagesOpenAI SDK 配对应的 chat completions 路径。别把两套混着用。OAuth 相关报错。有些工具默认走 OAuth 登录流程而不是 API Key。如果你在 Claude Code 里看到 OAuth 报错说明它没读到你的 API Key 配置。检查 settings 文件路径对不对环境变量有没有被工具读取。必要时在启动命令前显式导出export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的TaoToken密钥 export ANTHROPIC_MODEL你的模型ID模型返回空或截断。检查max_tokens是不是设太小以及 Model ID 是否拼写正确。Model ID 写错有时不报错只是返回空内容很容易误判成通道问题。工具调用死循环。Agent Loop 里模型反复调同一个工具通常是 System Prompt 没约束好或者工具返回结果格式不对模型无法判断任务已完成。在工具结果里加上明确的状态字段并在 Prompt 里写清终止条件。排查顺序建议固定先 curl 验证通道再验证配置读取最后才看 Agent 逻辑。这样能避免在业务代码里绕圈。6. 长期编码与 Agent 场景把通道固定下来拆完架构你会发现Claude Code 这类工具真正的复杂度不在 UI而在 Agent Loop 和工具权限系统的工程细节。51.2 万行代码里大量篇幅花在上下文管理、权限检查、流式响应处理上而不是「聪明」的算法。这也解释了为什么它选择极简的 while 循环而不是复杂的任务规划器——把决策权交给模型工程上只保证循环稳定、工具安全、上下文不丢。如果你打算长期跑编码类 Agent反复手动填 Key 不现实。把 Base URL、Key、Model ID 固定到配置文件或环境变量里是第一步。TaoToken 的 Coding Plan 就是针对这种持续调用场景设计的适合每天都要跑 Agent 的人https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入细节和不同工具的配置模板文档里都有https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。Key 管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 建议给不同工具建不同的 Key方便单独吊销和统计用量。最后给一个实用习惯每次改完配置先用模型对话页面发一条最小请求验证再去跑 Agent。这一步花十秒能省掉后面半小时的排查。通道稳了架构拆解和本地复现才有意义。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →