Agent 架构文档 · Markdown
Cline Agent 架构全景讲解
以 Agent 的生命脉络 为主线,讲清楚 Cline 这个开源 VSCode 扩展是怎么把"对话框 + LLM" 变成"会读代码、会写文件、会跑命令、会开浏览器"的自治 coding agent。围绕 Plan/Act 双模式 + Tool use 主循环 + Checkpoint 影子 git 三根支柱展开。 适合:第一次 fork Cline 想看代码
以 Agent 的生命脉络 为主线,讲清楚 Cline 这个开源 VSCode 扩展是怎么把"对话框 + LLM" 变成"会读代码、会写文件、会跑命令、会开浏览器"的自治 coding agent。围绕 Plan/Act 双模式 + Tool-use 主循环 + Checkpoint 影子 git 三根支柱展开。
适合:第一次 fork Cline 想看代码 / 想把它和别的 coding agent 放一起对比 / 想理解 "VSCode 扩展形态的 agent" 比 server 端 agent 多出哪些设计。
2026-06-08 官方复核补丁:GitHub
cline/clinelatest release 已到v3.88.1(2026-06-07);npmclinelatest 为3.0.20,@cline/agentslatest 为0.0.43。 本文保留 2026-05 的源码/文档走读结构;版本号与 SDK/CLI 包名以本条和官方 release 为准。
#目录
- 写在前面:Cline 是什么、不是什么 0.5. 一张图看懂:Cline = Model + Harness
- Agent 是什么 —— 模型 + 系统提示 + 工具表 + 规则文件
- Agent 怎么活起来 —— 从 VSCode 激活到 Task 启动
- Agent 怎么思考 —— Plan / Act 双模式 + ReAct 主循环
- Agent 怎么行动 —— 工具系统:本地 + 浏览器 + MCP
- Agent 怎么记忆 —— Context、@ 引用、Checkpoint 与 /smol /newtask
- Agent 怎么开口 —— Webview UI + 流式 diff + gRPC 桥
- Agent 的外脑 —— 30+ Provider 与 LLM 适配层
- 关键设计权衡(架构师视角)
- 附录:组件地图、关键概念与源码索引
#零、写在前面:Cline 是什么、不是什么
Cline(前身 Claude Dev)是一个 开源 VSCode 扩展,把 LLM 装进侧边栏,
让它在用户的本地工作区里读文件、写文件、跑终端、开浏览器、调 MCP server。
仓库在 github.com/cline/cline,npm 也提供 cline CLI 包。
消歧:本文专指
cline/cline这一支。Roo Code(前 Roocline) 是 Cline 的 fork, 加了多 mode、apply_diff 等差异化能力,不是本文主角,只在第八章提一次作为衍生物对照。 其它同名工具一律忽略。
理解 Cline 之前,先认这三个核心矛盾——后面每一章都会回到这里:
| 矛盾 | Cline 的回答 |
|---|---|
| 想完全自治执行,又怕模型乱写文件/跑命令 | Plan/Act 双模式 + 每一步必须 approval + Checkpoint 影子 git 兜底回滚 |
| 本地工作区上下文是无限的,LLM context 是 200k | @file/@folder/@problems/@terminal/@git 显式引用 + /smol 自压缩 + /newtask 切上下文 |
| 想多模型自由切换,又要一致的工具行为 | ApiHandler 抽象层 + ToolExecutor 统一路由 + 30+ provider 各自实现流式适配 |
"VSCode 扩展形态"决定了 Cline 没有 server,没有数据库,没有多租户;
所有状态都落在用户本机的 ~/.cline/data/ 和工作区的 .clinerules/。
#零·五、一张图看懂:Cline = Model + Harness
业界视角:Anthropic / Cursor / Codex / Aider / Cline 用的是同一批底层模型,实际表现差距却很大。 差的不是模型,是"模型之上的外壳(Harness)"——指令、工具、基础设施、可观测性这四层共同决定 agent 的真实能力上限。
Cline 是这套视角的极端样本:它把 harness 完全压缩进一个 VSCode 扩展进程里,没有 server、没有 DB、 没有 trace 后端,所有四层都跑在用户本机。这种"零基础设施 harness"让 Cline 启动极快、隐私强、可 fork, 但也意味着可观测性几乎为零。下文按"4 层 + 8 支柱"反向索引本文档每个章节。
#0.5.1 四层 Harness 结构
┌──────────────────────────────────────────────────────────────────────┐
│ Agent = Model (30+ provider) + Harness (VSCode 扩展进程) │
└──────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
│ ① 指令层 │ 内置 system prompt (src/core/prompts/system-prompt/) → §1.1│
│ │ `.clinerules/` 目录(工作区 + 全局,注入 system) → §1.2│
│ │ Plan/Act 模式切换(不同 prompt 套件) → §3.1│
│ │ slash 命令改思考链路(/deep-planning / /smol 等) → §3.5│
├──────────────────────────────────────────────────────────────────────┤
│ ② 能力层 │ 20+ 件内置工具(read/write/replace/execute/browser)→ §1.3│
│ │ `replace_in_file` SEARCH/REPLACE block(差异化) → §4.5│
│ │ Puppeteer + 本地 Chromium 浏览器 → §4.3│
│ │ MCP Hub(stdio + SSE,含 Marketplace) → §4.4│
│ │ 30+ provider 适配(Anthropic / OpenRouter / Ollama) → §7.1│
├──────────────────────────────────────────────────────────────────────┤
│ ③ 基础设施│ ~/.cline/data/ 本地存储(task history + state 镜像) → §5.1│
│ │ Checkpoint 影子 git(每 step commit,3 粒度 restore) → §5.3│
│ │ Auto-Approve 分级开关 + Plan/Act 双模式 → §3.1 / §4.2│
│ │ VSCode terminal API + shell integration → §4.5│
│ │ Webview gRPC over postMessage 桥 → §6.1│
│ │ ⚠ 无 server / 无 DB / 无多租户 │
├──────────────────────────────────────────────────────────────────────┤
│ ④ 可观测 │ UI 实时 cost 显示(input/output tokens + 美元) → §5.5│
│ │ PostHog telemetry(可关闭)+ Sentry error → §9.3│
│ │ Loop detection(连续相同 tool call 计数) → §4.5│
│ │ ⚠ 无 trace / 无 metrics 后端 / 无团队级聚合 — 本地扩展形态决定 │
└──────────────────────────────────────────────────────────────────────┘
#0.5.2 八支柱对照表
| # | Harness 支柱 | 一句话定义 | Cline 的实现 | 对应章节 |
|---|---|---|---|---|
| 01 | FS + Git | state 必须活在 context 之外 | .clinerules/ 入 git + Checkpoint 影子 git 兜底每步快照 + ~/.cline/data/taskHistory.json 跨 session 持久 |
§1.2 / §5.3 / §5.1 |
| 02 | Bash 通用工具 | "随用随装",避免 token 爆炸 | execute_command 走 VSCode terminal API + shell integration;MCP Marketplace 一键装外部能力 |
§4.5 / §4.4 |
| 03 | 沙箱 + 子工具 | 行动可隔离 + 可自检 | 无物理沙箱——靠 Plan Mode(strictPlanModeEnabled 软隔离)+ Auto-Approve 分级 + Checkpoint 兜底回滚;危险靠回滚不靠隔离 | §3.1 / §4.2 / §5.3 |
| 04 | 记忆 + 搜索 | 跨 turn / 跨 project 拿历史 | 无向量记忆 / 无 retriever——@ 引用纯 token 暴力注入(@file/@folder/@problems/@terminal/@git/@url);ripgrep + tree-sitter 做代码搜索 | §5.2 / §4.1 |
| 05 | 对抗 Context Rot | 长对话也别糊 | /smol 让 LLM 自压缩 history(同 task 瘦身)+ /newtask 把进度打包开新 task(清 context);无 server-side compaction |
§5.4 |
| 06 | 长程执行 | 多 phase 任务不跑偏 | Plan Mode 强制先想再做 + /deep-planning 强化推理 prompt + plan/act 各选模型(plan 用 Opus 想透、act 用 Sonnet 落地) |
§3.1 / §3.5 / §7.3 |
| 07 | Hooks 强制层 | 失败转成永久规则 | Loop Detection 卡连续相同调用 + consecutiveMistakeCount>3 触发问用户;规则永久化只能人工写 .clinerules/;无自动 ratchet 机制 |
§4.5 / §3.3 |
| 08 | 规划 + 工具选择 | 别什么都试,先想再调 | Plan/Act 双模式是 Cline 最有辨识度的设计——plan 阶段工具表受限,只能读 + plan_mode_respond,不能写;YOLO 模式可跳过 plan 自动落地 |
§3.1 / §3.4 |
#0.5.3 当前架构的短板(按 Harness 视角看出来的)
Cline 的指令层 / 能力层 / 基础设施层针对"单机 IDE agent"打磨得很完整,但可观测性层接近零—— 这不是疏忽,而是"零基础设施 harness"的逻辑必然。文档现状:
- ✅ 有:UI 实时 cost 显示(同台机一目了然)、Loop Detection、PostHog/Sentry(可关闭)
- ❌ 缺:长任务可观测性几乎为零——没有 trace、没有 metrics 后端、没有跨 task 聚合视图。 跑一晚的 YOLO task 出问题,事后只能在 webview 滚动 chat history 找线索,没有结构化的失败模式聚合
- ❌ 缺:多模型一致性不强——30+ provider 各自实现
ApiHandler,tool calling 在 Anthropic / OpenAI / Ollama 上行为不一致(特别是本地模型常退化到 prompt-style tool 模拟),同一份.clinerules/换 provider 表现飘忽 - ❌ 缺:没有 cross-session 记忆——
taskHistory.json只是历史归档,不是可检索的"经验库"。 agent 上次踩过的坑这次不会自动避开,靠用户手工把"教训"写进.clinerules/(Cline 不会自己改) - ❌ 缺:Plan-Act 切换的状态机不显式——
togglePlanActModeProto走 gRPC,但 plan 阶段的"已对齐意图" 没有结构化产出,只是 chat 历史的一部分;切到 act 后 agent 是否真的按 plan 走,没有 hook 强制
这是 Cline 押"本地优先 = 信任优先"路线的代价。补可观测性层意味着要起 server / DB / 跨设备同步——而这恰好是
Cline 刻意避开的复杂度。Roo Code 等 fork 在 cloud layer 上探索,方向就是补这块。Harness 的"The Ratchet 方法论"
(每一次失败 → 一条永久规则)在 Cline 里完全靠 .clinerules/ 人工沉淀,与 Codex AGENTS.md 同一逻辑但更原始。
#一、Agent 是什么 —— 模型 + 系统提示 + 工具表 + 规则文件
在 Cline 里,"一个 Agent" = 一份 System Prompt + 一份内置 Tool 表 + 一组
.clinerules/+ 用户选定的模型。 不像 server 端 agent 平台用数据库表来定义 agent,Cline 的 agent "定义"就是配置文件 + 代码常量。
#1.1 四件套:Agent 定义的物理形态
| 组成 | 物理位置 | 谁能改 |
|---|---|---|
| System Prompt | src/core/prompts/system-prompt/ |
Cline 维护者 |
| 内置工具表 | src/core/task/tools/ToolExecutorCoordinator.ts + tools/handlers/ |
Cline 维护者 |
.clinerules/ |
工作区 .clinerules/*.md + ~/Documents/Cline/Rules/ |
用户(每项目可定制) |
| 模型 + provider | StateManager → ~/.cline/data/ |
用户(设置面板) |
加上用户对话里的 @ 引用、@mention 注入的上下文,就构成了一次推理的全部输入。
#1.2 .clinerules/ 的两层结构
.clinerules 是 目录,不是文件(这点经常被新人弄错):
~/Documents/Cline/Rules/ # 全局规则(所有 workspace 共享)
└── style.md
your-project/.clinerules/ # 工作区规则(随 git 入库)
├── 01-coding.md # 数字前缀只是组织手段,不影响加载顺序
├── testing.md
└── architecture.md
加载规则:
- Cline 把
.clinerules/下所有.md/.txt拼起来,注入到 system prompt - 工作区规则优先级 > 全局规则(冲突时工作区赢)
- 文件可以带 YAML frontmatter,用
paths:glob 限定只在某些文件激活 - UI 里有"Rules"开关,可以临时禁用某条规则
#1.3 内置工具表(当前 20+ 件,分六类)
早期版本(≈2024)只有 13 件经典工具;当前 main 分支已扩展到 20+ 件,按
src/core/task/tools/handlers/实际文件清单(每个文件一个 Handler):
读 写 交互/收尾
─ read_file ─ write_to_file ─ ask_followup_question
─ list_files ─ replace_in_file ─ attempt_completion
─ search_files (ripgrep) ─ apply_patch ─ plan_mode_respond
─ list_code_definition_names ─ act_mode_respond
─ new_task
执行 外联 上下文/元
─ execute_command ─ browser_action ─ condense
─ use_mcp_tool ─ summarize_task
─ access_mcp_resource ─ generate_explanation
─ load_mcp_documentation ─ report_bug
─ web_fetch ─ use_skill
─ web_search ─ subagent
分类要点:
- plan_mode_respond / act_mode_respond:两模式下 agent 出"陈述性回复"(不调动作工具)的专用工具
- apply_patch:unified diff 形态的写入,与
replace_in_file的 SEARCH/REPLACE block 并存 - web_fetch / web_search:新加入的内置 web 能力,独立于
browser_action(Puppeteer) - condense / summarize_task:服务于
/smol、/newtask等上下文压缩链路 - use_skill:触发
.clinerules/中带 frontmatter 的 skill(详见 §1.2) - subagent:派生子 agent 跑独立 sub-task(与
new_task区别:subagent 是同 task 内并行/隔离,new_task 是切换 task)
每个工具在 src/core/task/tools/handlers/ 下都有对应的 Handler,由
ToolExecutorCoordinator 维护 name→handler 映射,ToolExecutor 统一路由(详见第四章)。
#1.4 跟 server 端 agent 的最大不同
Cline 没有 agent 表,因为:
- 单用户:没必要做 agent 复用与版本化
- 工具表是写死的:用户能扩的是 MCP server,不是改 system prompt 加新工具
- "切换 agent"在 Cline 语义里是"切换模型 + 切换
.clinerules"
这是 IDE 扩展形态的天然约束:所有 agent 个性化都要能放进文件系统。
#二、Agent 怎么活起来 —— 从 VSCode 激活到 Task 启动
用户在 VSCode 里点一下侧边栏 Cline 图标,敲一句 "帮我把 X 改成 Y",背后走的是 一条从
extension.ts→Controller→Task→ApiHandler的链路。 这条链路在每个 task 上只活一次,但任务期内 task 实例长生命周期。
#2.1 启动链路
VSCode 启动事件
│
▼
src/extension.ts: activate(context)
│ ├─ setupHostProvider(context) 注入 VSCode 抽象(共享给 CLI)
│ ├─ cleanupLegacyVSCodeStorage(context) 一次性迁移老存储
│ ├─ exportVSCodeStorageToSharedFiles() 复制到 ~/.cline/data/
│ └─ initialize(storageContext) 调用 src/common.ts
│ ├─ Logger / StateManager / ClineEndpoint
│ ├─ ErrorService / PostHogClientProvider
│ ├─ AuthService / BannerService / FeatureFlagsService
│ └─ WebviewProvider 实例(claude-dev.SidebarProvider)
▼
用户在侧边栏输入消息
│
▼
WebviewProvider 收到 gRPC 调用 (newTask / sendMessage)
│
▼
Controller (src/core/controller/)
│ ├─ 维护当前 Task 生命周期
│ ├─ 处理 webview 来的 grpc 请求
│ └─ new Task(...) 启动
▼
Task (src/core/task/index.ts)
│ ├─ 拼 system prompt(用户配置 + .clinerules + 当前 mode)
│ ├─ 收集 @ 引用(@file/@folder/@url 等)
│ ├─ 起 ApiHandler(按 plan_mode / act_mode 选 provider)
│ └─ recursivelyMakeClineRequests() ← 主循环入口
▼
ToolExecutor → Handler → 渲染回 Webview
#2.2 关键类的职责切分
| 类/模块 | 文件 | 一句话职责 |
|---|---|---|
WebviewProvider |
src/core/webview/ |
创建侧边栏 React app,跑 message bridge |
Controller |
src/core/controller/index.ts |
接 gRPC 请求,管 Task 生命周期 |
Task |
src/core/task/index.ts |
一个 task = 一段 agentic 推理循环 |
ToolExecutor |
src/core/task/tools/ |
解析 LLM 输出的 tool block,路由到 handler |
ToolExecutorCoordinator |
src/core/task/tools/ToolExecutorCoordinator.ts |
维护 tool name → handler 映射 |
ToolValidator / autoApprove |
src/core/task/tools/ |
参数校验 + auto-approve 判定 |
ApiHandler |
src/api/index.ts + src/api/providers/ |
LLM provider 抽象,吐流式 token |
StateManager |
src/core/storage/StateManager.ts |
全局/工作区状态,跨 session 持久化 |
McpHub |
src/services/mcp/ |
管 MCP server 连接、工具发现、调用 |
#2.3 一次 task 的状态机
idle ─── newTask ──▶ planning (mode=plan)
│
toggle │ act
▼
acting (mode=act)
│
tool ──┤── attempt_completion ──▶ done
│
ask_followup_question
▼
waiting_user
TaskState 里关键字段(src/core/task/TaskState.ts):
consecutiveMistakeCount:连续工具调用失败计数,触发 loop detectiondidAlreadyUseTool:单轮内是否已用过工具(防并行)toolUseIdMap:原生 tool calling 的 id → block 映射
#三、Agent 怎么思考 —— Plan / Act 双模式 + ReAct 主循环
Cline 最有辨识度的设计:让 agent 在"想清楚"和"动手做"之间显式切档。 这一章解释为什么这个分裂是必要的,以及切档时引擎的什么变了。
#3.1 Plan vs Act:两种"agent 人格"
| Plan Mode | Act Mode | |
|---|---|---|
| 能做 | 读文件、ripgrep、问澄清、聊方案 | 写文件、跑命令、开浏览器、调 MCP |
| 不能做 | 任何写操作(strictPlanModeEnabled 强制阻断) |
—— |
| 典型工具 | read_file / search_files / list_files / list_code_definition_names / plan_mode_respond / ask_followup_question |
全部工具 + act_mode_respond |
| 目的 | 探索 + 对齐意图,省钱省时间 | 执行 + 落地 |
| 可独立配置模型 | 是(planActSeparateModelsSetting=true) |
是 |
经典用法:Plan 用 Opus 想透 → Act 用 Sonnet 快速落地,省 70% 成本。
#3.2 模式切换的实现
StateManager.mode # "plan" | "act"
StateManager.planActSeparateModelsSetting # 是否双模型
StateManager.strictPlanModeEnabled # plan 严禁写
StateManager.yoloModeToggled # YOLO:plan 完自动切 act + auto-approve
切换走 togglePlanActModeProto RPC(proto/cline/state.proto):
UI 点切换按钮 (webview-ui/src/components/chat/ChatTextArea.tsx)
│ gRPC
▼
StateService.togglePlanActModeProto
│
├─ StateManager 更新 "mode" 键
├─ 若有运行中 task: Controller.task.api = buildApiHandler(<新 mode 的 provider>)
└─ 广播新 ExtensionState 给 webview
注意切档不会清空 history,Plan 阶段读出来的所有上下文会保留进 Act 阶段。 这才是双模式真正的价值所在——不是"重新开始",是"换一副工具"。
#3.3 ReAct 主循环
Task.recursivelyMakeClineRequests() 内部就是经典 ReAct,但加了流式:
loop:
1. 拼 messages(system + history + user@mentions)
2. ApiHandler.createMessage(messages, tools) → 返回 stream
3. 从 stream 边收边解析:
text 块 → 直接 push 到 webview(流式渲染 markdown)
tool_use 块 partial → ToolExecutor.partial(...)(更新 UI 占位,不执行)
tool_use 块 final → ToolExecutor.execute(...)(真正调工具)
4. tool 结果 → 加进 userMessageContent
5. 若上一次工具是 attempt_completion → break
6. 若 consecutiveMistakeCount > 3 → 触发 loop detection,问用户
7. 否则继续 loop
关键点:
- partial / final 两阶段渲染:tool block 在 LLM 还没吐完时就开始在 UI 占位, 写文件时还没流完已经在 diff 视图里看到部分内容
- 每个 tool 默认要 approval:Auto-approve 配了的除外(见第四章)
- 每步 checkpoint:tool 执行完,影子 git 自动 commit 一次(见第五章)
#3.4 YOLO 模式:把所有保险全拆掉
yoloModeToggled=true 时:
- 所有 auto-approve 项默认开
- Plan 模式的 agent 自己决定"我准备好了"就自动切 Act
- 工具调用全部跳过 approval
文档里专门贴了警告:"This is dangerous. Cline executes whatever it decides without asking permission"。 适合在 sandbox / docker 里跑全自动 agent,不要在主仓库开。
#3.5 几个 Slash Commands 是怎么改思考链路的
按官方 docs(docs.cline.bot/core-workflows/using-commands)当前命令清单:
| 命令 | 改了什么 |
|---|---|
/newtask |
把当前 task 的"plan + 已完成的事 + 相关文件 + 下一步"打包成 prompt,开新 task(清 context) |
/smol(别名 /compact) |
让 LLM 给当前 history 出一份压缩摘要,替换原 history(同 task 内瘦身) |
/newrule |
引导式生成 .clinerules/ 规则文件(沟通风格 / 编码规范 / 项目约定) |
/deep-planning |
切到一套强化推理 prompt,强制先产出多步计划再开始(要 GPT-5/Claude 4 级模型) |
/explain-changes |
对 git diff 出 AI 解释(commits / branches / PR 范围,VS Code only) |
/reportbug |
走一套对话式 bug report 收集,自动 POST 到 Cline GitHub Issues |
此外,.clinerules/ 里启用的 Skill 也可直接以 /<skill-name> 触发,等效于把对应 skill 文件以"专家身份"注入当前 task(由 use_skill 工具实现)。
#四、Agent 怎么行动 —— 工具系统:本地 + 浏览器 + MCP
Cline 的"行动力"来自三类工具:本地工具(FS / 终端)+ 浏览器(Puppeteer 跑无头 Chrome)+ MCP server。 三类共享一个 ToolExecutor 调度器和一套 approval 机制。
#4.1 ToolExecutor 调度全图
LLM stream
│
▼
parseAssistantMessage() ─── 拆 text / tool_use 块
│
▼
ToolExecutor.handleToolUse(block)
│
├─ block.partial = true → ToolExecutorCoordinator.partial(handler, block)
│ └─ 仅刷新 UI(diff 占位、写入指示器)
│
├─ block.partial = false → AutoApprove.shouldAutoApprove(toolName, args)?
│ ├─ 是 → 直接执行
│ └─ 否 → push approval message → 等用户点 ✓ / ✗
│
└─ Coordinator.dispatch(toolName) → Handler.execute(args)
│ (handlers 实际在 src/core/task/tools/handlers/)
├─ ReadFileToolHandler (含 read_files 批量)
├─ WriteToFileToolHandler (含 replace_in_file 模式)
├─ ApplyPatchHandler (unified diff 形态写入)
├─ SearchFilesToolHandler (ripgrep)
├─ ListFilesToolHandler / ListCodeDefinitionNamesToolHandler
├─ ExecuteCommandToolHandler (检查 CommandPermissionController)
├─ BrowserToolHandler (走 BrowserSession,Puppeteer)
├─ WebFetchToolHandler / WebSearchToolHandler
├─ UseMcpToolHandler (走 McpHub.callTool)
├─ AccessMcpResourceHandler / LoadMcpDocumentationHandler
├─ AskFollowupQuestionToolHandler(挂起,等 webview 回消息)
├─ AttemptCompletionHandler (收尾,可选最终命令)
├─ PlanModeRespondHandler / ActModeRespondHandler
├─ CondenseHandler / SummarizeTaskHandler (/smol /newtask 链路)
├─ GenerateExplanationToolHandler (/explain-changes)
├─ ReportBugHandler / UseSkillToolHandler
├─ SubagentToolHandler (同 task 内派生子 agent)
└─ NewTaskHandler (切 task 拆 sub-task)
#4.2 Auto-Approve:让 agent 跑多远
Auto-approve 是个分级开关(设置面板 / ~/.cline/data/),默认全部关闭:
| 类别 | 开关项 | 风险 | 备注 |
|---|---|---|---|
| 文件读 | Read project files / Read all files | 低 / 中 | all 允许出 workspace,需先开 project |
| 文件写 | Edit project files / Edit all files | 中 / 高 | all 需先开 project |
| 命令 | Execute safe commands / Execute all commands | 中 / 极高 | all 需先开 safe,等于把白名单去掉 |
| 浏览器 | Use the browser | 中 | 控制 browser_action + web_fetch/web_search |
| MCP | Use MCP servers | 中 | 取决于具体 server |
| 通知 | Enable notifications | —— | 长跑命令 / 等待批准时的系统通知 |
关键约束:扩展开关("all files"、"all commands")只有在对应基础开关启用后才生效, 不是独立两档;这是产品上避免误操作的小设计。
判定走 AutoApprove 类(位于 src/core/task/tools/autoApprove.ts,被 ToolExecutor 调用),
每个工具调用 shouldAutoApprove(name, args),返回 false 就 push 一条带 ✓/✗ 按钮的 message 到 webview。
YOLO Mode 与 Auto-Approve 的区别:Auto-Approve 是"按类别授权",YOLO 是"全部放开 + Plan→Act 自动切"—— YOLO 默认勾上所有 auto-approve 项 + 跳过 plan_mode_respond 的"等用户确认才切 act"步骤。
#4.3 浏览器工具:本地 Puppeteer + Chromium
browser_action 走 BrowserSession(src/services/browser/),由 BrowserToolHandler 调度:
- 后端:Puppeteer 驱动 Chromium(不是 Playwright)
- Chromium 解析顺序:
- 用户配的 chromeExecutablePath
- 系统 Chrome(
chromeLauncher.Launcher.getFirstInstallation()) - Puppeteer-Chromium-Resolver 自动下载捆绑版
- 支持的动作:launch / click / type / scroll_down / scroll_up / close
- 每步自动截图,console.log 也一并捕获回上下文
- 强约束:browser session 未 close 之前不能调其它非浏览器工具(BrowserToolHandler 内部强制)
- 模型要求:原本绑死 Claude Sonnet 的 Computer Use,现在大多数模型都能用(坐标用截图引导)
注意 ARM Linux 上 Chromium 长期有兼容问题(issue #1673)。
browser_action vs web_fetch / web_search(后两者是新加入的内置工具):
| 工具 | 后端 | 适用场景 |
|---|---|---|
browser_action |
Puppeteer + 本地 Chromium | 真交互页面(点按钮、填表单、看 SPA 状态) |
web_fetch |
直接 HTTP + HTML→Markdown | 抓 doc / blog 等静态内容,省一个 Chromium |
web_search |
走 provider 自带搜索或内置 | 查"最新的某 API 文档" |
Auto-Approve 里的 "Use the browser" 同时控制这三类(统一归"浏览器/网络出口")。
#4.4 MCP Hub:把外部能力也变成 tool
~/Documents/Cline/MCP/cline_mcp_settings.json
│
▼
McpHub (src/services/mcp/)
│ ├─ 启动每个 server(stdio 子进程 / SSE)
│ ├─ 调 list_tools / list_resources 拿能力清单
│ └─ 把这些能力作为 use_mcp_tool / access_mcp_resource 的合法参数
▼
LLM 发起 use_mcp_tool(server_name, tool_name, args)
│
▼
UseMcpToolHandler → McpHub.callTool() → server stdin/stdout JSON-RPC
│
▼
返回结构化结果 → 进 history
Cline 是 MCP 早期采用方之一,与 Claude Desktop 一同被列为参考实现。 对比 Claude Desktop:
- Cline 自带 MCP Marketplace(设置面板里能浏览 / 一键安装)
- 支持 stdio + SSE 两种 transport
- 用户可以让 agent 自己写 MCP server:"add a tool that..."
#4.5 工具执行的几个隐藏细节
replace_in_file是 Cline 的差异化设计:传 SEARCH/REPLACE block 而不是 unified diff, 比让模型生成 diff 稳得多,但仍需要"看完整文件"作为代价 (Roo Code 的 fork 替成apply_diff只输出变更行,省 token,是它最大区分点)execute_command走 VSCode terminal API,输出回收靠 shell integration, 在 Windows / macOS / Linux 三平台行为差异不小(终端集成是 Cline 长期 issue 来源)- 每个工具结果都有 size 上限:超大文件会截断 + 提示,避免一次塞爆 context
- loop detection:
src/core/task/loop-detection.ts检测连续相同 tool call, 达到阈值会自动停下来问用户(防"agent 鬼打墙"烧钱)
#五、Agent 怎么记忆 —— Context、@ 引用、Checkpoint 与 /smol /newtask
Server 端 agent 用 PG/Milvus/Neo4j 做长记忆。Cline 是单机扩展,所有"记忆"都落 在用户文件系统上:history 在
~/.cline/data/,工作区上下文在.clinerules/, 历史快照在影子 git。但内核问题相同——LLM context 是有限的,agent 想看的东西是无限的。
#5.1 三层记忆模型
┌────────────────────────────────────────────┐
长期 │ ~/.cline/data/taskHistory.json │ 跨 task 持久化
│ ├─ 每个 task 的 messages │ StateManager 写入
│ └─ 元信息(cost / 用时 / 检查点) │
└────────────────────────────────────────────┘
▲
│ Task 启动时按 id 读取
│
┌────────────────┴───────────────────────────┐
工作 │ Task.apiConversationHistory │ 单 task 内
│ + Task.userMessageContent │ in-memory
│ + 当前回合 stream buffer │
└────────────────────────────────────────────┘
▲
│ 每轮 LLM 调用时重新拼装
│
┌────────────────┴───────────────────────────┐
即时 │ System prompt 里塞的: │ 每次请求重算
│ - .clinerules 合并内容 │
│ - 工作区文件树(top-level) │
│ - 当前 mode (plan/act) 标记 │
│ + 用户消息里的 @ 引用展开 │
└────────────────────────────────────────────┘
#5.2 @ 引用:用户控的 context 注入
| 引用 | 注入什么 |
|---|---|
@/path/to/file |
完整文件内容(带 import 上下文) |
@/path/to/folder/ |
整个目录树 + 每个文件全文 |
@problems |
VSCode Problems 面板里的 errors/warnings |
@terminal |
最近终端输出(保留格式) |
@git-changes 或 @<commit-hash> |
uncommitted diff 或某个 commit 的 diff |
@https://example.com |
webfetch 抓回该页面 markdown |
注意:
- @file 不能引用 hidden directory(
.foo/),是个长期 issue(#453 / #4357) - @url 走的是 Cline 自己的 fetcher,不是 LLM 自带 web search
- @ 引用展开后直接拼进 user message,不经过任何 retriever / 向量召回,纯 token 暴力
#5.3 Checkpoint:影子 git 兜底
每次工具执行完(文件编辑、命令、浏览器动作等),Cline 会把 workspace 当前状态 commit 到一个与项目 git 完全隔离的影子仓库。流程:
tool 执行成功
│
▼
checkpoints/ShadowGit.add(.) → git commit -m "<step n>"
│
▼
push 一条 "Checkpoint" 卡片到 webview,挂 Restore 按钮
特点:
- 不污染项目的
.git——影子仓库放在工作区外(按 workspace hash 分目录),主仓库提交保持干净 - 包括 .gitignore 里的文件——影子仓库忽略主仓库的 .gitignore 规则,避免漏抓临时产物
- commit 粒度 = 单次 tool use——三次连续 edit 产生三个 checkpoint,可任意 step 回滚
- UI 上每个 step 旁边有 "Restore" 按钮,三种粒度:
- Restore Files Only:撤代码改动,留对话(适合"代码崩了但讨论还有用")
- Restore Task Only:删后续对话,文件不动(适合"想重新换种 prompt 试试")
- Restore Files & Task:两个都撤(完全重来)
实现位置:src/integrations/checkpoints/。具体物理存储路径(用户 home 下 .cline/ 或 workspace 内)
随版本调整,详见源码(待核实)。docs 提示:大仓库可能因 checkpoint 占盘 / 影响速度而选择关闭。
这是 Cline 区别于 Cursor/Claude Code 的核心安全网——让 YOLO 模式有底气。
#5.4 Context 太长了怎么办
LLM 200k context,跑一会儿很容易塞满。Cline 给了两条路:
路线 A: /smol(同 task 内瘦身)
现 history (180k tokens)
│
▼ /smol 触发 LLM 自压缩
summary (10k) + 最近 N 轮原文 (20k)
│
▼
继续在同一 task 里聊
路线 B: /newtask(切 task)
当前 task plan + 已完成项 + 关键文件 + 下一步
│
▼ 打包成新 task 的初始 user message
开 task #2,清空 history
判定怎么用哪个(官方推荐):
- 同一个调试链路深挖 →
/smol - 阶段切换(feature A 做完进 feature B) →
/newtask
#5.5 Cost Tracking:每个 task 都贴价签
Cline 在 UI 显眼位置显示当前 task 的累计:input tokens / output tokens / 美元成本。
实现:每次 ApiHandler 调用结束,从 provider 返回的 usage 对象拿数字,
按 model_info 里的 per-1k 价格换算。这套数据顺带也喂给 telemetry。
这是个不起眼但极重要的产品决策——让用户对成本有实时感知,否则 YOLO 一晚醒来账单 $200。
#六、Agent 怎么开口 —— Webview UI + 流式 diff + gRPC 桥
Cline 的 UI 是个跑在 VSCode webview 里的 React app(Vite 构建)。它和扩展主进程 之间走 gRPC(不是简单 postMessage),方便共享给 CLI / standalone 等其它 host。
#6.1 Host ↔ Webview 通信
extension host (Node) webview (React, Vite)
─────────────────── ────────────────────
src/core/controller/ webview-ui/src/
├─ grpc-handler.ts ├─ components/
├─ grpc-service.ts ├─ services/grpc-client.ts
└─ grpc-request-registry.ts └─ App.tsx
▲ ▲
│ gRPC over postMessage │
└────────────────────────────────┘
proto/cline/*.proto
gRPC 服务面(部分):
StateService:状态读写、togglePlanAct、settings 更新TaskService:开 task / 取消 / restore checkpointMcpService:MCP server 增删改查BrowserService:浏览器会话管理FileService:@ mention 文件 picker 后端
#6.2 流式渲染的关键组件
| 组件 | 作用 |
|---|---|
ChatRow / ChatView |
渲染消息列表,区分 user / assistant / tool / approval |
BrowserSessionRow |
浏览器步骤分页 + 截图缩略图 |
BrowserActionBox |
单条 browser action 的人类可读描述 |
ChatTextArea |
输入框 + @ mention popover + plan/act toggle |
CodeBlock + diff renderer |
边流式接收边渲染 unified diff |
Cline 的 diff 不是收完整段再渲染,而是 partial-tool-block 阶段就开始喂前端。 用户能看到代码一行一行写出来,配合 VSCode 自带的 diff editor 高亮。
Streaming output 三阶段:
LLM provider 流式吐 token
│
▼ ① assistant-message/parseAssistantMessage 边收边解析
text / tool_use 分块;tool_use 解析出来仍带 partial=true
│
▼ ② ToolExecutorCoordinator.partial(handler, block)
handler 的 partial 实现:write_to_file 把已收到的内容写进 diff editor
replace_in_file 把 SEARCH/REPLACE 已收齐部分预览出来
│
▼ ③ stream 收完 → partial=false
触发真正的 execute(),做最终落盘 + checkpoint commit
这套机制让"Cline 在写一个长文件"看起来是真的"边想边写",而不是"卡住几秒钟然后刷一坨"。
代价是 partial 渲染要小心:用户在 stream 中途按 Cancel,要能撤掉已经写进 diff editor 的预览
(StreamChunkCoordinator / StreamResponseHandler 负责管这块状态机)。
#6.3 通知与中断
- 长跑命令:超过阈值(默认 30s)发系统通知 "Cline is waiting for command"
- 用户中断:UI 上"Cancel"按钮 → gRPC →
Task.abortTask()→ 中断当前流,影子 git 不再 commit - 错误:写文件失败 / 命令 exit code != 0 → push 错误消息回 history,让 LLM 自我纠正
#七、Agent 的外脑 —— 30+ Provider 与 LLM 适配层
Cline 不绑死任何模型。
ApiHandler是个抽象接口,每个 provider 实现一份, 30+ 个文件躺在src/api/providers/。这一层换得勤,是 Cline 升级最快的地方。
#7.1 Provider 全景
src/api/index.ts: buildApiHandler(provider, config) → ApiHandler
src/api/providers/ # 30+ 个文件,每个一个 provider
├─ anthropic.ts Claude(直连 + Vertex AI + Bedrock 三个变种)
├─ openrouter.ts OpenRouter(最常用,单 key 多模型)
├─ openai.ts OpenAI 官方 + 任何 OpenAI 兼容端点
├─ openai-native.ts 带 reasoning effort 的 GPT-5 等
├─ gemini.ts Google Gemini
├─ bedrock.ts AWS Bedrock
├─ vertex.ts GCP Vertex AI
├─ ollama.ts 本地 Ollama
├─ lmstudio.ts 本地 LM Studio
├─ deepseek.ts / qwen.ts / moonshot.ts / xai.ts ...
├─ groq.ts / cerebras.ts / fireworks.ts / together.ts ...
├─ vercel-ai-gateway.ts Vercel AI Gateway(README 已正式列入)
└─ cline.ts Cline 自家托管(ClineEndpoint,含一些专用模型)
#7.2 ApiHandler 接口
每个 provider 实现:
interface ApiHandler {
createMessage(systemPrompt, messages, tools): AsyncIterable<ApiStreamChunk>;
getModel(): { id: string; info: ModelInfo };
}
ApiStreamChunk 是统一的流块类型,包含:
text/reasoning/tool_use/usage等子类型- 各 provider 内部把自家 SDK 的流式事件 normalize 成这套
ModelInfo 带 maxTokens / contextWindow / 价格,UI 和 cost tracking 都依赖它。
#7.3 Plan / Act 各选各的模型
打开 planActSeparateModelsSetting,StateManager 会维护两套:
planModeApiProvider / planModeApiModelId / planModeApiKey
actModeApiProvider / actModeApiModelId / actModeApiKey
Controller 在 mode 切换时调 buildApiHandler(<对应配置>) 替换 task 当前 ApiHandler。
这意味着 plan 用 OpenRouter Opus、act 用本地 Ollama 也是合法组合。
#7.4 OpenRouter 的特殊地位
社区里大部分 Cline 用户是 OpenRouter 用户:
- 一个 key 覆盖几十个模型
- 不需要每个 provider 单独申请
- 能直接看到 token 价格 + 速率
- 失败自动 fallback 模型
- Cline 在 README 把它放在第一位推荐,不是巧合
但缺点是延迟略高 + 对 prompt caching 支持取决于具体 provider 中转情况。
#7.5 本地模型路线
Ollama / LM Studio 走 OpenAI 兼容协议,配置 baseURL 指向 localhost:11434 即可。
但要意识到:
- 大多数本地模型 tool calling 不稳,Cline 在很多本地模型上要走 prompt-style tool 模拟
- context 通常只有 8k–32k,跑稍大项目就紧
- 适合"探索 / 学习 / 隔离敏感代码",不适合生产 agent
#八、关键设计权衡(架构师视角)
五条权衡,每条三段式:问题 / Cline 的回答 / 启发。
#8.1 怎么平衡 agent 自治与用户控制?
- 问题:完全 auto-approve = 危险(可能
rm -rf /),完全人工 approve = 慢到失去 agent 价值。 - Cline 的回答:分级 auto-approve(按工具种类 + 项目内/外双轴)+ Plan/Act 双模式(plan 天然不会破坏)+ Checkpoint 兜底(出事就 restore)。三层叠加,给用户连续光谱而不是开关。
- 启发:自治不是个布尔值,是个风险预算分配问题。让用户在不同维度上独立调,比一个总开关好用得多。
#8.2 Plan vs Act 这种显式分裂值不值?
- 问题:很多 agent 框架(Claude Code / Cursor)就一个连续模式,Cline 偏要分两段,用户每次切档增加心智负担。
- Cline 的回答:对复杂任务值——可以用便宜模型 plan、贵模型 act;对简单任务有 YOLO 模式自动跳过 plan。本质是给用户提供"想清楚再动手"这个工程纪律的产品化抓手。
- 启发:模式切换不是 UX 设计问题,是让用户对 agent 的认知阶段建立掌控感的设计。Roo Code 加到 5 个 mode,方向类似但走得更远。
#8.3 影子 git 而不是简单的 file backup?
- 问题:要支持回滚,最简单是每步把改动文件 zip 一份。但这样没法 diff、没法选择性 restore。
- Cline 的回答:起一个独立仓库(影子 git),每个 step 一个 commit,commit 包括所有 workspace 文件(含 .gitignore)。用 git 自身的 reset/diff 能力实现 file-only / task-only / both 三种粒度的恢复。
- 启发:版本控制是程序员最熟悉的"时间机器",把它复用为 agent 安全网,比自己造一套快照系统省百倍力气。代价是用户要忍受
~/.cline/data/占盘。
#8.4 30+ Provider 适配层有没有过度设计?
- 问题:维护这么多 provider 是巨大工作量,每个 SDK 升级都得跟。能不能只支持 OpenRouter?
- Cline 的回答:不能。原因 (1) 隐私(很多企业不允许走 OpenRouter);(2) 性能(直连 Anthropic 比走中转省 100ms);(3) 本地模型必须直连;(4) prompt caching 各家实现差异大,必须各 provider 各自适配。所以
ApiHandler抽象 + provider 各实现是必要的复杂度。 - 启发:抽象层的价值不是"统一接口让上层省事",是让下层各 provider 各自把自家最优特性暴露出来(caching / reasoning / vision)。
#8.5 单机扩展 vs Server 端 Agent,谁是终局?
- 问题:Cline 是 VSCode 扩展,没有团队协作、没有跨设备、没有 RBAC。商业化空间在哪?
- Cline 的回答:Cline 自己也意识到了,于是出了 cline.bot(托管 endpoint)+ CLI(脱离 VSCode)+ Cloud(团队功能在路上)。但产品形态本质还是"以 IDE 为中心、本地优先"。Roo Code 加了 cloud layer 走得稍远。
- 启发:单机 agent 的护城河在本地工具的真实掌控感——文件就在你硬盘上、命令真的跑在你机器上、git 真的是你的 git。Server 端 agent 想模拟这层就要 sandbox + 镜像 + 同步,复杂度量级不同。Cline 押的是"本地优先 = 信任优先"。
#九、附录:组件地图、关键概念与源码索引
#9.1 组件地图(一张图)
┌─────────────────────────── VSCode ───────────────────────────────┐
│ │
│ ┌──────── Webview (React + Vite) ─────────┐ │
│ │ ChatView / ChatRow / ChatTextArea │ │
│ │ BrowserSessionRow / Settings / Rules │ │
│ └──────────────┬──────────────────────────┘ │
│ │ gRPC over postMessage │
│ ┌──────────────▼──────────────────────────┐ │
│ │ Controller (gRPC server) │ │
│ │ ├─ StateService / TaskService │ │
│ │ ├─ McpService / BrowserService │ │
│ │ └─ FileService / SlashService │ │
│ └──────┬─────────────┬──────────┬─────────┘ │
│ │ │ │ │
│ ┌──────▼──┐ ┌──────▼──┐ ┌────▼─────┐ │
│ │ Task │ │ McpHub │ │ Browser │ │
│ │ (主循环)│ │ (子进程)│ │ Session │ │
│ └──┬──┬───┘ └────┬────┘ └────┬─────┘ │
│ │ │ │ │ │
│ │ │ stdio │ │ Puppeteer │
│ │ │ ┌─────────▼─┐ ┌─────▼──────┐ │
│ │ │ │ MCP Server│ │ Chromium │ │
│ │ │ │ (外部进程)│ │ (本地无头) │ │
│ │ │ └───────────┘ └────────────┘ │
│ │ │ │
│ │ │ tool dispatch │
│ │ ▼ │
│ │ ToolExecutor / ToolExecutorCoordinator │
│ │ ├─ ReadFile / WriteToFile / ReplaceInFile │
│ │ ├─ ExecuteCommand (VSCode terminal) │
│ │ ├─ BrowserAction / UseMcpTool / ... │
│ │ └─ Approval gate ← AutoApprove ← StateManager │
│ │ │
│ │ LLM stream │
│ ▼ │
│ ApiHandler (抽象) ── provider 实现 ──▶ Anthropic / OpenAI / │
│ OpenRouter / Ollama / │
│ Bedrock / Vertex / ... │
│ │
│ ┌──────────────── 持久化层 ──────────────┐ │
│ │ ~/.cline/data/ │ │
│ │ ├─ taskHistory.json │ │
│ │ ├─ globalState 镜像 │ │
│ │ └─ 影子 git 仓库(checkpoints) │ │
│ │ workspace/.clinerules/*.md │ │
│ │ ~/Documents/Cline/MCP/cline_mcp_settings.json │
│ └─────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
#9.2 关键概念速查
| 名字 | 一句话定义 |
|---|---|
| Task | 一段 agentic 推理循环;UI 上一个对话气泡历史 = 一个 Task |
| Plan Mode | 只读模式,agent 能读不能写;用来探索 + 对齐意图 |
| Act Mode | 执行模式,agent 能写文件 / 跑命令 / 开浏览器 |
| YOLO Mode | 全 auto-approve + plan→act 自动切换,最大放权 |
| Checkpoint | 影子 git 在每个 tool 执行后的 commit;可三粒度 restore |
| Auto-Approve | 按工具类型 + 范围分级的自动批准开关 |
.clinerules/ |
工作区目录形态的"用户给 agent 的规矩",注入 system prompt |
| @ Mention | 用户在输入框引用文件 / 终端 / git 等本地资源 |
| MCP Hub | 管 MCP server 子进程 + 工具 / 资源发现的中枢 |
| ApiHandler | LLM provider 抽象,每个 provider 实现一份 |
/smol(别名 /compact) |
同 task 内压缩 history |
/newtask |
把当前进度打包,开新 task 清 context |
/newrule |
引导式生成 .clinerules/ 规则文件 |
/deep-planning |
强化推理 prompt,强制多步规划 |
/explain-changes |
对 git diff 出 AI 解释(VS Code only) |
| Skill | .clinerules/ 中带 frontmatter 的可触发规则,/<skill-name> 调用,由 use_skill 工具执行 |
| Subagent | 同 task 内派生独立子 agent(与 /newtask 切换 task 不同) |
| Loop Detection | 检测连续相同 tool call,达到阈值停下来问用户 |
#9.3 源码索引(仓库目录级)
cline/cline
├─ src/
│ ├─ extension.ts VSCode activate / deactivate 入口
│ ├─ common.ts host 共用初始化(VSCode 和 CLI 都调)
│ ├─ registry.ts 服务注册表
│ ├─ config.ts 静态配置
│ │
│ ├─ core/
│ │ ├─ controller/ gRPC 服务面 + Task 生命周期
│ │ │ ├─ index.ts Controller 主类
│ │ │ ├─ grpc-handler.ts gRPC 路由
│ │ │ ├─ state/, task/, mcp/, browser/, slash/, ... 各子服务
│ │ │ └─ worktree/ worktree 支持(多 root workspace)
│ │ ├─ task/
│ │ │ ├─ index.ts Task 主类(recursivelyMakeClineRequests)
│ │ │ ├─ ToolExecutor.ts 工具调度核心
│ │ │ ├─ TaskState.ts 运行时状态字段
│ │ │ ├─ StreamChunkCoordinator.ts / StreamResponseHandler.ts
│ │ │ ├─ loop-detection.ts 防鬼打墙
│ │ │ ├─ multifile-diff.ts 多文件 diff 渲染辅助
│ │ │ ├─ tools/handlers/ 20+ 个工具 Handler(实际文件数随版本增长)
│ │ │ ├─ focus-chain/ 引用链管理
│ │ │ └─ utils/, types/
│ │ ├─ webview/ 侧边栏 React app 容器
│ │ ├─ prompts/
│ │ │ ├─ system-prompt/ 当前 system prompt 模板
│ │ │ ├─ system-prompt-legacy/ 旧版本(按模型 family 分)
│ │ │ ├─ commands.ts slash command prompt
│ │ │ ├─ contextManagement.ts /smol /newtask 的 prompt
│ │ │ ├─ loadMcpDocumentation.ts
│ │ │ └─ responses.ts 固定回复模板
│ │ ├─ storage/
│ │ │ └─ StateManager.ts 全局 + 工作区状态键值存储
│ │ ├─ slash-commands/ /newtask /smol /deep-planning 等
│ │ ├─ mentions/ @ 引用解析与展开
│ │ ├─ context/ 上下文注入逻辑
│ │ ├─ permissions/ CommandPermissionController
│ │ ├─ ignore/ .clineignore
│ │ ├─ commands/ VSCode command palette 命令
│ │ ├─ assistant-message/ LLM 输出解析
│ │ ├─ hooks/, locks/ 工具执行钩子 + 互斥
│ │
│ ├─ api/
│ │ ├─ index.ts buildApiHandler 工厂
│ │ ├─ providers/ 30+ provider 实现
│ │ ├─ transform/ 消息格式变换(各家 SDK 对齐)
│ │ └─ retry.ts
│ │
│ ├─ services/
│ │ ├─ mcp/ McpHub / 子进程管理
│ │ ├─ browser/ BrowserSession + Puppeteer 集成
│ │ ├─ ripgrep/ search_files 后端
│ │ ├─ tree-sitter/ list_code_definition_names 后端
│ │ ├─ glob/ list_files 后端
│ │ ├─ search/ 文件搜索辅助
│ │ ├─ auth/, account/ cline.bot 登录
│ │ ├─ telemetry/, error/ PostHog + Sentry
│ │ ├─ feature-flags/ 远程开关
│ │ ├─ banner/, logging/, temp/, uri/
│ │
│ ├─ integrations/
│ │ ├─ checkpoints/ 影子 git 实现
│ │ ├─ terminal/ VSCode terminal API + shell integration
│ │ ├─ editor/ diff editor / decoration
│ │ ├─ diagnostics/ @problems 后端
│ │ ├─ notifications/ 系统通知
│ │ ├─ claude-code/ Claude Code 互操作
│ │ ├─ openai-codex/ Codex 互操作
│ │ └─ misc/
│ │
│ ├─ hosts/ VSCode / CLI / standalone host 适配
│ ├─ shared/ proto 生成的 TS 类型 + 常量
│ ├─ standalone/ 脱离 VSCode 跑的入口
│ ├─ exports/ 对外 API
│ ├─ types/ 全局类型
│ ├─ utils/
│ ├─ packages/, samples/cli/, dev/
│
├─ webview-ui/ React + Vite 侧边栏 UI
│ └─ src/
│ ├─ App.tsx
│ ├─ components/chat/ ChatView / ChatRow / ChatTextArea / ...
│ ├─ components/settings/ 设置面板(含 plan/act 模型分离)
│ ├─ components/mcp/ MCP marketplace UI
│ ├─ services/grpc-client.ts gRPC over postMessage
│ └─ utils/
│
├─ proto/cline/ *.proto 服务定义(state.proto / task.proto 等)
├─ cli/ 独立 CLI 包
├─ docs/ 用户文档源(部分同步到 docs.cline.bot)
├─ locales/ i18n
├─ tests/ 端到端 / 集成测试
└─ package.json esbuild 打 extension,Vite 打 webview
#9.4 一句话总结
Cline = VSCode 侧边栏 + Plan/Act 双模式 + 20+ 件本地工具 + 影子 git checkpoint + 30+ provider 适配 + MCP hub。 设计核心是把"agent 自治"切成可控制的等级(人工 approve / auto-approve / YOLO), 用影子 git 兜底回滚,让用户敢放手让 LLM 在本机执行。
#文档元信息
- 消歧结论:本文专指
cline/cline(开源 VSCode 扩展,前身 Claude Dev)。Roo Code(前 Roocline)是 fork,在第八章作为对照点出现,不是本文主角。 - 文档路径:
agents/docs/cline-agent-architecture.md - 总行数:约 950 行
- 核对来源(2026-05 时点):
- GitHub
cline/cline/src/core/task/tools/handlers/(24 个 handler 文件) - docs.cline.bot:tools-reference / plan-and-act / auto-approve / checkpoints / using-commands / mcp
- README(CLI v3.0.9,263 releases)
- GitHub
- 2026-06-08 官方复核:
- GitHub release
cline/cline@v3.88.1 - npm
cline@3.0.20 - npm
@cline/agents@0.0.43
- GitHub release
- 仍不确定 / 待核实:
- 影子 git 的具体物理路径:能确认是"独立于项目 git 的影子仓库 + commit 包括 .gitignore 文件 + 每次 tool use 一个 commit",但物理路径(home 下
.cline//.config/还是按 workspace hash 分目录)随版本变化,需看src/integrations/checkpoints/源码确认。 - SDK 工具名 vs 内部工具名差异:
docs.cline.bot/tools-reference/all-cline-tools列出的是 SDK 层精简名(bash/editor/read_files/apply_patch/search/fetch_web/ask_question),与扩展内部 handler 名(execute_command/write_to_file等)映射关系本文按内部名为准;如直接用@cline/agentsSDK,应以 SDK 名为准。 subagent与new_task的边界:根据 handler 文件名推断 subagent 是"同 task 内派生子 agent",new_task 是"切到新 task",但具体语义(共享 history? 共享 checkpoint?)需源码确认。
- 影子 git 的具体物理路径:能确认是"独立于项目 git 的影子仓库 + commit 包括 .gitignore 文件 + 每次 tool use 一个 commit",但物理路径(home 下