---
url: /zh/build/npc.md
description: |
  介绍云原生构建中的 NPC（自动化角色）概念及其触发的事件类型， 支持在 Issue 和 PR 评论中通过 @ 提及触发自动化任务。
---
云原生构建里的 **NPC（Non-Player Character）** 是一类自动化角色：在 Issue 或 PR 的评论里
`@` 一个 NPC 并描述需求，平台就会为它启动一条流水线，让它替你自动回复、协作代码，甚至闭环解决 Issue。
NPC 包括开箱即用的**系统 NPC**，也有你在仓库里自定义的**自定义 NPC**。
本文介绍 NPC 的使用方法、触发事件、工作模式与安全限制，以及如何定义和定制你自己的 NPC。

## 快速上手

在 Issue 或 PR 的评论中 `@CodeBuddy` 并说出需求，它会自动执行并回复：

```text
@CodeBuddy 帮我实现这个 Issue
@CodeBuddy 帮我审查一下这个 PR 的代码
```

`@CodeBuddy` 是系统内置 NPC，开箱即用。

**定义自己的 NPC**

在仓库 `.cnb/settings.yml` 里配置角色，即可通过 `@仓库路径(角色名)` 使用：

```yaml title=".cnb/settings.yml"
npc:
  roles:
    - name: 专家
      prompt: |
        你以“专家”自称，致力于提供专业、准确的技术解答。
```

```text
@<你的仓库路径>(专家) 帮我回答下这个 issue。
```

将 `<你的仓库路径>` 替换为实际路径，例如 `your-group/your-repo`。
系统会使用默认运行环境（`cnbcool/default-npc:latest`），无需额外配置 `.cnb.yml` 或 Dockerfile。

如需进一步指定运行镜像、模型或注入自定义提示词，见 [自定义 NPC](#自定义-npc)。

## 理解 NPC

上手之后，这一部分带你搞懂 NPC 到底是什么、有哪几类，以及如何选用。

### 什么是 NPC

NPC（Non-Player Character）是云原生构建中的**自动化角色**——虚拟智能助手，
可以替你回复评论、协作代码等。

云原生构建把用户操作分为两类：手动点击、编辑的**页面交互**，
以及 NPC 代你完成的**自动化交互**。后者的操作者身份统一显示为 **`NPC`**，与真人区分。

`@` 提及 NPC 时，平台会为它启动一条流水线，由 NPC 在其中执行任务并回复。

### 委托代理模型

NPC 代你操作，本质上是一次**委托**：你把任务托付给 NPC，
NPC 以你的名义在限定范围内代办。云原生构建为这层关系定义了三个术语：

* **当事人**（principal）：发起委托的用户，即 `@` 提及 NPC 的操作者。
  平台按当事人的角色为 NPC 流水线签发临时令牌。
* **代理人**（agent）：受托执行任务的 NPC，以当事人名义在限定范围内代办，
  对外展示为 NPC 身份。
* **代理权**（delegated authority）：当事人授予代理人的权限范围，受三重约束：

  * **限时**：仅本次任务有效。
  * **限地**：仅限当前仓库。
  * **限权**：角色上限为**开发者**（`Developer`）。

  任务结束或流水线销毁时自动终止。

### NPC 能力

NPC 能做的事分为三层，由浅入深：

* **自动回复**：回答评论区问题、给出代码审查意见等文字回复
* **工作模式**：开启后 NPC 可自主写代码、推代码、建分支、发 PR、按评审意见修改，闭环解决 Issue
* **自定义行为**：定义 NPC 的角色人设与运行方式

### 读取并分析图片

在 Issue 或 PR 的讨论里，你可以直接粘贴图片（如错误截图、界面截图、流程图），
并在同一段文字里要求 NPC 查看并分析这些图片，让 NPC 结合文字完成分析、定位问题。

NPC 是否支持读取图片，由**平台配置 + 模型能力**共同决定：

* 平台可在 `NPC_CONFIG` 中声明 `supportImage: true`，作为默认模型的基础图片能力。
* 同时要求 NPC 所采用的**底层模型支持图片输入**，两者都满足时 NPC 才会真正
  读取并理解图片内容。

除平台配置外，你也可以在自己流水线的 `npc:go` options 中通过 `supportImage`
字段开启或关闭图片输入：

* 未指定该字段时，其默认值按以下规则决定：
  * 未在 `npc:go` 中指定 `model`（走平台默认模型）时，继承平台 `NPC_CONFIG`
    为默认模型配置的 `supportImage`；
  * 在 `npc:go` 中指定了 `model`（自定义模型）时，**不继承**平台为默认模型
    配置的 `supportImage`，回落到内置默认 `false` —— 因为不同模型的图片能力
    并不通用，避免误把针对默认模型开启的开关套用到自定义模型上。
* 显式传 `supportImage: true` 时才会声明图片输入并注入读图能力。

:::: tip 说明

* 图片支持 PNG / JPEG / WebP / GIF，单张不宜过大。
* 若能力未开启或模型暂不支持图片输入，读取图片只会返回路径、类型与大小等
  元信息，无法识别图片内容。此时可改用文字描述问题。
  ::::

### 两类 NPC

云原生构建里有两类 NPC：

* **系统 NPC**——平台内置，目前是 `CodeBuddy`，通过 `@CodeBuddy` 直接使用。
* **自定义 NPC**——用户在自己的仓库中定义的角色，通过 `@仓库路径(角色名)` 提及：

```text
@<你的仓库路径>(专家) 帮我回答下这个 issue。
```

`@` 后是 **NPC 所属仓库路径**（如 `your-group/your-repo`），
括号里是**角色名**（如 `专家`），两者共同定位到一个具体的 NPC。

### NPC 选择器

在评论编辑器中输入 `@` 即可弹出 NPC 选择器，
其中列出了系统 NPC、你定义的 NPC，以及你关注仓库中的 NPC，点选即可提及。

### 工作模式

默认情况下，NPC 只能读代码、写评论。如需让它完成开发闭环（写代码、推代码、发 PR），
在评论区勾选 **`替我上班`** 开启工作模式，即可授予更高权限。

开启工作模式需要仓库 **开发者及以上** 权限。开启后，NPC 可自主：

* 编写代码、推送代码、创建分支
* 创建合并请求（PR）
* 按 PR 评审意见修改代码
* 协助解决 Issue

详细令牌权限说明见 [CNB\_TOKEN](./build-in-env.md#cnb_token)。

![在 Markdown 编辑器中选择 NPC 角色并开启工作模式的示意图](/images/build/how-to-use-npc.zh.png)

## NPC 事件

`@` 提及 NPC 时启动的那条流水线，就是由**NPC 事件**触发的。
这一节展开讲：都有哪些 NPC 事件、如何执行、以及配套的安全限制。

### 事件类型

目前 NPC 事件都由**评论触发**，共两种：

* `issue.comment@npc`：在 Issue 描述或评论中提及 NPC 时触发
* `pull_request.comment@npc`：在 PR 描述、评审、评审评论或评论中提及 NPC 时触发

:::: warning 重要提示

* 重新打开 PR、Issue，或编辑描述、评论，都不会重新触发 NPC 事件。
* 一次最多支持触发 10 个 NPC 事件。
* 当 Issue 或 PR 的评论数超过 100 条时，对应的 `issue.comment` /
  `pull_request.comment` 及 `@npc` 事件都不再触发流水线。
* 以下格式中的 `@` 提及不会触发 NPC 事件：
  引用（blockquote）、代码块（code）、折叠块（details）、有序列表、无序列表、表格、部分 HTML 标签等。

::::

### 事件执行

NPC 事件触发的流水线，有几个关键点：

* **执行位置**：流水线跑在**当前 Issue 或 PR 所属仓库**下（不是 NPC 所属仓库）；
  触发者是当前操作用户（即 [委托代理模型](#委托代理模型)中的当事人）。
* **代码分支**：
  * `issue.comment@npc`：在仓库**默认分支**下执行
  * `pull_request.comment@npc`：
    * 默认在 PR 的**目标分支**下执行；跨仓 Fork PR 且触发者为 PR 提交者时，克隆**源仓库源分支**代码
    * PR 已合并时，克隆**合并后 commit** 的代码（源分支可能已删除），
      `CNB_COMMIT` 即合并后的 `sha`，可配合 `git cherry-pick` 把提交同步到其他分支
* **结果呈现**（以评论 Issue 为例）：
  1. 当前评论下方显示被提及的 NPC 角色名及流水线执行状态
  2. 若 NPC 使用 [CNB\_TOKEN](./build-in-env.md#cnb_token) 回复了评论，
     评论提交者显示为 NPC 角色名
* **计费口径**：NPC 视作开发场景，消耗**云原生开发**用量。

![NPC 事件触发后的效果展示](/images/build/npc.zh.png)

### 安全限制

以下限制是 [委托代理模型](#委托代理模型)中**限地**与**限权**约束的具体体现：

* **仓库范围**：NPC 事件流水线中 `CNB_TOKEN` **默认**仅限访问当前仓库。
  跨仓 Fork PR 的 `pull_request.comment@npc` 事件中，
  若触发者为 PR 提交者，`CNB_TOKEN` 仅限访问公开仓库。
* **角色上限**：`CNB_TOKEN` 的最大角色取决于触发用户在仓库中的角色：
  * `Developer` / `Master` / `Owner` → 最大角色 `Developer`
  * `Reporter` / `Guest` → 最大角色 `Reporter`，且**无法启用工作模式**
* **密钥引用**：NPC 流水线若通过 `imports`、`settingsFrom`、`optionsFrom` 等方式引用了
  [密钥仓库](./grammar.md#pipeline-imports)文件，该 NPC 将不可分享（不会出现在 NPC 榜单中）。

### 允许 NPC 跨仓操作

安全限制中的“仓库范围”是默认策略，可以由根组织管理员**显式放宽**。

在组织设置中开启 **「允许 NPC 跨仓操作」** 开关后，
NPC 事件流水线的 `CNB_TOKEN` 访问范围从“当前仓库”扩大到“当前根组织下的所有仓库”，
NPC 就能自动处理跨仓协作任务（如跨仓库读取代码、发起 PR 等）。

::: tip 边界说明

* 只放宽**限地**约束，不改变**限权**（角色上限）与**限时**（任务/流水线生命周期）约束。
* 放宽范围为**根组织内**：仍不允许跨根组织访问。
* 跨仓 Fork PR 场景（PR 提交者触发）仍走公开仓库限制，不受此开关影响。

:::

### 环境变量

NPC 事件流水线执行时，除通用环境变量外，还会注入 `CNB_NPC_*` 系列变量，
包含 NPC 角色名、所属仓库、当前 Issue/PR 上下文等，便于流水线中读取和使用。

完整变量清单请参考 [环境变量](./build-in-env.md#npc-variables)。

## 自定义 NPC

NPC 可以逐步定制，让它更贴合你的需求：

1. **定义角色（必选）**：在 NPC 所属仓库的 `.cnb/settings.yml` 中，
   配置角色名、头像、prompt 等。**只做这一步 NPC 就能用起来**——
   系统默认运行环境（`cnbcool/default-npc:latest`）会兜底后面的步骤。
2. **自定义行为（可选）**：在 NPC 所属仓库的 `.cnb.yml` 中，
   定义 NPC 事件流水线，控制 NPC 被 `@` 时具体做什么。
3. **自定义运行环境（可选）**：通过 `.cnb.yml` + `Dockerfile`，
   构建并指定 NPC 执行时使用的 Docker 镜像。

如果你已经按照上文 [快速上手](#快速上手)定义过角色，可直接从第 2 步开始。

::: tip 建议
每完成一步，在 Issue 评论中 `@` 该 NPC 验证效果，再继续下一步——比一次配到位更容易排查问题。
:::

### 定义 NPC 角色

在仓库的 `.cnb/settings.yml` 中，通过 `npc.roles` 列表定义一个或多个角色：

```yaml title=".cnb/settings.yml"
npc:
  roles:
    - name: 专家
      slogan: 专业解答，高效协助
      prompt: |
        你以“专家”自称，致力于提供专业、准确的技术解答。
        回复时保持简洁专业，引用可靠来源。
        无论是日常对话还是讲解知识，你都会保持以上风格
```

* **`name`**：角色名，`@` 提及时使用（如 `@your-group/your-repo(专家)`）
* **`slogan`**：角色标语，展示在 NPC 卡片和榜单中
* **`prompt`**：给 NPC 的系统提示词，决定它的人设与回复风格

更多可配置项（头像等）详见 [UI 定制配置文件](../repo/settings.md)。

### 自定义 NPC 行为

角色定义好后，NPC 已经具备默认响应行为（默认镜像 + `npc:go` 内置任务，执行任务并回复评论）。
如果默认行为够用，可以跳过本小节。

常见需要自定义的场景：使用自己构建的 NPC 镜像、
在流水线中准备运行环境（如 Skill 加载、预装编程语言、各种工具命令等）、
或按角色区分不同的响应流程。

做法：在 NPC 所属仓库的 `.cnb.yml` 中，把 NPC 事件流水线挂在 `$` 下（对所有角色生效）或角色名下（仅对指定角色生效）。

#### 最小示例

只自定义 `issue.comment@npc` 事件的流水线：

```yaml title="NPC 所属仓库的 .cnb.yml"
$:
  issue.comment@npc:
    - docker:
        image: cnbcool/default-npc:latest
      stages:
        - name: npc go
          type: npc:go
```

::: tip 镜像说明
最小示例中使用 `cnbcool/default-npc:latest` 作为运行环境。
如果你已构建并推送了自定义 NPC 镜像，可使用变量引用：

```yaml
image: ${CNB_DOCKER_REGISTRY}/${CNB_NPC_SLUG_LOWERCASE}:latest
```

:::

#### 配置合并机制

NPC 事件触发时，系统通过 [include](./grammar.md#include) 自动合并**系统默认配置**和
**NPC 仓库的 `.cnb.yml`**。NPC 仓库中已定义的事件覆盖默认，未定义的事件保留默认行为。

::: warning 注意
合并按**事件**独立进行。若只配了 `issue.comment@npc` 而未配 `pull_request.comment@npc`，
则 Issue 评论执行自定义流水线，PR 评论仍走默认。建议同时配置两个事件。
:::

以上面最小示例为例，合并后等效配置：

```yaml
$:
  issue.comment@npc: # 来自 NPC 仓库（覆盖默认）
    - docker:
        image: cnbcool/default-npc:latest
      stages:
        - name: npc go
          type: npc:go

  pull_request.comment@npc: # 来自系统默认（保留）
    default:
      docker:
        image: cnbcool/default-npc:latest
      stages:
        - name: npc go
          type: npc:go
```

#### 完整示例

相比最小示例，完整示例**使用自己构建并推送的 NPC 镜像**
（通过 `${CNB_DOCKER_REGISTRY}/${CNB_NPC_SLUG_LOWERCASE}:latest` 引用），
并把镜像构建流水线也放进同一 `.cnb.yml`。

**NPC 事件流水线**（定义 NPC 被 `@` 时的行为）：

```yaml title="NPC 所属仓库的 .cnb.yml（NPC 事件部分）"
$:
  issue.comment@npc:
    - docker:
        image: ${CNB_DOCKER_REGISTRY}/${CNB_NPC_SLUG_LOWERCASE}:latest
      stages:
        - name: npc go
          type: npc:go

  # 两个事件配置一致，可按需配置
  pull_request.comment@npc:
    - docker:
        image: ${CNB_DOCKER_REGISTRY}/${CNB_NPC_SLUG_LOWERCASE}:latest
      stages:
        - name: npc go
          type: npc:go
```

**Docker 镜像构建流水线**（在 push 事件上构建并推送镜像到制品库，供上面的 NPC 事件流水线使用）：

```yaml title="NPC 所属仓库的 .cnb.yml（镜像构建部分）"
main:
  push:
    - services:
        - docker
      stages:
        - name: build
          script: docker build -t ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:latest .
        - name: push
          script: docker push ${CNB_DOCKER_REGISTRY}/${CNB_REPO_SLUG_LOWERCASE}:latest
```

> 以上两部分可合并放在同一 `.cnb.yml` 文件中。镜像本身如何构建见后面的 [自定义运行环境](#自定义运行环境)。

#### 按角色名配置

如果一个仓库里定义了**多个 NPC 角色**，希望它们各自跑不同的流水线，
可以把事件挂在**角色名**顶层 key 下（与 `$` 平级）。当被 `@` 的角色名与某顶层 key 一致时，
才会加载对应的自定义流水线。

未在 `.cnb.yml` 中显式配置 NPC 事件时，系统会使用内置的 [默认配置](#配置合并机制)。
下例中，`专家` 角色被 `@` 时执行 `专家:` 下的自定义流水线；
其他角色（未匹配到任何顶层 key）走系统默认行为。

```yaml title="NPC 所属仓库的 .cnb.yml"
# 仅对「专家」角色覆盖事件流水线
专家:
  # Issue 评论与 PR 评论事件配置一致，可按需配置
  issue.comment@npc:
    default:
      docker:
        image: cnbcool/default-npc:latest
      stages:
        - name: npc go
          type: npc:go
  pull_request.comment@npc:
    default:
      docker:
        image: cnbcool/default-npc:latest
      stages:
        - name: npc go
          type: npc:go
```

**与 `$` 下配置的合并关系：**

如果仓库中同时存在 `$` 顶层 key（即所有角色共用的默认配置），匹配到角色名顶层 key 时，
会按 [include](./grammar.md#include) 语义与默认配置（系统默认 + `$` 下配置）合并；
**角色名下的同名事件会覆盖 `$` 下的同名事件**，未在该 key 下定义的事件仍走系统默认行为。

::::: tip 命名要求

* 顶层 key 必须与 `.cnb/settings.yml` 中 `npc.roles[].name` **完全一致**（区分大小写、字符精确匹配）。
* 顶层 key **不要**带 `@` 前缀、也不要带括号中的角色名，例如不要写 `@cnb/feedback(专家)`。
* 同一仓库下可以为不同角色各自定义独立的顶层 key，互不覆盖。
  :::::

### 自定义运行环境

`npc:go` 任务运行在 NPC 事件流水线的 Docker 容器中。
运行环境（即用哪个镜像）有三种选择，按需求由简到繁：

* **默认**：不做任何配置，系统使用 `cnbcool/default-npc:latest`。
* **直接指定已有镜像**：在 `.cnb.yml` 的 `docker.image` 中填一个现成镜像地址，
  跳过自己构建的步骤。
* **构建自定义镜像**：编写 `Dockerfile`，用一条流水线把镜像构建并推送到制品库，
  再在 NPC 事件流水线的 `docker.image` 中引用它。

> 注意：Dockerfile 不会被 NPC 直接读取运行，它只用于构建镜像。
> 完整流程见上面的 [完整示例](#完整示例)：`Dockerfile` → push 事件构建镜像 → NPC 事件引用镜像。

#### 自定义镜像的 Dockerfile 示例

构建自定义 NPC 镜像时，Dockerfile 里通常需要安装 NPC 运行时依赖的 Skills 和 CLI 工具。
下面的示例安装了 `cnb-cli` 和 `skills` 命令行，并预装了官方 `cnb-skill`：

```Dockerfile title="Dockerfile"
FROM node:22-bookworm-slim

RUN apt-get update \
    && apt-get install -y --no-install-recommends ca-certificates git git-lfs curl jq ripgrep \
    && rm -rf /var/lib/apt/lists/* \
    && git lfs install \
    && npm install -g @cnbcool/cnb-cli skills \
    && npx skills add https://cnb.cool/cnb/skills/cnb-skill.git -g -y
```

::: tip Skills 加载目录
Skills 会自动加载以下目录：

* 全局级：`~/.agents/skills`、`~/.codebuddy/skills`
* 项目级：`.agents/skills`、`.codebuddy/skills`

同名 Skill **全局级优先**，会覆盖项目级：
项目仓库里自带一份同名 Skill 时，以镜像内安装的全局版本为准，
避免仓库内未及时更新的旧副本（如旧版 `cnb-skill`）顶掉全局版本。

:::

### 分享 NPC

定义了好用的 NPC 后，如何让其他人也能使用？

**他们怎么找到你的 NPC？**
只要 NPC 所属仓库是公开的，或者对方拥有该仓库的读权限，
就能在评论编辑器中输入完整 NPC 路径 `@仓库路径(角色名)` 直接提及。
路径格式参考上文 [两类 NPC](#两类-npc)。

**如何让 NPC 出现在选择器里？**
当其他人关注了 NPC 所属仓库后，你定义的 NPC 会自动出现在对方的 `@` 选择器中，
无需记路径。详见上文 [NPC 选择器](#npc-选择器)。

## 更多使用场景

前面讲的都是 `@` 触发的场景，但**NPC 的核心是 AI 驱动的自动化任务**，`@` 只是入口之一。
在任意事件的流水线里，都可以用内置任务 [npc:go](./internal-steps/npc/go.md) 把 NPC 能力用起来。

### 示例 1：PR 自动审查

场景：不想每次都手动 `@CodeBuddy` 审 PR，希望每次开 PR 就自动跑一次 AI 审查。

```yaml title=".cnb.yml"
$:
  pull_request:
    - docker:
        image: cnbcool/default-npc:latest
      stages:
        - name: npc go
          type: npc:go
          options:
            role: 代码审查员
            systemPrompt: 你是一个专业的代码审查员，请审查代码变更并给出改进建议
            userPrompt: 审查本次 PR 的代码变更，给出改进建议
```

### 示例 2：网页按钮手动触发

场景：在仓库主页放一个按钮，点击后弹窗输入任务描述，交给 NPC 去执行——
用户不需要写评论，也不需要懂流水线。

```yaml title=".cnb.yml"
$:
  web_trigger:
    - docker:
        image: cnbcool/default-npc:latest
      stages:
        - name: npc go
          type: npc:go
          options:
            role: 小助
            systemPrompt: 你是一个助手，负责执行用户指定的任务并回复结果
            userPrompt: $userPrompt
```

其中 `$userPrompt` 会读取用户在页面上填写的 `userPrompt` 输入框。
关于按钮如何配置，参考 [手动触发流水线](./web-trigger.md)。

### 示例 3：CI 失败自动分析

场景：流水线失败时自动让 AI 分析根因、给出解决方案，
并把结果推送到企微群，比人工翻日志排查快得多。

这个案例涉及**失败上下文收集 → AI 分析 → 通知推送**完整链路，
完整配置和讲解见 [失败流水线 AI 分析并通知](./showcase/ci-fail-ai-analyze.md)。

::: tip 代码写权限
NPC 事件下，通过开启 [工作模式](#工作模式)获得代码写权限。
其他事件下，NPC 能否协作代码取决于流水线的
[CNB\_TOKEN](./build-in-env.md#cnb_token) 权限，与 NPC 事件的规则不同。
:::

### 通过 API 以 NPC 身份触发

除了 `@` 评论、其他事件之外，还有第三种入口：直接调 OpenAPI 触发构建。
只要在触发 [`api_trigger`](./trigger-rule.md#api_trigger) 时传入 `npc.name=CodeBuddy`，
该次构建就会**按 NPC 语义处理**：

* 操作者展示为 NPC 身份，而非调用 API 的用户
* 构建标题按 NPC 语义生成
* 计费口径归入 NPC 场景
* Token 资源限定按 NPC 规则收窄

这条路径不是评论触发的事件，`npc:go` 的 `systemPrompt` / `userPrompt` 仍从流水线 `options` 里读，与示例 1/2 一致。

### 外部系统接入

如果你希望把 CNB NPC 嵌进自己的平台（例如客服系统、内部工作台），
让外部业务的一次动作触发 NPC 任务，可以通过 API 触发流水线来实现。

完整对接方案见 [外部系统接入 NPC](./npc-integration.md)。
