> ## Documentation Index
> Fetch the complete documentation index at: https://cc.cyber101.cc/llms.txt
> Use this file to discover all available pages before exploring further.

# Claude Code 逆向分析

> 通过技术手段逆向分析Claude Code的API交互过程，揭秘AI编程之王的多模型协作策略、精巧的系统提示词设计和智能工具调用机制。

**来源**: [掘金文章](https://juejin.cn/post/7535400490835656740)\
**作者**: 子昕AI编程\
**发布时间**: 2025-01-15

## [文章摘要](#文章摘要)

通过技术手段逆向分析Claude Code的API交互过程，揭秘AI编程之王的多模型协作策略、精巧的系统提示词设计和智能工具调用机制，手把手教你监控AI的每一次"内心独白"。

## [正文内容](#正文内容)

> 大家好，我是子昕，一个干了10年的后端开发，现在在AI编程这条路上边冲边摸索，每天都被新技术追着跑。
> 最近几天我发现一个有趣的现象：作为 Claude Pro 订阅用户，我明显感觉到 Claude Code 有点`降智`了，不如之前那么聪明。
> 这让我突然想起一个经典问题——**我们能否偷看一下 AI 的"小抄"？**
> 作为一个有着强烈好奇心的程序员，我决定对 Claude Code 来一场"开膛破肚"式的逆向分析。毕竟，既然它被誉为"AI编程工具之王"，那我就要看看它的王座到底是怎么坐稳的。
> 经过一番折腾，我发现了 GitHub 上一个对Claude Code进行逆向的项目：`claude-code-reverse`
> [github.com/Yuyz0112/claude-code-reverse](https://github.com/Yuyz0112/claude-code-reverse)
> 这个项目可以让我们实时拦截和分析 Claude Code 与服务器的所有通信，相当于给 AI 装了个`窃听器`。

## [为什么要逆向 Claude Code？](#为什么要逆向-claude-code)

在开始动手之前，先说说为什么要这么做：

1. **技术好奇心**：Claude Code 凭什么能做到比其他 AI 编程工具更强？
2. **成本透明度**：作为 Pro 用户，我想知道每次对话到底消耗了哪个模型，用了多少 tokens
3. **学习借鉴**：了解顶级 AI Agent 的设计思路，对我们自己开发 AI 应用有巨大价值
4. **质量监控**：当感觉 AI 表现异常时，可以通过日志分析找到原因

## [准备工作：工具箱清单](#准备工作工具箱清单)

在开始这场"技术侦探"之旅前，你需要准备：

* **Claude Code**：废话，没有目标怎么逆向
* **Node.js 环境**：用于安装 js-beautify
* **一颗不怕搞坏东西的心**：记得备份，万一搞砸了别哭

## [第一步：定位"目标"](#第一步定位目标)

首先要找到 Claude Code 的真身。在命令行执行：

```
which claude
```

通常会得到类似这样的结果：

```
/opt/homebrew/bin/claude
```

但这只是个"替身"！在 Mac 上，这通常是一个软链接。我们需要找到真正的 `cli.js` 文件：

```
ls -l /opt/homebrew/bin/claude
```

你会看到它指向了真正的安装位置：

```
/opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/cli.js
```

这就是我们要"动手脚"的地方！

## [第二步：美化代码，让它"可读"](#第二步美化代码让它可读)

Claude Code 的代码是压缩过的，就像一团乱麻。我们需要先让它变得人类可读：

```
# 进入 Claude Code 安装目录
cd /opt/homebrew/lib/node_modules/@anthropic-ai/claude-code/
# 备份原文件（这一步很重要！）
mv cli.js cli.bak
# 安装代码美化工具
npm install -g js-beautify
# 美化代码
js-beautify cli.bak > cli.js
```

现在 `cli.js` 就变成了格式良好、可读性强的代码。

## [第三步：植入"间谍代码"](#第三步植入间谍代码)

这是整个过程中最关键的一步。我们要在 `cli.js` 中植入监控代码，让它把所有与 LLM 的对话都记录下来。

### [3.1 添加基础监控模块](#31-添加基础监控模块)

在文件开头 `#!/usr/bin/env node` 这行之后，添加我们的"间谍模块"：
间谍代码如下，直接复制粘贴即可：

```
// ============= 间谍模块开始 =============
import fs from "fs";
import path from "path";
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const LOG_PATH = path.resolve(__dirname, 'messages.log');
// 每次启动时创建新的日志会话
fs.writeFileSync(
  LOG_PATH,
  `---Session ${new Date()}---\n`
);
function isAsyncIterable(x) { 
  return x && typeof x[Symbol.asyncIterator] === 'function'; 
}
const ts = () => new Date().toISOString();
function uid() {
  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
}
// 这个函数负责拦截流式响应，记录工具调用的详细信息
function tapIteratorInPlaceWithTools(inner, onFinal) {
  if (!inner) return inner;
  const TAPPED = Symbol.for('anthropic.tap.iterator');
  if (inner[TAPPED]) return inner;
  Object.defineProperty(inner, TAPPED, { value: true, configurable: true });
  const byteLen = s =>
    typeof Buffer !== 'undefined'
      ? Buffer.byteLength(s, 'utf8')
      : new TextEncoder().encode(s).length;
  const makeWrapper = getOrigIter => function() {
    const it = getOrigIter();
    let text = '';
    const open = new Map();
    const done = [];
    const PREVIEW_CAP = Infinity;
    const start = (id, name) => {
      if (id == null || open.has(id)) return;
      open.set(id, { 
        id, 
        name: name||'unknown', 
        startedAt: Date.now(), 
        inputBytes: 0, 
        preview: '' 
      });
    };
    const delta = (id, chunk) => {
      if (id == null) return;
      if (!open.has(id)) start(id);
      const rec = open.get(id);
      if (!rec) return;
      const s = typeof chunk==='string' ? chunk : JSON.stringify(chunk||'');
      rec.inputBytes += byteLen(s);
      if (rec.preview.length < PREVIEW_CAP) {
        rec.preview += s.slice(0, PREVIEW_CAP - rec.preview.length);
      }
    };
    const stop = id => {
      const rec = open.get(id);
      if (!rec) return;
      open.delete(id);
      const finishedAt = Date.now();
      done.push({ 
        ...rec, 
        finishedAt, 
        durationMs: finishedAt - rec.startedAt 
      });
    };
    const finalizeDangling = err => {
      for (const rec of open.values()) {
        done.push({
          ...rec,
          finishedAt: Date.now(),
          durationMs: Date.now() - rec.startedAt,
          errored: err ? (err.stack||String(err)) : undefined
        });
      }
      open.clear();
    };
    return (async function*() {
      try {
        for await (const ev of it) {
          // 记录每个事件
          const logEntry = {
            timestamp: ts(),
            event: ev,
            type: ev.type || 'unknown'
          };
          fs.appendFileSync(LOG_PATH, JSON.stringify(logEntry, null, 2) + '\n');
          yield ev;
        }
      } catch (err) {
        finalizeDangling(err);
        throw err;
      }
    })();
  };
  return makeWrapper(() => inner);
}
// ============= 间谍模块结束 =============
```

### [3.2 找到正确的注入点](#32-找到正确的注入点)

现在我们需要找到在 `cli.js` 中注入监控代码的位置。搜索处理 API 调用的函数，寻找类似这样的模式：

```
async function makeRequest(options) {
  // ... 现有代码
}
```

在 API 调用之前插入我们的间谍代码：

```
// 在 API 调用之前添加监控
const monitoredResponse = tapIteratorInPlaceWithTools(response, () => {
  // 记录最终结果
  fs.appendFileSync(LOG_PATH, `---Session End ${new Date()}---\n\n`);
});
```

## [第四步：测试我们的"窃听器"](#第四步测试我们的窃听器)

现在让我们测试监控系统：

```
# 启动 Claude Code
claude
# 问一个简单的问题
Describe the project structure
```

你应该会在 Claude Code 安装目录中看到一个 `messages.log` 文件生成。这个文件包含了所有被拦截的通信！

## [第五步：分析结果](#第五步分析结果)

打开日志文件，你会看到关于以下内容的详细信息：

1. **API 请求/响应**：完整的 HTTP 通信
2. **模型选择**：每个任务使用了哪个模型
3. **Token 使用**：详细的 token 消耗
4. **工具调用**：所有工具调用及其参数
5. **系统提示词**：指导 Claude Code 行为的复杂提示词

## [关键发现](#关键发现)

### [1. 多模型协作策略](#1-多模型协作策略)

Claude Code 并不只使用一个模型。它会智能地为不同任务选择不同的模型：

* **Opus**：用于复杂推理和代码生成
* **Sonnet**：用于常规任务和简单查询
* **Haiku**：用于快速响应和基本操作

### [2. 精巧的系统提示词设计](#2-精巧的系统提示词设计)

系统提示词非常详细且精心设计，涵盖：

* **角色定义**：Claude Code 能力的明确定义
* **工具使用指南**：每个工具的详细说明
* **错误处理**：全面的错误恢复策略
* **上下文管理**：智能的上下文压缩和保留

### [3. 智能的上下文管理](#3-智能的上下文管理)

当对话变长时，Claude Code 会自动压缩历史上下文，保留关键信息的同时节省 token 消耗。这个功能通过专门的压缩提示词实现。

### [4. 工具调用的精细化设计](#4-工具调用的精细化设计)

Claude Code 定义了丰富的工具集，包括：

* 文件系统操作（读取、写入、搜索）
* 代码执行（Bash、Python 等）
* 任务管理（TodoWrite）
* IDE 集成工具
* 子代理系统（Task）

## [实际应用：解决"降智"问题](#实际应用解决降智问题)

通过日志分析，我发现我感觉到的"降智"现象可能有几个原因：

1. **模型选择策略变化**：可能是为了控制成本，某些任务改用了较轻量的模型
2. **上下文压缩过于激进**：重要信息在压缩过程中丢失
3. **工具调用链过长**：复杂任务的多步骤推理被分散到多个工具调用中

## [总结](#总结)

通过这次"技术侦探"之旅，我不仅了解了 Claude Code 强大秘密的冰山一角，还学到了一些 AI Agent 设计的宝贵经验：

1. **多模型协作**比单一模型更高效
2. **精心设计的系统提示词**是关键
3. **工具系统的丰富性**决定了能力上限
4. **上下文管理策略**影响对话质量

### [这只是开始](#这只是开始)

需要说明的是，这次分析只是通过一个简单的"描述项目结构"需求，初步了解了如何进行逆向分析。Claude Code 的真正实力远不止于此！
后面我计划通过更复杂的场景来深入挖掘：

* `复杂编程任务`：看它如何处理多文件重构、架构设计等高难度任务
* `性能优化场景`：分析它如何进行代码审查和性能调优
* `调试和问题解决`：观察它的错误诊断和修复策略
* `项目搭建全流程`：从零开始创建一个完整项目的思维过程
* `Sub-Agent 系统`：深入了解它的多智能体协作机制
  每一个场景都会揭示 Claude Code 更深层的设计哲学和技术细节。如果你对某个特定场景特别感兴趣，欢迎留言告诉我！
  如果你也想探索 AI 的内心世界，不妨试试这个方法。记住，好奇心是程序员最宝贵的品质！

## [相关图片](#相关图片)

文章包含多张截图，展示了逆向分析的过程和结果：

1. 代码植入过程截图
2. API 拦截代码示例
3. 监控日志文件生成
4. 可视化分析界面
5. 多模型协作流程图
6. 工具调用序列图
7. 系统提示词详细内容
   这些图片详细展示了整个逆向分析的技术细节和发现结果。

***

*本文基于掘金的子昕AI编程的原创作品。你可以在 [https://juejin.cn/post/7535400490835656740](https://juejin.cn/post/7535400490835656740) 找到原文。*

* [复合式工程：构建自我改进的开发系统](/docs/advanced/advanced_compounding-engineering) - 学习如何构建随着每次迭代变得更快、更安全、更优秀的开发系统。将你的工程工作流程从短期收益转变为永久改进。
