跳到主要内容

Cline — 架构与原理

30 秒导读: Cline 是一个开源的编码 agent,跑在你的 IDE(VSCode)和终端(CLI)里。你给它一句话("修一下登录的 bug"),它会自己读文件、搜代码、跑命令、改文件,反复迭代直到任务完成。本库讲的是它的 SDK 内核:一个干净分层的 TypeScript monorepo。

1. 这是什么(零基础也能懂)

一句话定义: Cline 是一个能自己动手改你代码库的 AI agent —— 它把大模型(LLM)接上「读文件 / 搜代码 / 跑 shell / 改文件」这些工具,让模型像一个坐在你电脑前的工程师那样,一步步把任务做完。

解决什么问题 / 给谁用:

假设你在 VSCode 里写代码,想让 AI 帮你「把这个函数重构成异步的,并更新所有调用点」。普通聊天机器人只能给你一段文字让你自己粘贴。Cline 不一样 —— 它能真的去 search_codebase 找到所有调用点、read_files 读出来、用 editor 工具逐个改掉、再 run_commands 跑测试验证。给的人是:想让 AI 端到端完成编码任务的开发者

它能做什么:

  • 在两种界面运行:VSCode 扩展(带 Kanban 看板)和命令行 CLI(交互式聊天 + 无头 CI/CD 模式)。
  • 接几乎所有主流模型供应商(Anthropic、OpenAI、Google、Bedrock、Vertex、本地兼容端点……)。
  • 内置一套编码工具:读文件、正则搜索、跑命令、改文件、抓网页、调用 skills。
  • 两种工作模式:Plan(只读规划)Act(实际动手)
  • 安全护栏:循环检测、连续错误熔断、可回滚的检查点(checkpoint)。
  • 能派生子 agent、组队协作(multi-agent)。

用起来什么样:

安装就一行,然后在终端里直接对话:

npm i -g cline
cline # 进入交互式 TUI,像聊天一样下指令

SDK 的最小调用长这样(来自 ClineCore.ts 顶部的 JSDoc 示例):

// 示意,非源码(摘自 sdk/packages/core/src/ClineCore.ts 的 @example)
import { ClineCore } from "@cline/core";

const cline = await ClineCore.create({ clientName: "my-app" });
const session = await cline.start({
config: { providerId: "anthropic", modelId: "claude-opus-4-1" },
});
session.subscribe((event) => console.log("事件:", event)); // 流式看 agent 在干啥

一句话直觉/类比:

把大模型想成一个「只会动嘴」的工程师 —— 它知道该怎么改,但没有手。Cline 给它装上了手(工具),再加一个不知疲倦的工头(循环):工头反复问「下一步做什么?」,执行模型说的工具调用,把结果喂回去,直到模型说「做完了」。

本节到此为止,不碰底层。下面进入大盘。

2. 顶层全景(它大概怎么转)

Cline 的代码不是一个大文件,而是一个分层的 monorepo:越往下越通用、越无状态;越往上越贴近具体宿主(IDE / 终端)。

2.1 包的分层

职责路径
@cline/agents最内核:无状态的工具调用循环(AgentRuntime)。不含工具、不含存储sdk/packages/agents
@cline/llms多供应商网关:把各家 API 统一成一个 stream()sdk/packages/llms
@cline/shared共享类型、系统提示词、createTool 等原语sdk/packages/shared
@cline/core应用运行时:默认工具、会话存储、安全护栏、检查点、多 agentsdk/packages/core
apps/cli apps/vscode宿主:终端 TUI / VSCode 扩展,调用 @cline/coreapps/

关键的设计取舍写在 @cline/agents 的 README 里:内核只管「跑循环」,工具/存储/护栏全在 @cline/core。这样内核能在 Node、浏览器、自定义宿主里复用。

2.2 一次请求怎么流动

请求是自上而下穿过这四层的:宿主把一句话交给 SDK 门面,门面交给有状态的会话层,会话层每一轮新建一个无状态循环,循环再调网关去问模型。下面这张去程图(纵向,每层一行)读起来不依赖横向对齐:

┌───────────────────────────┐
│ CLI / IDE(宿主) │
└─────────────┬─────────────┘
│ start()

┌───────────────────────────┐
│ ClineCore(SDK 门面) │ 选 local / hub / remote 后端
└─────────────┬─────────────┘
│ 把用户消息存进会话

┌───────────────────────────┐
│ SessionRuntime(有状态会话)│ 记忆 + 护栏,活整个会话
└─────────────┬─────────────┘
│ 每个 run 新建一个一次性实例

┌───────────────────────────┐
│ AgentRuntime(无状态循环) │ while:调模型→执行工具→喂回
└─────────────┬─────────────┘
│ stream(request)

┌───────────────────────────┐
│ LLM 网关(@cline/llms) │ 抹平各家供应商,流式吐 token
└───────────────────────────┘

所有进展再沿着同一条链反向冒泡回宿主渲染 —— 这是一条独立的事件回程,不和去程箭头挤在一行:

LLM 网关 ──流式 token──▶ AgentRuntime ──工具/消息/用量事件──▶ SessionRuntime ──装护栏后转发──▶ ClineCore ──事件流──▶ CLI / IDE

怎么读这两张图: 去程图(纵向)是「谁调用谁」,顺序就是 ClineCore → SessionRuntime → AgentRuntime → 网关;回程图(横向一行)是「事件往回冒泡」。关键记两点:SessionRuntime 是会话的「记忆 + 护栏」层,它每一轮都新建一个一次性的 AgentRuntime 来跑实际的「模型↔工具」循环;循环里每次调模型都走 @cline/llms 网关。

2.3 部件一句话职责

部件干什么在哪个文件
ClineCoreSDK 对外门面:create / start / send / stop,选 local/hub/remote 后端sdk/packages/core/src/ClineCore.ts
AgentRuntime无状态的工具调用循环本体(while + 流式解析)sdk/packages/agents/src/agent-runtime.ts
SessionRuntime每会话编排器:消息存储、循环检测、连错熔断、每轮造一个 AgentRuntimesdk/packages/core/src/runtime/orchestration/session-runtime-orchestrator.ts
默认工具read_files / search_codebase / run_commands / editor / ...sdk/packages/core/src/extensions/tools/definitions.ts
LLM 网关统一各供应商的 stream(),做上下文裁剪sdk/packages/llms/src/providers/gateway.ts
检查点 hooks用 git stash 在每个 run 前打快照sdk/packages/core/src/hooks/checkpoint-hooks.ts

2.4 主线走一遍(高层)

  1. 宿主调 ClineCore.start(...),内部根据 backendMode 选一个运行时宿主(本地 / hub 守护进程 / 远程)。
  2. 会话由 SessionRuntime 管:它持有跨轮的消息历史、连错计数器、循环检测器。
  3. 用户每发一句话,SessionRuntime 把它存进对话,然后新建一个 AgentRuntime,把完整历史作为 initialMessages 喂进去。
  4. AgentRuntime 进 while 循环:调模型 → 流式拿回文本 + 工具调用 → 执行工具 → 把结果当消息追加 → 再调模型……直到模型不再要工具(或调用了「完成」工具)。
  5. 整个过程的事件(assistant-text-deltatool-startedtool-finished……)实时冒泡给宿主渲染。

3. 往下读哪一章

本项目较大,拆成五章,建议按顺序:

  1. 01-agent-loop.md — 内核 AgentRuntime:整个项目的心脏,一个 while 循环怎么把流式 token 拼成消息、解析工具调用、收尾。先读这章。
  2. 02-tools.md — 工具是什么、str_replace 精确编辑 vs apply_patch、Plan/Act 模式如何换一套工具。
  3. 03-orchestration-safety.mdSessionRuntime 怎么把无状态内核包成有记忆的会话;循环检测 + 连续错误两道护栏怎么挂成 hook。
  4. 04-llm-gateway.md — 多供应商网关的统一抽象与上下文窗口管理。
  5. 05-checkpoints-multiagent.md — git stash 检查点的巧妙实现,以及 spawn_agent 派生子 agent。

4. 代码地图(导航索引)

主题文件路径符号名
SDK 门面sdk/packages/core/src/ClineCore.tsClineCoreClineCore.createClineCore.start
内核循环sdk/packages/agents/src/agent-runtime.tsAgentRuntimeAgentRuntime.execute
会话编排sdk/packages/core/src/runtime/orchestration/session-runtime-orchestrator.tsSessionRuntimeexecuteRunInternal
默认工具工厂sdk/packages/core/src/extensions/tools/definitions.tscreateDefaultToolscreateReadFilesTool
工具预设(Plan/Act)sdk/packages/core/src/extensions/tools/presets.tsToolPresetsresolveToolPresetName
系统提示词sdk/packages/shared/src/prompt/system.tsDEFAULT_CLINE_SYSTEM_PROMPTYOLO_CLINE_SYSTEM_PROMPT
LLM 网关sdk/packages/llms/src/providers/gateway.tsDefaultGatewaycreateGateway
循环检测sdk/packages/core/src/runtime/safety/loop-detection.tsLoopDetectionTracker
连错熔断sdk/packages/core/src/runtime/safety/mistake-tracker.tsMistakeTracker
检查点sdk/packages/core/src/hooks/checkpoint-hooks.tscreateCheckpointHooks
派生子 agentsdk/packages/core/src/extensions/tools/team/spawn-agent-tool.tscreateSpawnAgentTool