# klient、SDK 与 ACP

> 契约驱动门面的三段式 API 与两种传输、直连 v2 引擎的 acp-server、node-sdk 的 v2 客户端，以及 OAuth、遥测与迁移。

- 作者：David（道雾轩）
- 专栏：Kimi Code 源码解读（https://daiw.org/manual/kimi-code.md）
- 最后更新：2026-09-19
- 原文：https://daiw.org/manual/kimi-code/klient-acp
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

几个包解决同一个问题的不同侧面：**怎么让外部消费这个引擎**。v1 退场后，它们全都站在 agent-core-v2 之上。

## klient：契约驱动的门面

`packages/klient`（约 8056 行）的包描述：

> Kimi client SDK — contract-driven facade over agent-core-v2, routable over ipc or in-memory transports.

`src/core/klient.ts` 第 38 行定义了整个公开面：

```ts
export interface Klient {
  readonly global: GlobalFacade;
  readonly events: KlientEvents;
  session(sessionId: string): SessionHandle;
  close(): Promise<void>;
}
```

`session(id)` 的句柄再提供 `agent(id)`，于是 API 是三段式：`global.*`（会话、工作区、配置、模型、插件……）、`session(id).*`（标题、归档、fork、审批与问题）、`session(id).agent(id).*`（`prompt`、`steer`、`cancel`、切模型、查用量）。每一段都带自己的 `events`。

包内 `AGENTS.md` 规定了严格分层：

- **Facade**：唯一的公开 API，不暴露引擎的服务令牌，**没有通往原始服务的后门**——明令不许再引入 service locator。
- **Contract**（`src/contract/`）：每个方法的 zod 输入 / 输出 schema，照着 agent-core-v2 的类型手抄，由 `test/contract-parity.ts` 的编译期断言钉住——引擎类型一变，这里先编译失败。校验默认开启（`KlientOptions.validate`），README 说它比线上本就要付的 JSON 序列化还便宜。
- **Transports**：只实现 `KlientChannel` 这一个 SPI。`ipc` 在 unix socket 上跑 NDJSON（宿主侧用 `serveKlientIpc`）；`memory` 在进程内分发，但每个值都做一次 JSON 往返，**两种传输返回逐字节相同的数据**。

```ts
import { createKlient } from '@moonshot-ai/klient/memory';   // or '/ipc'
```

这与 [node-sdk 的 RPC 契约](https://daiw.org/manual/kimi-code/message-lifecycle)是同一个哲学：**接口与传输解耦**。包里还托管 e2e：`test/e2e/legacy/` 的 `/api/v1` 实况用例（没设 `KIMI_SERVER_URL` 就跳过）与 `docker:e2e` 运行器。仓库里 klient 的两个消费者 acp-server 与 node-sdk，都用 memory 传输。

## node-sdk：公开 SDK

`packages/node-sdk`（`@moonshot-ai/kimi-code-sdk`）面向第三方程序嵌入，也是 CLI 与 VS Code 插件消费引擎的入口。导出面开头：

```ts
export { KimiHarness } from '#/kimi-harness';
export type { KimiHarnessRuntimeOptions } from '#/kimi-harness';
export { Session } from '#/session';
export { KimiAuthFacade } from '#/auth';
export {
  createKimiHarness,
  SDKRpcClientV2,
  type SDKRpcClientV2Options,
} from '#/sdk-rpc-client-v2';
```

`SDKRpcClientV2` 的文件头说得直白：它是「an `SDKRpcClientBase` backed by the agent-core-v2 engine (DI × Scope) instead of the v1 `KimiCore` RPC pair」——引擎在进程内启动，经 klient 的 memory 传输访问；门面够不着的操作（显式会话 id、恢复、工作区命令）才经 `engineAccessor` 直取引擎服务。`KimiConfigRpcClient` 仍在，配置读写带 `KimiConfigValidationIssue` 这类结构化校验反馈。

[前面说过](https://daiw.org/manual/kimi-code/monorepo-map)的那条性质依然成立：运行时 `dependencies` 里没有任何引擎包，agent-core-v2、klient、kosong、kaos 都只在 `devDependencies`。

## ACP：编辑器集成

`packages/acp-adapter` 已删除，取而代之的是 `packages/acp-server`（约 5647 行）：

> Agent Client Protocol (ACP) host backed directly by the DI × Scope agent engine (agent-core-v2)

依赖只有 `@agentclientprotocol/sdk`、agent-core-v2 与 klient，不再经过 node-sdk。`kimi acp`（`apps/kimi-code/src/cli/sub/acp.ts`）懒加载 `runAcpServer()`，走 **stdio**，供 Zed、JetBrains 等 ACP 客户端驱动。README 的承诺没变：

> Log in once, then point your editor at the `kimi acp` subcommand — **no extra login needed**.

客户端需要登录时，会带 `--login` 重新调起同一个二进制，走设备码流程。

`start.ts` 是组合根：`bootstrap()` 建 App 作用域，上面套一个 memory 传输的 klient；`initialize`、`session/new`、`/load`、`/resume`、`/list`、`/close`、`/delete`、`/fork`、`session/prompt`、`session/cancel` 以及模型 / 模式 / thinking 配置，都经这个门面驱动引擎。两处宿主替换最有意思：

- **文件系统**：`acp-fs/` 在 Session 作用域注册一个 ACP 版 `IHostFileSystem`，文本读写走客户端的 `fs.readTextFile` / `fs.writeTextFile`，从而遮住 App 级的本地实现；App 级消费者（持久化、技能加载）仍用真实磁盘。
- **终端**：客户端声明了 `clientCapabilities.terminal` 时，Bash 经 `AcpRuntimeProviderFactory` 反向调用编辑器的终端执行。

stdout 是 JSON-RPC 通道，所以 `console.*` 被整体重定向到 stderr。CHANGELOG 里的迁移节点：v0.33.0 起 `kimi acp` 默认跑 v2（`KIMI_CODE_LEGACY_FLAG=1` 可回退），v0.40.0 起不再理会该开关。

## OAuth

`packages/oauth`（`@moonshot-ai/kimi-code-oauth`）是 Kimi OAuth 与托管认证工具，被 agent-core-v2、kap-server、node-sdk、remote-control 以及 CLI、VS Code 插件共同依赖。`KimiHostIdentity`（`src/identity.ts`）贯穿引擎启动、服务端与 SDK，用来区分宿主。`kimi login` 走设备码流程，`--region` 选 `mainland-cn`（kimi.com）或 `global`（kimi.ai）。

[MCP 也有自己的 OAuth](https://daiw.org/manual/kimi-code/mcp)，在 v2 里是 `mcpCore/oauth/` 与 `app/mcpConfig/oauthService.ts`，与本包是两套：本包是「Kimi 认你」，那边是「第三方 MCP 服务器认你」。

## 遥测

`packages/telemetry` 仍是最小的包，只剩 CLI 一个依赖方：`main.ts` 调 `installCrashHandlers()`，各子命令用 `track()`、`setTelemetryContext()`、`withTelemetryContext()`、`shutdownTelemetry()`。`withTelemetryContext(patch)` 返回一个带上下文的派生客户端（`defaultClient.withContext(input)`），拿着它上报就自动带上归属信息。

引擎则有自己的 `app/telemetry/`：`ITelemetryService`、云端与控制台 appender、隐私脱敏，以及 `noopTelemetryService`——**默认无操作，宿主注入真实实现**。这与 [Web 工具与服务注入](https://daiw.org/manual/kimi-code/web-tools)是同一个思路：抓取网页的工具只依赖 `IWebFetchService`，由它按 services 配置、托管 OAuth、本地抓取器的顺序选定实现。

## 迁移

`packages/migration-legacy`：

> Migrate kimi-cli (`~/.kimi/`) data into kimi-code (`~/.kimi-code/`).

它现在建在 agent-core-v2 之上。CLI 在 `src/migration/` 接入：启动时 `detectPendingMigration()` 检测并弹迁移界面，另有 `kimi migrate` 子命令与无界面模式。单独成包的好处仍是**可删除**——若干版本后可以整包移除，不留痕迹。

第 6 部分结束。下一篇：[agent-core-v2 与 kaos](https://daiw.org/manual/kimi-code/agent-core-v2)。
