首页
/ Cline SDK ClineCore 运行时:用内置工具、会话持久化与多进程 Hub 构建有状态编码智能体

Cline SDK ClineCore 运行时:用内置工具、会话持久化与多进程 Hub 构建有状态编码智能体

2026-09-03 16:16:14作者:董宙帆

本文围绕 Cline SDK 中 @cline/core 包的核心运行时 ClineCore 展开:它如何把 Agent 循环、内置工具、.cline/ 配置发现、SQLite 会话持久化与可选的 Hub 多进程支持整合为一个完整的有状态运行时。读完后,你将能够独立完成 ClineCore 实例的创建与配置、启动和续接会话、订阅事件流、管理会话生命周期(列表/恢复/删除/用量统计),并理解每种后端模式(auto / local / hub / remote)的适用场景与源码实现依据。

何时选择 ClineCore 而非裸 Agent

Cline SDK 提供两层能力:Agent(无状态、最小依赖的 Agent 循环)与 ClineCore(完整运行时)。ClineCore 封装了 Agent 循环,并补齐了生产级应用所需的会话持久化、内置工具、配置发现、插件加载和可选的 Hub 多进程支持(见 ClineCore 运行时参考)。选择建议如下:

需要 ClineCore 的场景 用 Agent 即可的场景
需要内置工具(bash、editor 等) 只需要自定义工具
需要会话持久化到磁盘 无状态运行即可
需要从 .cline/ 目录发现配置 自己管理配置
需要定时/自动化 Agent 不需要调度能力
需要多客户端共享同一会话 单进程运行即可
在构建完整应用 希望最小依赖

从源码结构看,ClineCore 类本身是一个“门面”:它持有 RuntimeHost(本地/Hub/远程三种后端)以及 settingsautomationpendingPromptsfeatureFlags 等只读服务句柄,绝大多数方法都是对 host 对应能力的直接转发。核心实现位于 ClineCore.ts,包级说明见 @cline/core README

快速上手

安装 @cline/core 后,最简路径是三步:创建实例 → 启动会话 → 释放资源:

import { ClineCore } from "@cline/sdk"

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

const session = await cline.start({
  prompt: "Set up CI with GitHub Actions",
  config: {
    providerId: "anthropic",
    modelId: "claude-sonnet-4-6",
    apiKey: process.env.ANTHROPIC_API_KEY,
    cwd: "/path/to/project",
    enableTools: true,
  },
})

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

start() 返回 StartSessionResult,包含 sessionIdmanifestmanifestPathmessagesPath,以及会话跑完后的 result?: AgentResult(定义见 ClineCore API 参考)。README 特别提示:当 cwdworkspaceRoot 都省略时,运行宿主会把会话放入共享聊天工作区 ~/.cline/data/workspaces/chat,并预置一个 AGENTS.md 规则文件告诉 Agent 以对话模式对待会话、只有用户明确要求时才创建命名项目目录;此时应以 result.manifest.cwdresult.manifest.workspace_root 为准读取解析后的路径(见 README 说明)。

实例创建:ClineCoreOptions 全参数

ClineCore.create(options) 是整个 SDK 的主工厂方法。它在内部依次完成:解析 distinctId、归一化 capabilities、按 backendMode 创建 RuntimeHost、初始化特性开关与自动化服务(CronService),详见 create 方法实现。完整选项定义在 cline-core/types.ts

interface ClineCoreOptions {
  clientName?: string                    // 应用标识,用于遥测与日志
  distinctId?: string                     // 机器/用户标识,默认取系统机器 ID,
                                          // 否则生成 cl-<nanoid> 并持久化到 ~/.cline/data/machine-id
  backendMode?: "auto" | "local" | "hub" | "remote"
  hub?: HubOptions                        // hub.endpoint / authToken / strategy 等
  remote?: RemoteOptions                  // remote.endpoint(必填)/ authToken 等
  capabilities?: RuntimeCapabilities      // 客户端拥有的交互能力回调
  telemetry?: ITelemetryService           // 省略时遥测为 no-op
  featureFlags?: FeatureFlagsService      // 省略时使用默认 no-op provider
  logger?: BasicLogger                   // 运行时时选择/回退等诊断日志
  toolPolicies?: Record<string, ToolPolicy>
  messagesArtifactUploader?: ...          // messages.json 落盘后的镜像上传钩子
  automation?: boolean | ClineCoreAutomationOptions
  fetch?: typeof fetch                    // 注入自定义 HTTP 行为(代理/重试/测试替身)
  prepare?: (input) => StartSessionBootstrap | ...
}

几个值得展开的细节:

  • distinctId:默认取系统机器 ID,缺失时生成 cl-<nanoid> 并持久化到 ~/.cline/data/machine-id,用于遥测归属(types.ts 注释)。
  • fetch:会被透传给本地会话所用 AI 网关各 provider 的 ProviderConfig.fetch,用于注入代理、重试、追踪或测试替身。注意作用范围:仅对本进程内执行的会话(local 及 auto 回退 local)生效;Hub/remote 运行时的 HTTP 调用发生在拥有网关的那个进程内,需在 @cline/hubstartHubServer({ fetch }) 处配置(fetch 字段注释)。
  • prepare:每次会话启动前的准备钩子,可用于装配工作区级运行时状态(watcher/扩展/遥测),再通过返回的 StartSessionBootstrap.applyToStartSessionInput() 改写启动输入。注意它运行在宿主解析省略的工作区之前,因此“无路径启动”时 cwd/workspaceRoot 对该钩子均不可见(README Session Bootstrap)。
  • automation:传 trueClineCoreAutomationOptions 启用文件/事件驱动的自动化;autoStart 不为 false 时,create() 内部会自动调用 automation.start()ClineCore.create)。

HubOptions 与 RemoteOptions

interface HubOptions {
  endpoint?: string
  authToken?: string
  strategy?: "prefer-hub" | "require-hub"
  clientType?: string
  displayName?: string
  workspaceRoot?: string
  cwd?: string
}

interface RemoteOptions {
  endpoint: string        // remote 模式下必填
  authToken?: string
  clientType?: string
  displayName?: string
  workspaceRoot?: string
  cwd?: string
}

两者定义见 types.tshubbackendMode"hub""auto"(偏好共享本地 Hub)时生效;remote 仅在 backendMode: "remote" 时相关。

后端模式:auto / local / hub / remote

模式 行为
"auto"(默认) 优先尝试连接本地 Hub;不可用时回退到进程内执行
"local" 进程内执行 + 本地 SQLite 存储,不接触 Hub
"hub" 要求存在可用的本地 WebSocket Hub,否则失败
"remote" 连接显式指定的远程 Hub 端点

模式选择在 createRuntimeHost(options) 中完成(ClineCore.create 调用点),底层宿主类型包括 LocalRuntimeHostHubRuntimeHostRemoteRuntimeHost。实践建议与参考文档一致:简单脚本和 CLI 工具使用 "local" 可避免 Hub 发现开销;Hub 模式则解锁多客户端会话共享——例如一个仪表板进程订阅另一个进程里正在运行的会话事件(auto 模式默认优先本地 Hub,从 hub-runtime-host 测试 可看到其工作区解析行为)。

启动会话:ClineCoreStartInput 与 CoreSessionConfig

cline.start(input) 接受 ClineCoreStartInput,其结构为:

interface ClineCoreStartInput {
  prompt: string
  config: CoreSessionConfig
  source?: string                          // 会话来源标记
  interactive?: boolean
  sessionMetadata?: Record<string, unknown>
  initialMessages?: AgentMessage[]
  toolPolicies?: Record<string, ToolPolicy>
  capabilities?: RuntimeCapabilities
  localRuntime?: LocalRuntimeStartOptions   // 本地运行时的启动选项
}

config: CoreSessionConfig 是核心配置面(完整定义见 API 参考):

interface CoreSessionConfig {
  cwd?: string                            // 工作目录
  providerId: string                      // LLM 提供商(必填)
  modelId: string                         // 模型标识(必填)
  apiKey?: string                         // 提供商 API Key
  systemPrompt?: string                   // 自定义系统提示词
  tools?: readonly AgentTool[]            // 追加的自定义工具
  enableTools?: boolean                   // 是否启用内置工具
  hooks?: Partial<AgentRuntimeHooks>      // 运行时钩子
  extensions?: AgentPlugin[]              // 内联加载的插件对象
  pluginPaths?: string[]                  // 插件包目录路径
  extensionLoading?: "isolated" | "direct"
  extensionContext?: {
    workspace?: { rootPath: string; cwd: string } // 传给插件 setup() 的上下文
  }
  checkpointConfig?: CoreCheckpointConfig
  compactionConfig?: CoreCompactionConfig
  telemetry?: ITelemetryService
  logger?: BasicLogger
  enableSpawnAgent?: boolean              // 允许生成子 Agent
  enableAgentTeams?: boolean              // 启用团队协同
  teamName?: string
}

start() 的实际执行路径是:归一化输入 → 调用 prepare 钩子(若有)→ 交给 host.startSession(),并在成功后发出 session-started 遥测;任何一步失败都会先清理 bootstrap 再抛出(start 方法)。两个容易踩坑的点:

  1. extensionspluginPaths 是两条插件注入路径:前者直接传插件对象,后者指向 package.json 中含 cline.plugins 字段的目录。
  2. 必须设置 extensionContext.workspace,否则插件 setup() 中的 ctx.workspaceInfoundefinedAPI 参考说明)。

内置工具与配置发现

enableTools: true 时,ClineCore 自动提供以下内置工具:

工具 说明
bash 执行 shell 命令
editor 编辑文件
read_files 读取文件内容
apply_patch 应用 unified diff
search 搜索文件内容与结构
fetch_web HTTP 请求与网页内容获取

从源码结构看,这些工具由 createBuiltinTools(...) 统一装配进运行时构建器,见 runtime-builder.ts@cline/core 同时导出 createDefaultToolscreateDefaultExecutors 供宿主自行组合(README Default Tools 一节)。

除代码内配置外,ClineCore 还会监听 .cline/ 目录,发现以下六类资源:

  • Rules(系统提示词附加内容)
  • Skills(领域知识)
  • Workflows(多步骤流程)
  • Hooks(生命周期逻辑)
  • Plugins(工具 + 钩子捆绑包)
  • MCP servers(外部工具提供方)

这使得“把仓库里的 .cline/ 目录配好,任何 ClineCore 应用自动获得这些能力”成为可能,也是它与裸 Agent 的关键差异之一。

关键 API 一览

以下 API 均来自 ClineCore 公开接口(实现见 ClineCore.ts):

API 说明 源码映射
ClineCore.create(options) 创建并初始化实例 static create
cline.start(input) 启动新会话 host.startSession
cline.send({ sessionId, prompt }) 发送后续消息 host.runTurn
cline.subscribe(listener, options?) 订阅会话事件,返回 unsubscribe host.subscribe
cline.list(limit = 200, options?) 列出历史会话 listSessionHistory
cline.get(sessionId) 获取会话元数据 host.getSession
cline.readMessages(sessionId) 读取持久化消息(模型/回放视角) host.readSessionMessages
cline.getAccumulatedUsage(sessionId) 累计 token/成本 host 服务扩展
cline.abort(sessionId) 中止当前工具执行,会话继续存活 host.abort
cline.stop(sessionId) 优雅终止会话(不可再续) host.stopSession
cline.update(sessionId, updates) 更新会话元数据(如 title) host.updateSession
cline.delete(sessionId) 删除会话及全部关联数据 host.deleteSession
cline.restore(input) 从 checkpoint 恢复会话 host.restoreSession
cline.dispose(reason?) 释放全部资源,之后实例不可复用 host.dispose

几点语义澄清,避免误用:

  • abortstop 的区别abort(sessionId) 中断的是“正在执行的工具操作”(如文件读取、shell 命令),会话仍存活并继续处理;stop(sessionId) 则彻底结束会话且无法恢复(abort 文档注释stop 文档注释)。
  • readMessages vs readLiveMessages:持久化转录只在 assistant 消息/轮次边界追上磁盘,进行中的轮次可能缺失;需要“当前对话”时(如 plan/act 模式切换时为新会话播种消息)应使用 readLiveMessages,它优先读取宿主内存中的实时对话(readLiveMessages 注释)。此外 readDisplayMessages 提供面向 UI 展示的消息投影,把观测类模型工具活动投影为普通工具块。
  • getAccumulatedUsage 返回两个口径usage 只统计根/主 Agent,aggregateUsage 额外包含 teammates 与子 Agent。
  • list(limit) 默认 200list 方法)。

从 checkpoint 恢复:restore

skill 文档中的简写是 cline.restore({ sessionId, checkpointId }),而当前仓库源码中 RestoreInput 的实际字段为 checkpointRunCount(数字,表示修剪到第几个 run),且可选附带 start(在新会话中继续)与 restore 选项(RestoreInput/RestoreOptions 定义):

interface RestoreInput {
  sessionId: string
  checkpointRunCount: number
  start?: ClineCoreStartInput   // 恢复后立即开始新会话
  cwd?: string
  restore?: {
    messages?: boolean          // 默认 true:fork 出修剪到 checkpoint 的消息历史
    workspace?: boolean        // 默认 true:从 checkpoint 的 git 快照恢复工作区文件
    omitCheckpointMessageFromSession?: boolean
  }
}

配套的 cline.compareCheckpoint({ sessionId, checkpointRunCount, cwd }) 可比较 checkpoint 与工作区当前状态的差异(compareCheckpoint)。

事件流:CoreSessionEvent 与 AgentResult

cline.subscribe(listener, { sessionId? }) 发出的是 ClineCore 层面的 CoreSessionEvent 类型,它与独立 Agent 类发出的 AgentRuntimeEvent 是不同的两套事件体系(完整对比见 events/REFERENCE.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 }

流式输出场景的标准写法:

cline.subscribe((event) => {
  switch (event.type) {
    case "chunk":
      if (event.payload.type === "text") {
        process.stdout.write(event.payload.text)
      }
      break
    case "ended":
      console.log(`Session ended: ${event.payload.finishReason}`)
      break
  }
})

注意结果对象上的字段差异:ClineCore 的结果使用 AgentResult.text,而独立 AgentAgentRunResult 使用 .outputText——混用两套 API 时这是最常见的字段取不到值的原因。AgentResult 完整字段包括 textusagemessagestoolCallsiterationsfinishReasoncompleted | max_iterations | aborted | mistake_limit | error)、modelstartedAt/endedAt/durationMs(见 API 参考 AgentResult)。

会话持久化布局

所有会话统一存储在 ~/.cline/data/sessions/ 下:

~/.cline/data/sessions/
  sessions.db        # SQLite 数据库(会话索引)
  [session-id]/      # 每会话一个目录
    [session-id].json  # 消息历史/manifest

源码依据:SQLite 库文件由 SqliteSessionStore 在会话数据目录中创建为 sessions.dbsqlite-session-store.ts);历史列举路径则直接扫描该目录、读取 [session-id]/[session-id].json manifest(history.ts)。这个布局支撑了跨实例能力——任意同机 ClineCore 实例都能 list / readMessages / restore 之前创建的会话。

实战模式(源自 patterns 文档)

以下模式整理自 ClineCore Patterns,均可直接用于生产代码。

多轮会话

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,
  },
})

const result = await cline.send({
  sessionId: session.sessionId,
  prompt: "Now add a health check endpoint",
})
console.log(result?.text)

分层权限模型(ToolPolicy)

读取类工具自动放行,写类工具走审批回调:

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 仅两个字段:enabled: false 表示工具对模型完全隐藏;autoApprove: false 表示执行前必须经过 requestToolApproval 回调(ToolPolicy 定义)。toolPolicies 既可以在 create() 级别设置,也可以在 start() 输入中按会话覆盖。

自定义工具与内置工具并存

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" }
  },
})

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

无状态 Worker 模式(API/队列负载)

一个长驻 ClineCore 实例 + backendMode: "local",每个请求开新会话,返回文本、用量与会话 ID,会话本身留盘可追溯:

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,
  }
}

Hub 多客户端共享

// 进程 1:启动会话
const cline = await ClineCore.create({
  clientName: "backend",
  backendMode: "hub",
})
const session = await cline.start({
  prompt: "Long running refactor task",
  config: { /* ... */ },
})

// 进程 2:附着同一会话并按 sessionId 过滤订阅
const viewer = await ClineCore.create({
  clientName: "dashboard",
  backendMode: "hub",
})
viewer.subscribe((event) => {
  dashboard.render(event)
}, { sessionId: session.sessionId })

会话列举与回放、优雅退出

// 列出最近 10 个会话
const sessions = await cline.list(10)
for (const session of sessions) {
  console.log(`${session.id}: ${session.title}`)
}

// 回放消息 + 用量统计
const messages = await cline.readMessages(sessions[0].id)
const usage = await cline.getAccumulatedUsage(sessions[0].id)
console.log(`Total tokens: ${usage.aggregateUsage.totalInputTokens + usage.aggregateUsage.totalOutputTokens}`)

// SIGTERM 时优雅释放
process.on("SIGTERM", async () => {
  await cline.dispose("SIGTERM received")
  process.exit(0)
})

自动化 API(Scheduled / Event-Driven Agents)

create() 中启用 automation: true(或传入 ClineCoreAutomationOptions,如 cronSpecsDircronScopepollIntervalMsglobalMaxConcurrency 等,见 ClineCoreAutomationOptions)后,实例即获得 cline.automation 控制器:

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

cline.automation.start()
cline.automation.stop()
cline.automation.reconcileNow()
cline.automation.ingestEvent(event)   // 事件驱动入口
cline.automation.listEvents(options?)
cline.automation.listSpecs(options?)   // one_off / schedule / event 三类触发器
cline.automation.listRuns(options?)    // 状态: queued | running | done | failed | cancelled

底层由 CronService 承担(SQLite 存储 + 轮询 + 事件摄取),未启用 automation 时调用任何 cline.automation.* 会抛出明确错误提示(构造函数中的守护逻辑)。

小结与延伸阅读

ClineCore 的定位可以用一句话概括:@cline/core 是 Cline SDK 的“有状态编排层”,把 Agent 运行时、provider 配置、存储、默认工具与会话生命周期组装为宿主就绪的运行时(README 首段)。选型时的判断顺序是:先问是否需要内置工具/持久化/配置发现/调度/多客户端(是则 ClineCore),再看部署形态决定 backendMode(单机脚本 local,多进程共享 hub,跨机 remote,探索期 auto)。

配套资料(均在当前仓库内):

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

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
527
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
502
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384