# Karmen AI 原生接入指南

版本：Karmen API v1 / 文档 2026-09-11

> 这是 Karmen 自己的接入方法。使用一个 Karmen API Key，即可在网站、CRM 或内部业务系统中调用已经挂载好的 Karmen AI。当前仓库已实现 v1 合同；生产环境中的模型、邮箱、NAS 和沙箱是否可用，仍以工作台的真实状态为准。

## 1. Karmen 原生接入协议是什么

Karmen AI 向外提供一套独立的 **Karmen 原生接入协议**。开发者调用的是 Karmen AI 服务，而不是某个底层模型供应商的接口。Karmen 内部的能力编排层负责组合身份、职责、知识、记忆、模型入口、策略和审计，再以一个稳定的 Karmen 实例对外服务。

一个 API Key 对应一个已经部署的 Karmen AI 实例。这个实例可以是网站客服、CRM 销售助理、询单岗位或内部协作角色。外部系统只需要保存 Karmen 的地址、Key、用户标识和会话标识，不需要分别接入底层模型。

```text
客户网站 / CRM / 内部系统
            │
            │  一个 Karmen API Key
            ▼
     Karmen API 网关
            │
            ├─ 识别已部署的 Karmen 实例
            ├─ 加载身份、职责与语言策略
            ├─ 加载获授权知识和连续会话
            ├─ 执行权限、额度与审计规则
            └─ 交给 Karmen 能力编排层
                       │
                       ▼
                 Karmen 回复
```

因此，客户接入 Karmen 时不需要理解内部挂载了几个模型、哪一套知识库或哪一个内部 Agent。Karmen 可以在内部升级或调整这些能力，而客户仍然使用同一个 Karmen API Key 和同一份 v1 合同。

当前 v1 每个实例绑定一个隔离的模型入口，上游模型不持有独立工具权限。Karmen 网关支持管理员验证、确认为只读并批准到当前实例的 MCP 工具：只有活动绑定及允许清单内的工具可用，凭据由服务端保管，参数校验、调用上限与审计由网关执行。没有获批绑定时不调用工具。

接入方不能在请求中提交 `tools`、任意 URL 或写操作。管理员确认只读不等于技术上证明第三方工具绝无副作用；生产环境是否真实连接仍需单独验收。多模型规划和更复杂的能力组合属于后续扩展方向。

## 2. 你接入的是一个 Karmen 实例

一个 Karmen 实例是已经在工作台完成配置的 AI 服务单元。它包含：

- 固定服务板块：由管理员在工作台配置，接入方统一通过 Karmen 实例调用。
- 固定职责与目标：例如客户咨询、询单整理或内部协作。
- 固定站点来源：公开组件只能在获准的网站来源中使用。
- 独立知识与会话：岗位 A 不能读取岗位 B 的客户资料。
- 独立服务器 API Key：Key 自动绑定 Karmen 实例，调用方不能在请求中切换为其他实例。
- 独立运行状态：暂停、撤销密钥或撤回资料会立即影响后续请求。

工作台内部仍可以把它称为“岗位”，底层标识仍是 `jobId`；面向接入方统一称为“Karmen 实例”。Karmen 的中央记忆、NAS 原始资料、其他实例记录、内部备注和模型凭据不会通过实例 API 暴露给客户。

### 接入方最终获得什么

完成配置后，接入方只需要三项内容：

1. `KARMEN_BASE_URL`：Karmen 原生 API 的 HTTPS 地址。
2. `KARMEN_API_KEY`：绑定某个 Karmen 实例的服务器密钥。
3. Karmen v1 合同：规定如何检查连接、发送消息和延续会话。

这三项就是完整的接入凭证。接入方不需要获得底层模型 Key、内部提示词、NAS 路径或 Karmen 的管理权限。

## 3. 选择接入方式

### 方式 A：网站有自己的后端

推荐使用服务器 API。网站后端保存 `KARMEN_BASE_URL` 和 `KARMEN_API_KEY`，浏览器只调用你自己的网站后端。

适合：CRM、会员网站、App 后端、需要把会话关联到已登录客户的系统。

### 方式 B：只有静态网站

使用工作台生成的一行嵌入代码。公开组件使用短时访客会话，不在网页中放服务器 API Key。

适合：公开客服、咨询入口和需求表单。涉及客户私密数据、订单或账号操作时，仍应接入网站自己的登录和后端授权。

### 方式 C：CRM 或业务平台

CRM 使用方式 A。每个 CRM 租户或业务岗位使用独立 Karmen 实例与独立 Key，在 CRM 服务端保存对应关系：

```text
CRM tenant_id + CRM user_id
          │
          ├─ 选择管理员预先部署的 Karmen 实例
          ├─ 生成稳定 userId
          ├─ 保存 conversationId
          └─ 调用 Karmen /v1/chat
```

CRM 用户不能提交 Karmen 的 `branch`、`model`、`system`、`tools` 或 NAS 路径。

## 4. 管理员部署 Karmen 实例

1. 在 Karmen 工作台创建实例，并选择该实例获授权使用的服务板块。
2. 配置实例的名称、职责、语言策略、网站来源和权限边界。
3. 上传已获授权的岗位 MD 包、PDF、DOCX 或 MD 知识资料。
4. 等待资料状态变为可检索。可检索表示解析与索引完成，不表示训练了新的模型权重。
5. 确认实例的隔离模型入口已经配置，然后启用实例。
6. 在“接入与密钥”中创建服务器 API Key。每个实例最多同时保留 20 个未撤销 Key；Key 默认永久有效，直到管理员主动删除或撤销。
7. 立即把完整 Key 保存到目标系统的服务器秘密变量。完整值只显示一次，Karmen 数据库只保存摘要。
8. 下载实例接入包。接入包包含客户端、连接检查、公开实例设置、OpenAPI 合同和本指南，不包含知识正文、会话、内部配置或任何已签发 Key。

生成 Key 不等于生产链路已经通过。上线前必须分别核验模型、知识、目标网站、邮箱、NAS 回传和沙箱状态；未连接的能力保持未连接。

## 5. 服务器环境变量

```dotenv
KARMEN_BASE_URL=https://your-karmen-api.example/v1
KARMEN_API_KEY=在工作台中签发并只保存到服务器秘密变量
```

不要使用 `NEXT_PUBLIC_`、`VITE_` 或其他会进入浏览器构建产物的变量名。不要把 Key 写进 Git、HTML、移动端安装包、提示词、知识文件、日志或错误页面。

## 6. 验证连接

连接检查只验证 Key、岗位绑定、岗位状态和聊天配置，不调用模型：

```bash
curl --request GET \
  --url "$KARMEN_BASE_URL/connection" \
  --header "Authorization: Bearer $KARMEN_API_KEY"
```

响应示例：

```json
{
  "authenticated": true,
  "apiVersion": "v1",
  "jobId": "job-0123456789abcdef0123456789abcdef",
  "status": "active",
  "chat": {
    "configured": true,
    "enabled": true,
    "verified": false
  }
}
```

`verified: false` 是刻意设计：连接检查没有调用模型，不能把“配置存在”冒充“真实回答已验收”。

## 7. 调用已挂载的 Karmen AI

```bash
curl --request POST \
  --url "$KARMEN_BASE_URL/chat" \
  --header "Authorization: Bearer $KARMEN_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "requestId": "req_0123456789abcdef0123456789abcdef",
    "userId": "crm-user-1842",
    "message": "请根据已获授权的资料介绍这项服务。"
  }'
```

`message` 最多为 20,000 个 Unicode 字符，JSON 请求体最多为 262,144 字节。服务会把合规正文完整交给已绑定的 Karmen 实例；内部知识检索使用独立的有限检索词预算，不会因为提示词拼接或检索长度而截断正文。

`requestId` 与提供的 `conversationId` 均须匹配 `^[A-Za-z0-9_-]{16,100}$`，即16至100个英文字母、数字、下划线或连字符。首次请求省略 `conversationId`。请求须使用 `Content-Type: application/json`；超出字节上限返回 `413 request_too_large`，媒体类型不符返回 `415 json_required`。

响应示例：

```json
{
  "reply": "这是 Karmen 实例生成的回答。",
  "conversationId": "conv_0123456789abcdef0123456789abcdef",
  "sources": [
    {
      "label": "S1",
      "documentId": "doc_0123456789abcdef0123456789abcdef",
      "name": "产品资料.md",
      "section": "服务范围"
    }
  ]
}
```

Karmen 返回固定 JSON 结构，方便 CRM 保存回答、会话和来源。API Key 已经决定使用哪个 Karmen 实例，因此请求中不需要再次提交模型名、角色名或内部路由参数。

Karmen 的处理顺序是：验证 Key → 定位实例 → 恢复该用户的会话 → 加载获授权知识 → 调用当前实例的能力入口 → 记录审计 → 返回 Karmen 结果。这就是 Karmen 自己的运行方法，不依赖接入方理解内部模型结构。

## 8. Node.js 客户端

接入包中的 `karmen-client.mjs` 无第三方依赖，只用于服务器端：

```js
import {createKarmenClient} from './karmen-client.mjs';

const karmen = createKarmenClient({
  baseURL: process.env.KARMEN_BASE_URL,
  apiKey: process.env.KARMEN_API_KEY,
});

const connection = await karmen.connection();
if (!connection.chat.enabled) {
  throw new Error('Karmen 岗位尚未启用或未配置聊天服务');
}

const result = await karmen.chat({
  userId: authenticatedUser.id,
  message: validatedMessage,
  requestId: stableRequestId,
  conversationId: savedConversationId,
});

await conversations.save({
  userId: authenticatedUser.id,
  conversationId: result.conversationId,
  reply: result.reply,
  sources: result.sources,
});
```

`userId` 必须从目标系统已经鉴权的用户推导，不能直接相信浏览器传来的其他用户 ID。`conversationId` 必须与同一用户绑定；不要让用户枚举或切换他人的会话。

## 9. Idempotency 与安全重试

`POST /v1/chat` 使用请求体中的 `requestId` 做 Idempotency（幂等）控制：

- 发送前，在调用方服务端持久保存原 `requestId`、`userId`、`conversationId`（首次请求省略）和完整请求体。不要只保存消息正文。
- 同一业务动作获准重试时，复用原ID及完整请求体，包括属性顺序。当前服务端按 `JSON.stringify(body)` 摘要比较；不要重新排列字段、增删可选字段或换用新的用户标识。
- 已完成的同ID同请求体返回缓存结果；不同请求体返回 `409 request_id_conflict`；处理中返回 `409 request_in_progress`；结果未知返回 `409 request_outcome_uncertain`。
- 超时、网络失败或结果未知不等于模型没有执行。停止自动重发并交管理员核对；当前没有公开请求查询或结果核对端点，不能编造查询接口。
- 错误响应的 `requestId` 是新生成的诊断追踪号，不是原业务幂等号。保留它用于排障，但不能拿它或客户端默认生成的新 UUID 重发原业务。
- 当前客户端不自动重试。只有确定未受理并符合业务策略时，调用方才可有限重试，并显式传入已保存的原 `requestId`。

## 10. 会话与记忆边界

- `userId` 标识目标系统中的稳定用户，Karmen 在服务端将它转换成岗位内隔离身份。
- `conversationId` 延续同一用户在同一岗位的对话。
- 岗位只能使用自己的会话和已批准知识。
- 客户不能读取 Karmen 中央记忆、NAS 全库、其他岗位会话或内部员工备注。
- 岗位事件可以进入 NAS 待回传队列；NAS 已收件不等于 Karmen 总脑已经理解、汇总或训练。
- 资料撤销需要传播到检索和待执行内容；不能仅在界面隐藏。

## 11. 邮箱、CRM、NAS 与沙箱

### CRM

当前 `/v1/chat` 可供 CRM 服务端调用。CRM 负责用户登录、客户权限、对话归属和业务记录；Karmen 负责岗位身份、授权知识、模型调用和岗位审计。

### 邮箱

邮箱选择、收件、人工回复和回执目前属于工作台登录接口，不属于服务器 API Key 的公开 v1 合同。只有完成真实邮箱桥接、收件 Worker、回复策略、SMTP 回执和人工接管验收后，才能增加对外邮箱能力。当前文档不承诺 `POST /v1/email/send`。

### NAS

NAS 是内部单向归档与总脑消费通道。公开 API 没有 NAS 读取端点，调用方不能通过 Key 获取 NAS 文件、目录、凭据或中央记忆。

### 沙箱

当前岗位任务可以进入审批台账；没有受限执行器时状态保持 `awaiting_executor`。服务器 Key 不能提交 shell、SQL、任意 URL 或任意工具调用。

## 12. 错误处理

错误使用固定结构：

```json
{
  "error": "stable_machine_code",
  "requestId": "req_0123456789abcdef"
}
```

这里的 `requestId` 是诊断追踪号。调用方应分别保存原业务请求ID和此追踪号，后者不能替代前者用于重试。

| HTTP | 含义 | 调用方处理 |
| --- | --- | --- |
| 400 | 请求字段或格式不正确 | 修正请求，不重试原错误内容 |
| 401 | Key 无效、已删除、已撤销或已过期 | 停止调用并联系岗位管理员 |
| 403 | 把服务器 Key 用在浏览器，或来源不允许 | 将调用移动到服务器端 |
| 404 | 会话不属于当前用户/岗位，或资源不存在 | 不枚举资源，核对本地归属 |
| 409 | 岗位暂停、幂等冲突或结果仍未知 | 保留原请求，人工或按原 ID 核对 |
| 413 | `request_too_large`，JSON请求体超过262,144字节 | 缩减待提交内容；不要重试相同的超大请求 |
| 415 | `json_required`，媒体类型不符 | 使用 `Content-Type: application/json` |
| 429 | 超过额度或并发限制 | 遵循 `Retry-After`，排队并降低速率 |
| 502 | 上游没有成功返回 | 保留原请求与诊断追踪号；结果未知时停止自动重发，交管理员核对 |
| 503 | 岗位模型尚未配置 | 保持“未配置”，不要降级成演示数据 |

当前 Key 连接检查限制为每分钟 60 次，聊天同时受岗位、访客和服务并发限制。发生 `429` 时响应带 `Retry-After`。不要假设 HTTP 200 之外的响应包含内部上游错误原文。

## 13. 当前 v1 不支持什么

- 不兼容 OpenAI SDK，也不是 OpenAI `/v1/chat/completions` 的完整替代品。
- 不支持流式响应、WebSocket 或 Server-Sent Events。
- 不允许调用方选择模型、板块、system prompt、tools 或内部 Agent。
- 不支持调用方提交任意结构化输出 Schema。
- 不提供任意工具调用、任意网页访问、shell、SQL、VM 或 NAS 管理能力。
- 不提供公开邮箱发送 API、Webhook、批量推理或文件上传 API。

这些能力只有在完成合同、权限、审计、幂等和真实生产验收后，才会以向后兼容的方式加入。

## 14. 版本与兼容策略

- 主版本位于路径中：`/v1`。
- v1 内只做向后兼容的增加，不删除或重命名现有字段。
- 破坏性变化使用新的主版本，并提供迁移指南和停用窗口。
- 调用方应忽略不认识的新增响应字段，但不得假设枚举永远不增加。
- 完整机器合同见 `openapi-karmen-v1.json`。

## 15. 上线验收

在对 CRM 或客户网站宣布可用前，逐项保存真实证据：

1. `GET /v1/connection` 使用目标岗位 Key 成功，并确认 `jobId` 正确。
2. 使用明确许可的测试用户发送一条真实模型消息，得到非演示回答。
3. 同一用户继续会话成功；不同用户不能读取该 `conversationId`。
4. 引用资料只来自该岗位已批准知识，撤回后不能继续检索。
5. 暂停岗位或删除 Key 后，新的聊天立即失败。
6. 目标 CRM 不记录完整 Key，不把 Key 下发到浏览器。
7. 邮箱、NAS 和沙箱分别验收；其中一项未接通不能被聊天成功掩盖。

## 16. Karmen 接入原则

- 接入方调用的是 Karmen，不是底层模型供应商。
- API Key 绑定一个已经部署的 Karmen 实例，不允许请求临时越权切换实例。
- Karmen 内部如何组合模型、知识、记忆和工具，不成为客户的接入负担。
- 内部能力升级时保持 Karmen v1 合同稳定；破坏性变化必须发布新的主版本。
- Karmen 的唯一准确信息源是本指南、OpenAPI 合同以及工作台显示的真实实例状态。
