> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qoder.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Skills

`options.skills` 控制当前会话里 `Skill` 工具能调用哪些 skill。SDK 会把它编译成 CLI 的 `Skill` allowlist，并与 `allowedTools` 合并后透传给 qodercli。

<div id="sdk-不加载内置-skills" />

## SDK 不加载内置 skills

SDK 启动 CLI 时**始终**追加 `--disable-builtin-skills`，会话不会拿到 CLI 出厂内置的那批 skill（`simplify`、`debug`、`security-review`、`quest`、`batch`、`agent-creator`、`hook-config`、`mcp-config`、`skill-creator` 等）。`init.skills` 里也不会出现 `source: 'built-in'` 的条目，模型系统提示同样看不到它们。

这是 SDK 的固定行为，没有开关可以打开；如果你想要 CLI 内置 skill 的能力，要么自己在 plugin / 用户目录 / 项目目录里复刻一份 SKILL.md，要么直接复用 CLI 默认场景。

你的会话仍然能用以下来源贡献的 skills：

* **plugin skills**：通过 `options.plugins` 加载，使用插件限定名（`plugin:skill`）。
* **用户 / 项目 skills**：通过 `options.settingSources` 显式打开 `user` / `project` / `local` 后被发现。
* **Agent 预加载 skills**：在 `options.agents[name].skills` 里声明，只对该子 Agent 生效。

要稳定确认本次会话发现到了哪些 skills，请运行一次 `query()` 后读 `init.skills`；不要在代码里硬编码集合。

***

<div id="使用-cli-默认策略" />

## 使用 CLI 默认策略

不传 `skills` 时，SDK 不额外注入 `Skill` allowlist，完全交给 CLI 自身策略。由于内置 skill 已经被禁用，没有 `settingSources` / `plugins` 的会话 `init.skills` 会是空数组。

```typescript theme={null}
import { query } from '@qoder-ai/qoder-agent-sdk';

const q = query({
  prompt: 'Analyze the test coverage of this project',
  options: {
    cwd: '/path/to/project',
  },
});
```

<div id="启用所有已发现-skills" />

## 启用所有已发现 skills

```typescript theme={null}
const q = query({
  prompt: 'Use an appropriate skill to perform a code review',
  options: {
    cwd: '/path/to/project',
    settingSources: ['project'],
    skills: 'all',
  },
});
```

`skills: 'all'` 会允许 `Skill` 工具调用所有当前 CLI 发现到的 skill（来源由 `settingSources` / `plugins` 决定，不再包含内置）。

<div id="只启用指定-skills" />

## 只启用指定 skills

```typescript theme={null}
const q = query({
  prompt: 'Use the review skill to inspect recent changes',
  options: {
    cwd: '/path/to/project',
    settingSources: ['project'],
    skills: ['review'],
  },
});
```

<div id="启用插件内-skill" />

## 启用插件内 skill

插件内 skill 使用插件限定名。关于 plugin 加载方式见 [Plugins 文档](/zh/cli/sdk/plugins)。

```typescript theme={null}
const q = query({
  prompt: 'Use the echo skill provided by the plugin to handle this input',
  options: {
    plugins: [{ type: 'local', path: '/path/to/sdk-test-plugin' }],
    skills: ['sdk-test-plugin:sdk-echo'],
  },
});
```

<div id="与显式工具白名单合并" />

## 与显式工具白名单合并

```typescript theme={null}
const q = query({
  prompt: 'Read the source and use the review skill to produce a list of issues',
  options: {
    cwd: '/path/to/project',
    settingSources: ['project'],
    allowedTools: ['Read', 'Grep'],
    skills: ['review'],
  },
});
```

上面的配置最终允许 `Read`、`Grep` 和 `Skill(review)`。

<div id="隐藏已发现的-skills" />

## 隐藏已发现的 skills

`options.skills` 是工具许可、不是发现过滤。想真正让某个 plugin / 用户 / 项目 skill 不出现在 `init.skills`、也不参与模型系统提示，需要走 `settings.skillOverrides`。

```typescript theme={null}
const q = query({
  prompt: 'Handle this task',
  options: {
    plugins: [{ type: 'local', path: '/path/to/sdk-test-plugin' }],
    settings: {
      skillOverrides: {
        'sdk-test-plugin:sdk-echo': 'off',
      },
    },
  },
});
```

* `'off'`：完全隐藏，不进 `init.skills`、不进模型系统提示、`Skill` 工具调用也会被拒。
* 其它取值：`'on'`（默认）、`'name-only'`（只露名字、不露描述）、`'user-invocable-only'`（模型看不到，用户仍可通过 `/name` 触发）。
* 影响范围：plugin、user、project 等所有 SDK 可见来源都尊重该 override；CLI 内置 skill 已经被 `--disable-builtin-skills` 拦在外面，写不写 override 都不会出现。
* key 命名规则：插件 skill 用插件限定名 `plugin:skill`；非插件 skill 用裸名。两种形态可以同时写，匹配时先按完整名命中、缺命中则退回裸名。

> `options.skills` 只控制工具调用许可，**不能用于隐藏 skill 的发现 / 上下文露出**。

***

<div id="读取当前会话发现到的-skills" />

## 读取当前会话发现到的 skills

初始化结果会包含 CLI 在本次会话中发现到的 skills，适合宿主 UI 展示「当前可用能力」。

```typescript theme={null}
const q = query({
  prompt: 'Do not execute any task yet',
  options: {
    cwd: '/path/to/project',
    settingSources: ['project'],
    skills: 'all',
  },
});

const init = await q.initializationResult();
console.log(init.skills?.map((skill) => skill.name));
```

> `skills` 是上下文与工具可见性控制，不是安全边界。未列出的 skill 不会通过 `Skill` 工具暴露给模型，但 skill 文件仍在磁盘上，仍可能被普通文件读取工具访问。

***

<div id="自定义-agent-预加载-skills" />

## 自定义 Agent 预加载 Skills

如果你用 `options.agents` 定义自定义子 Agent，可以在 Agent 定义里声明 `skills`。这样当主会话调用 `Agent` 工具时，子 Agent 会带着指定 skill 运行。

```typescript theme={null}
const q = query({
  prompt: 'Dispatch a helper agent that uses the sdk-agent-marker skill to return the marker',
  options: {
    cwd: '/path/to/project',
    allowedTools: ['Agent'],
    agents: {
      'sdk-skill-helper': {
        description: 'Invoke when the sdk-agent-marker skill is needed.',
        prompt: 'You are a helper agent that only reads and runs the specified skill.',
        skills: ['sdk-agent-marker'],
        maxTurns: 2,
      },
    },
  },
});
```

这类 `skills` 只影响该 Agent 的上下文，不等价于给主会话启用同名 skill。

***

<div id="options-速查" />

## Options 速查

| 字段               | 类型                                   | 说明                                         |
| ---------------- | ------------------------------------ | ------------------------------------------ |
| `skills`         | `string[] \| 'all'`                  | 控制主会话可通过 `Skill` 工具调用哪些 skills             |
| `agents`         | `Record<string, AgentDefinition>`    | 自定义 Agent；Agent 内可声明独立的 `skills` 预加载列表     |
| `allowedTools`   | `string[]`                           | 工具白名单；会与 `skills` 编译出的 `Skill(...)` 条目合并去重 |
| `settingSources` | `('user' \| 'project' \| 'local')[]` | 决定 CLI 是否扫描用户 / 项目目录里的 skills（默认空 = 沙箱）    |
| `plugins`        | `PluginSpec[]`                       | 加载插件，插件里的 skills 会进入发现集合                   |

`settings` 还有几个 skill 相关字段，SDK 都是透传，实际效果取决于 CLI 版本是否实现：

| 字段                              | 作用                                                                                                       |
| ------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `skillOverrides`                | 按 skill 名设置 `'on' \| 'name-only' \| 'user-invocable-only' \| 'off'`；plugin、user、project 等来源都尊重该 override |
| `skillListingMaxDescChars`      | skill listing 里每条描述的字符上限（SDK 默认 1536），超过会被截断                                                             |
| `skillListingBudgetFraction`    | 给 skill listing 预留的上下文窗口比例（SDK 默认 0.01 = 1%），超出后描述会被压缩                                                   |
| `strictPluginOnlyCustomization` | 把 `skills`、`agents`、`hooks`、`mcp` 中的一项或多项限制成只能由插件来源贡献                                                    |

***

<div id="返回值参考" />

## 返回值参考

```typescript theme={null}
type SDKControlInitializeResponse = {
  skills?: Array<{ name: string; description?: string; source?: string }>;
  // ...also returns commands / agents / plugins and similar fields
};
```

***

<div id="最佳实践" />

## 最佳实践

* **按需启用 `skills`**：`skills: 'all'` 适合开发和调试；面向最终用户的产品通常应该传明确列表。
* **想要 CLI 内置 skill 的行为，自己复刻**：SDK 不会把 `simplify` / `security-review` 这些塞进会话，需要的话在 plugin 或 settingSources 范围里自己提供 SKILL.md。
* **不要把 `skills` 当沙箱**：安全边界应由 `allowedTools`、`disallowedTools`、`canUseTool`、权限模式和沙箱共同控制。
* **给 UI 用 `initializationResult().skills`**：这是 CLI 发现链路的稳定入口，用来展示「当前可用 skill」。
* **子 Agent 的 `skills` 单独管理**：它与主会话 `options.skills` 是两套独立的列表，互不覆盖。
