记录DirectProject客户端Skill自然语言触发能力缺口
新增当前AGC Skill导入、注入和显式使用方式说明 记录普通自然语言触发缺口与可复现测试步骤 整理Codex客户端分层和候选修复方向
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
# DirectProject 客户端 Skill 自然语言触发能力缺口
|
||||
|
||||
状态:待提 Issue,当前仅记录现状和候选方向,未修改代码。
|
||||
|
||||
## 1. 问题摘要
|
||||
|
||||
AGC 已经可以把用户导入的 Skill 安装到客户端,并在下一次 DirectProject 启动时注入真实 Codex app-server。使用 Codex 原生的 `$skill-name` 形式时,导入的 Skill 可以被读取并执行。
|
||||
|
||||
目前缺少的是:用户在普通自然语言中直接提到 Skill 名称时,AGC 没有把这次请求确定性地绑定为 Codex 的 Skill 输入项。结果是模型可能只看到用户提到了一个名称,并把“调用 Skill”误解成调用一个工具,返回“没有可调用接口”,而不是读取 `SKILL.md`。
|
||||
|
||||
这不是 Skill 导入失败,也不是需要把 Skill 改造成 MCP 工具;是 AGC 客户端没有复用 Codex 官方客户端的 Skill 输入适配层。
|
||||
|
||||
## 2. 当前 AGC 如何使用 Skill
|
||||
|
||||
### 2.1 客户端导入
|
||||
|
||||
用户在客户端设置的“扩展”页面导入文件、目录或 zip。目录或 zip 中发现的每个 `SKILL.md` 会成为独立的 Skill 扩展项,可以单独启用、禁用、重命名和删除。
|
||||
|
||||
已识别的 Skill 导入后默认启用。扩展内容保存于 AGC 客户端扩展仓库,不直接写入用户全局 `CODEX_HOME`。
|
||||
|
||||
### 2.2 DirectProject 启动时注入
|
||||
|
||||
创建或复用 DirectProject 的 Codex app-server 时,AGC 会:
|
||||
|
||||
1. 读取客户端扩展索引中 `enabled=true` 的 Skill;
|
||||
2. 在本次隔离运行的临时 HOME 下创建客户端 Skill root;
|
||||
3. 将每个 Skill 的运行时副本复制到该目录;
|
||||
4. 对手动重命名的 Skill,只在运行时副本的 frontmatter 中使用当前名称;
|
||||
5. 调用 Codex app-server 的 `skills/extraRoots/set`;
|
||||
6. 调用 `skills/list` 重新发现 Skill。
|
||||
|
||||
AGC 侧的运行时目录准备位于 [`client_extensions.rs`](../../apps/ai-game-creator-shell/src-tauri/src/client_extensions.rs) 的 `prepare_enabled_client_skill_root`,app-server 的 Skill root 注册位于 [`codex_app_server.rs`](../../apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server.rs)。
|
||||
|
||||
Skill 配置从下一次 DirectProject 启动生效,当前已经运行的 Codex 会话不热更新。首页的 DirectHome 不作为客户端 Skill 的运行时入口。
|
||||
|
||||
### 2.3 当前可用的触发方式
|
||||
|
||||
Codex 原生显式触发方式是:
|
||||
|
||||
```text
|
||||
$import-smoke-skill 请只回复一行结果。
|
||||
```
|
||||
|
||||
这个方式已经在 AGC 中验证成功,测试 Skill 返回:
|
||||
|
||||
```text
|
||||
SKILL_IMPORT_OK
|
||||
```
|
||||
|
||||
这证明导入、启用、运行时 Skill root 注入、Codex 发现和 Skill 正文执行链路已经打通。
|
||||
|
||||
## 3. 当前缺少的能力
|
||||
|
||||
### 3.1 普通自然语言名称没有确定性绑定
|
||||
|
||||
以下输入目前不能稳定触发导入的 Skill:
|
||||
|
||||
```text
|
||||
请调用 import-smoke-skill skill。
|
||||
```
|
||||
|
||||
```text
|
||||
请明确使用 import-smoke-skill。
|
||||
```
|
||||
|
||||
实际结果是模型报告“当前没有可调用该 Skill 的工具接口”。这句话在“Skill 不是工具”这一点上没有错,但没有完成 Skill 指令的读取和应用。
|
||||
|
||||
### 3.2 AGC 没有发送结构化 Skill 输入项
|
||||
|
||||
Codex 官方 TUI 在识别 `$skill-name` 或用户从 Skill 提及菜单选择后,会向 `turn/start` 输入中追加类似内容:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "skill",
|
||||
"name": "import-smoke-skill",
|
||||
"path": ".../SKILL.md"
|
||||
}
|
||||
```
|
||||
|
||||
对应实现见 Codex 仓库中的 `codex-rs/tui/src/chatwidget/input_submission.rs`。随后 Codex core 会根据结构化输入加载 Skill 正文。
|
||||
|
||||
AGC 当前的 [`codex_app_server_turn_input`](../../apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server.rs) 只把用户消息整理成普通文本和图片输入,没有追加 `type: "skill"` 项。
|
||||
|
||||
### 3.3 “能发现”与“本轮已使用”没有明确的客户端绑定
|
||||
|
||||
AGC 启动时会设置 `skills/extraRoots` 并调用 `skills/list`,这只能证明 Skill 在当前 app-server 进程的发现范围内。它不等于本轮已经选中了某个 Skill,也不等于模型一定会读取该 Skill 的正文。
|
||||
|
||||
Codex 的 Skill 扩展会把可用 Skill 目录和使用规则放入模型上下文,但普通文本相关性判断主要交给模型;它不是 AGC 客户端已经完成的确定性绑定。
|
||||
|
||||
## 4. Codex 源码中的相关分层
|
||||
|
||||
### 4.1 模型侧使用规则
|
||||
|
||||
Codex 仓库中的 `codex-rs/ext/skills/src/catalog_prompt.rs` 会向模型说明:用户用 `$SkillName` 或普通文本点名 Skill,或者任务符合 Skill 描述时,应使用该 Skill。
|
||||
|
||||
这是一条模型行为指令,不是一个保证命中的 `if user_text.contains(...)` 路由器。普通自然语言是否命中,仍取决于模型能否看到对应目录、是否理解名称和描述,以及是否调用 `skills.read`。
|
||||
|
||||
### 4.2 显式 Skill 选择
|
||||
|
||||
Codex 仓库中的 `codex-rs/ext/skills/src/selection.rs` 会处理结构化 `UserInput::Skill`,也会解析文本中的 `$skill-name`。选中后,core 在回合开始阶段读取并注入 Skill 正文。
|
||||
|
||||
### 4.3 “隐式 Skill”不是普通自然语言路由
|
||||
|
||||
源码中的 `implicit invocation` 主要用于命令或脚本访问某个 Skill 的资源目录时记录/识别对应 Skill,入口在 Codex 仓库的 `codex-rs/ext/skills/src/invocation.rs`。它不是一个根据任意用户自然语言自动选择 Skill 的通用分类器。
|
||||
|
||||
### 4.4 相关性选择实验不是当前确定性注入
|
||||
|
||||
Codex 的 `shadow_selection` / `skill_search` 相关实现会对任务和 Skill 描述做词法/相关性排序,但当前是 shadow 观测路径,不直接替当前回合注入 Skill,不能作为 AGC 当前缺口的现成解决方案。
|
||||
|
||||
## 5. 复现步骤
|
||||
|
||||
准备一个普通的 Skill 导入目录,目录中放置一个 `SKILL.md`。例如:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: import-smoke-skill
|
||||
description: 用于验证客户端导入和加载 Skill 的最小测试 Skill。
|
||||
---
|
||||
|
||||
当用户明确要求使用 `import-smoke-skill` 时,先单独输出一行 `SKILL_IMPORT_OK`,再继续回答用户的问题。
|
||||
```
|
||||
|
||||
该目录和文件可以由 Issue 提交者在自己的测试环境中临时创建,不依赖仓库外的固定目录或本机产物。
|
||||
|
||||
复现:
|
||||
|
||||
1. 在客户端“扩展”中导入包含上述 `SKILL.md` 的目录;
|
||||
2. 确认列表显示 `import-smoke-skill`、类型为 Skill、状态为“已启用”;
|
||||
3. 新开一个 DirectProject 会话;
|
||||
4. 依次发送:
|
||||
|
||||
```text
|
||||
请调用 import-smoke-skill skill,如果找不到这个skill,不要伪造结果。
|
||||
```
|
||||
|
||||
```text
|
||||
请明确使用 import-smoke-skill,只回复一行结果。
|
||||
```
|
||||
|
||||
```text
|
||||
$import-smoke-skill 请只回复一行结果。
|
||||
```
|
||||
|
||||
预期现象:前两条不会稳定加载 Skill,第三条返回 `SKILL_IMPORT_OK`。
|
||||
|
||||
## 6. 可能的修复方向
|
||||
|
||||
以下只是供 Issue 讨论的候选方向,不在本文锁定具体实现。
|
||||
|
||||
### 方向 A:客户端显式绑定用户点名的 Skill
|
||||
|
||||
AGC 在发送回合前,根据当前已启用 Skill 列表识别用户明确提到的名称,并把匹配项转换成 Codex 原生的 `type: "skill"` 输入项,同时保留原始用户文本。
|
||||
|
||||
优点是行为确定、与官方 TUI 的协议一致;需要讨论名称边界、重名处理和用户文本中普通单词与 Skill 名称的冲突。
|
||||
|
||||
### 方向 B:增加 Skill 提及选择入口
|
||||
|
||||
在聊天输入框提供 Skill 名称补全或选择入口。用户选择后,客户端保存/发送结构化 Skill 绑定,而不是要求用户手写 `$`。
|
||||
|
||||
优点是用户不需要了解 Codex 协议标记;需要额外的前端交互设计,且要决定是否在 DirectProject 聊天区增加入口。
|
||||
|
||||
### 方向 C:仅支持 Codex 原生 `$skill-name`
|
||||
|
||||
保持当前实现,只把 `$skill-name` 作为 Skill 的正式调用方式,并在测试和使用说明中明确这一点。
|
||||
|
||||
优点是改动最小;缺点是用户需要知道 Codex 的 Skill 提及语法,普通中文“请使用某 Skill”仍不会得到确定性支持。
|
||||
|
||||
### 方向 D:依赖模型根据 Skill 目录自行判断
|
||||
|
||||
让 Skill 目录和描述保持模型可见,由模型在普通任务中自行判断是否需要调用 `skills.read`。
|
||||
|
||||
这种方式可以覆盖“任务适合某 Skill”而不仅是精确名称,但结果受模型判断和上下文影响,不适合作为“用户明确点名后必须使用”的唯一保证。
|
||||
|
||||
## 7. Issue 建议关注点
|
||||
|
||||
提 Issue 时建议先确认产品契约,而不是直接指定实现:
|
||||
|
||||
- “用户普通中文提到已启用 Skill 名称”是否必须确定性生效;
|
||||
- 是否接受用户使用 Codex 原生 `$skill-name`;
|
||||
- 是否需要聊天输入框提供 Skill 选择/补全;
|
||||
- Skill 名称与 MCP Server 名称冲突时,客户端按哪类扩展解析;
|
||||
- 没有找到匹配 Skill 时,是否只给出说明并继续普通对话;
|
||||
- 是否需要在回合记录或状态 UI 中展示本轮实际注入了哪些 Skill。
|
||||
|
||||
本 Issue 不应扩大为:重新设计 Skill/MCP 导入格式、把 Skill 做成 MCP 工具、增加第三方内容安全扫描、增加脚本沙箱,或重做 Codex Plugin Runtime。
|
||||
Reference in New Issue
Block a user