首页
/ Cline SDK ClineCore 编程模式详解:从单会话启动到 Hub 多客户端部署

Cline SDK ClineCore 编程模式详解:从单会话启动到 Hub 多客户端部署

2026-09-06 19:24:58作者:袁立春Spencer

本篇技术指南系统讲解 Cline SDK 中 ClineCore 的十大常用编程模式,覆盖基础会话、流式更新、多轮对话、分级权限、自定义工具、插件加载、会话回放、优雅停机、无状态 Worker 与 Hub 多客户端接入。读完后你可以直接照着文中可复制的示例搭建基于 @cline/sdk 的自动化编码代理应用,并理解每种模式背后在 Cline 仓库源码中的落点。

ClineCore 实例创建与 backendMode 选择

所有模式都从 ClineCore.create() 开始。它是 SDK 的主工厂方法,负责根据选项初始化运行时宿主(local、hub 或 remote)并返回一个可用于启动会话的实例。入口实现位于 ClineCore.ts,类上的 JSDoc 也给出了最小示例:

import { ClineCore } from "@cline/core";

const cline = await ClineCore.create({ clientName: "my-app" });
const session = await cline.start({ ... });

ClineCoreOptions 的完整定义在 cline-core/types.ts,关键字段与语义如下:

字段 类型 说明
clientName string 客户端标识,用于遥测与日志归因
distinctId string? 机器/用户稳定标识,默认使用系统 machine ID,回退为持久化在 ~/.cline/data/machine-idcl-<nanoid>
backendMode "auto" | "local" | "hub" | "remote" 运行时选择策略,详见下文
hub / remote HubOptions / RemoteOptions 对应模式下的连接选项
capabilities RuntimeCapabilities 客户端侧交互回调(如工具审批),实现一次、多后端复用
toolPolicies Record<string, ToolPolicy> 实例级工具审批策略
automation boolean | ClineCoreAutomationOptions 启用后通过 cline.automation.* 访问定时/事件驱动自动化
fetch typeof fetch 注入自定义 HTTP 行为(代理、重试、测试桩),仅对本进程内执行的会话生效
telemetry / logger / featureFlags 服务实例 省略时分别为 no-op
prepare 会话启动前钩子 返回可改写会话输入的 StartSessionBootstrap

backendMode 的四种取值(来自 types.ts 的字段注释):

  • "auto"(默认)——若存在兼容的本地 hub 则优先使用,否则回退到本进程内执行;
  • "hub"——要求有兼容的 websocket hub 运行时,不可达时抛错;
  • "remote"——要求显式的远端 websocket hub 端点;
  • "local"——总是使用本地进程内执行与本地 SQLite/文件存储。

这个选择在模式 8(无状态 Worker)和模式 10(Hub 多客户端)中会反复出现,是理解整篇指南的前提。

模式一:使用内置工具的基础会话

最小可用场景:创建实例、以 Anthropic 模型启动一次带工具的会话,读取结果并释放资源。

import { ClineCore } from "@cline/sdk"

const cline = await ClineCore.create({ clientName: "my-app" })

const session = await cline.start({
  prompt: "Read package.json and summarize the dependencies",
  config: {
    providerId: "anthropic",
    modelId: "claude-sonnet-4-6",
    apiKey: process.env.ANTHROPIC_API_KEY,
    cwd: process.cwd(),
    enableTools: true,
  },
})

console.log(session.result?.text)
await cline.dispose()

要点拆解:

  • start() 返回 StartSessionResult,包含 sessionIdmanifestmanifestPathmessagesPath,以及可选的 result?: AgentResult(完整字段见 api.md);
  • config.cwd 决定代理的工作目录,enableTools: true 才会挂载内置工具集;
  • AgentResult 除了 text,还提供 usagetoolCallsiterationsfinishReason"completed" | "max_iterations" | "aborted" | "mistake_limit" | "error")、durationMs 等,生产代码建议检查 finishReason 而非只看 text 是否存在;
  • dispose() 会关停运行时宿主、断开连接并清理所有会话与 bootstrap,ClineCore.ts 中的实现会先 Promise.allSettled 地清理所有活跃 bootstrap 再解绑事件订阅。

模式二:带 UI 更新的流式会话

如果应用需要在会话运行过程中实时渲染输出,用 subscribe() 注册事件监听,而不是等 start() 返回。

const cline = await ClineCore.create({ clientName: "my-app" })

cline.subscribe((event) => {
  switch (event.type) {
    case "chunk":
      if (event.payload.type === "text") {
        ui.appendText(event.payload.text)
      }
      break
    case "ended":
      ui.showComplete(event.payload.finishReason)
      break
  }
})

await cline.start({
  prompt: "Refactor the auth module",
  config: {
    providerId: "anthropic",
    modelId: "claude-sonnet-4-6",
    cwd: "/path/to/project",
    enableTools: true,
  },
})

subscribe(listener, options?) 返回一个取消订阅函数(见 ClineCore.ts),options 可传 { sessionId } 过滤指定会话。CoreSessionEvent 的完整联合类型(同见 api.md):

type CoreSessionEvent =
  | { type: "chunk"; payload: SessionChunkEvent }
  | { type: "agent_event"; payload: { sessionId: string, event: AgentEvent } }
  | { type: "ended"; payload: SessionEndedEvent }
  | { type: "team_progress"; payload: SessionTeamProgressEvent }
  | { type: "status"; payload: { sessionId: string, status: string } }
  | { type: "hook"; payload: SessionToolEvent }

一个容易忽略的细节:ClineCore 构造函数内部本身就订阅了 "ended" 事件,用于在会话结束时自动清理该会话对应的 bootstrap 资源(ClineCore.ts),所以你的业务监听器可以放心只管渲染,不必担心 bootstrap 泄漏。

模式三:多轮会话

会话启动后,用 send({ sessionId, prompt }) 在同一会话上继续对话。send 在源码中直接转发到运行时的 runTurnClineCore.ts),返回 AgentResult | undefined

const cline = await ClineCore.create({ clientName: "my-app" })

const session = await cline.start({
  prompt: "Create a new Express server",
  config: {
    providerId: "anthropic",
    modelId: "claude-sonnet-4-6",
    cwd: "/path/to/project",
    enableTools: true,
  },
})

// Follow-up
const result = await cline.send({
  sessionId: session.sessionId,
  prompt: "Now add a health check endpoint",
})

console.log(result?.text)
await cline.dispose()

多轮语义的关键是复用 session.sessionId:后续每轮共享同一份消息历史与工作目录上下文。若需要中途打断,还可以用 abort(sessionId)(中止当前工具执行但保留会话)与 stop(sessionId)(彻底结束会话,二者区别见 ClineCore.ts 的 JSDoc 与 api.md)。

模式四:分级权限模型(Tiered Permission Model)

这是生产环境最实用的模式:读类操作自动放行,写类操作必须经人确认。做法是两层配合——实例级的 toolPolicies 声明"哪些工具自动批准",capabilities.requestToolApproval 处理"没被自动批准的请求"。

const cline = await ClineCore.create({
  clientName: "my-app",
  toolPolicies: {
    read_files: { autoApprove: true },
    search: { autoApprove: true },
    fetch_web: { autoApprove: true },
    bash: { autoApprove: false },
    editor: { autoApprove: false },
    apply_patch: { autoApprove: false },
  },
  capabilities: {
    requestToolApproval: async (request) => {
      const approved = await promptUser(
        `Allow ${request.toolName}?\n${JSON.stringify(request.input, null, 2)}`
      )
      return { approved }
    },
  },
})

ToolPolicy 只有两个开关(见 api.md):

interface ToolPolicy {
  enabled?: boolean       // false = 工具对模型完全隐藏
  autoApprove?: boolean   // false = 必须走审批回调
}

即策略空间是三维的:enabled: false(模型根本看不到该工具)、autoApprove: true(静默执行)、autoApprove: false(执行前调用 requestToolApproval)。工具策略还可以下放到单次会话,start() 的入参本身就支持 toolPoliciescapabilities 字段,可覆盖实例级设置。

一个源码层面的注意点:内置工具名常量定义在 constants.ts,包括 read_filessearch_codebaserun_commandsfetch_web_contentapply_patcheditorskillsask_questionsubmit_and_exit。从源码结构看,示例中出现的 bashsearchfetch_web 等键名与常量表中的 run_commandssearch_codebasefetch_web_content 并不完全一致;编写真实策略时,建议以运行时实际注册的工具名为准,或先用 cline.settings.list() 查看当前生效的工具清单(api.md 的 Settings API 一节),避免把策略打到不存在的工具名上。此外 presets.ts 中提供了 "yolo" 预设,用 * 通配全部工具并设为 autoApprove: true,适合受控沙箱场景。

模式五:自定义工具与内置工具并存

createTool 定义应用专属工具(如部署、工单系统对接),通过 config.tools 与内置工具一起注入。createTool 的完整签名在 tools/create.ts

export function createTool<TInput, TOutput>(config: {
	name: string;
	description: string;
	inputSchema: Record<string, unknown> | z.ZodTypeAny;  // Zod 或原始 JSON Schema
	execute: (input: TInput, context: AgentToolContext) => Promise<TOutput>;
	lifecycle?: AgentTool<TInput, TOutput>["lifecycle"];
	timeoutMs?: number;
	retryable?: boolean;
	maxRetries?: number;
}): AgentTool<TInput, TOutput>

Zod schema 会在内部通过 zodToJsonSchema 转换后注册给模型(create.ts),所以推荐直接用 Zod 获得类型推导。完整示例:

import { ClineCore, createTool } from "@cline/sdk"
import { z } from "zod"

const deployTool = createTool({
  name: "deploy",
  description: "Deploy the application to the specified environment.",
  inputSchema: z.object({
    environment: z.enum(["staging", "production"]),
  }),
  execute: async (input) => {
    const result = await runDeployment(input.environment)
    return { url: result.url, status: "deployed" }
  },
})

const cline = await ClineCore.create({ clientName: "my-app" })

await cline.start({
  prompt: "Deploy the app to staging",
  config: {
    providerId: "anthropic",
    modelId: "claude-sonnet-4-6",
    cwd: process.cwd(),
    enableTools: true,
    tools: [deployTool],
  },
})

注意 enableToolstools 互不排斥:前者控制内置工具集,后者追加自定义工具,二者可以并存——这正是该模式标题的含义。对耗时操作,记得利用 timeoutMsretryable/maxRetries 防止工具卡死整个会话。

模式六:带插件的会话

插件有两种加载方式:extensions 直接传入插件对象,pluginPaths 指向目录形式的插件包。同时必须提供 extensionContext.workspace,插件的 setup() 才能拿到 ctx.workspaceInfo——不提供时 ctx.workspaceInfoundefined(见 api.mdCoreSessionConfig 的说明)。

import { ClineCore } from "@cline/sdk"
import myPlugin from "./my-plugin"

const cline = await ClineCore.create({
  clientName: "my-app",
  backendMode: "local",
})

await cline.start({
  prompt: "Do the thing my plugin enables",
  config: {
    providerId: "anthropic",
    modelId: "claude-sonnet-4-6",
    cwd: process.cwd(),
    enableTools: true,
    extensions: [myPlugin],
    extensionContext: {
      workspace: { rootPath: process.cwd(), cwd: process.cwd() },
    },
  },
})

await cline.dispose()

目录形式的插件包改用 pluginPaths

config: {
  pluginPaths: ["./my-cline-plugin"],
  extensionContext: {
    workspace: { rootPath: process.cwd(), cwd: process.cwd() },
  },
}

pluginPaths 指向的目录需要在 package.json 中声明 cline.plugins 字段。CoreSessionConfig 还提供 extensionLoading?: "isolated" | "direct" 控制插件的执行隔离方式,以及 enableSpawnAgentenableAgentTeamsteamName 等与子代理/团队协调相关的开关。完整的插件编写指南见 plugins/REFERENCE.md

模式七:会话列表与回放

本地模式的会话持久化在 SQLite/文件中,实例提供了完整的查询、回放与用量统计接口。

const cline = await ClineCore.create({ clientName: "my-app" })

// List recent sessions
const sessions = await cline.list(10)
for (const session of sessions) {
  console.log(`${session.id}: ${session.title}`)
}

// Read messages from a past session
const messages = await cline.readMessages(sessions[0].id)
for (const msg of messages) {
  console.log(`[${msg.role}] ${msg.content}`)
}

// Check usage
const usage = await cline.getAccumulatedUsage(sessions[0].id)
console.log(`Total tokens: ${usage.aggregateUsage.totalInputTokens + usage.aggregateUsage.totalOutputTokens}`)

源码层面的补充(ClineCore.ts):

  • list(limit = 200, options?) 默认最多返回 200 条历史记录,支持额外过滤参数;
  • readMessages 读取的是规范化消息历史,是 resume、fork 与 compaction 使用的模型表示;若要在 UI 中展示含"观测型模型工具活动"的完整转录,应改用 readDisplayMessages;如果会话仍在内存中驻留且需要包含尚未落盘的最新一轮,用 readLiveMessages——持久化转录只在助手消息/轮次边界追赶落盘,readMessages 可能漏掉进行中的轮次;
  • getAccumulatedUsage 返回两个口径:usage 只含根/主代理,aggregateUsage 额外包含队友与子代理,计费与配额展示时不要混用;
  • 同一实例上还有 update(改元数据)、delete(彻底删除,不可逆)、restore(从 checkpoint 分叉恢复,输入含 checkpointRunCount 与可选的 start)等会话管理方法,对应 api.md 的 Session Management 一节。

模式八:优雅停机

长驻进程(守护、队列消费者、API 服务)应在收到终止信号时主动 dispose 并传入原因,让运行时把进行中的状态收尾,而不是被信号直接杀掉:

const cline = await ClineCore.create({ clientName: "my-app" })

process.on("SIGTERM", async () => {
  await cline.dispose("SIGTERM received")
  process.exit(0)
})

// Run sessions...

dispose(reason?) 会关闭运行时宿主、断开连接并清理所有活跃会话与 bootstrap;调用后实例不可复用(ClineCore.ts)。如果启用了 automationdispose 会先清理内部的 CronService 再交给宿主。

模式九:无状态 Worker 模式

面向请求/响应型负载(API 端点、队列消费者):一个长生命周期的 ClineCore 实例 + 每请求一个新会话,是简单且隔离性好的组合。

import { ClineCore } from "@cline/sdk"

const cline = await ClineCore.create({
  clientName: "worker",
  backendMode: "local",
})

async function handleRequest(prompt: string, workspace: string) {
  const session = await cline.start({
    prompt,
    config: {
      providerId: "anthropic",
      modelId: "claude-sonnet-4-6",
      cwd: workspace,
      enableTools: true,
    },
  })

  return {
    text: session.result?.text,
    usage: session.result?.usage,
    sessionId: session.sessionId,
  }
}

设计要点:

  • ClineCore 实例只创建一次(初始化成本在 create 阶段,会话创建远比实例创建轻);
  • 每次请求返回 sessionId,为事后审计、回放(模式七)与恢复保留句柄;
  • usage 回传便于按请求计费/限流;
  • 由于 backendMode: "local",会话数据落在本机 SQLite/文件存储,无需额外部署 hub 组件。

模式十:Hub 后端的多客户端接入

当需要"多个客户端挂在同一个会话上"(例如后端进程跑长任务、前端面板实时观察),把 backendMode 切到 "hub" 即可。

// Process 1: start session
const cline = await ClineCore.create({
  clientName: "backend",
  backendMode: "hub",
})

const session = await cline.start({
  prompt: "Long running refactor task",
  config: { ... },
})

// Process 2: attach and stream events
const viewer = await ClineCore.create({
  clientName: "dashboard",
  backendMode: "hub",
})

viewer.subscribe((event) => {
  dashboard.render(event)
}, { sessionId: session.sessionId })

这背后是 Cline 的 Hub-Spoke 架构(完整讲解见 hub-spoke.mdx):

  • Hub 是每台机器单例的守护进程,负责会话协调、事件路由与审批转发,自身不跑 agent 循环;
  • Spoke 是 worker 进程,执行 agent 循环、调用工具、流式输出,并把事件汇报给 hub;
  • Client(CLI、IDE 或任意自定义应用)经 WebSocket 注册后附着到会话,发送输入、接收事件流;
  • 客户端来去不会打断执行:进程 1 退出后 spoke 继续运行,进程 2(dashboard)通过 subscribe(..., { sessionId }) 在中途接管事件流。

从源码结构看,hub 的发现基于 ~/.cline/locks/hub/owners/ 下的锁文件;"auto" 模式下 ClineCore 会在没有 hub 时自动启动它,因此模式一~九的示例代码在开发机上往往已经隐式受益于这一机制,只有明确要求多进程共享时才需要显式 backendMode: "hub"

模式选型速查

场景 模式 关键 API
一次性脚本/CI 任务 模式一 startsession.result
带实时 UI 的桌面/TUI 应用 模式二 subscribe + chunk/ended 事件
对话式产品 模式三 send({ sessionId, prompt })
生产环境、需人机边界 模式四 toolPolicies + requestToolApproval
接入内部系统(部署、工单) 模式五 createTool + config.tools
复用 Cline 插件生态 模式六 extensions / pluginPaths + extensionContext
审计、回放、计费 模式七 list / readMessages / getAccumulatedUsage
常驻服务 模式八 dispose(reason) + 信号处理
API/队列负载 模式九 单实例 + 每请求新会话
多端观察/接管同一会话 模式十 backendMode: "hub" + subscribe({ sessionId })

延伸阅读

以上模式均出自 clinecore/patterns.md,配套资料:

登录后查看全文
热门项目推荐
相关项目推荐