Files
efi-kernel/设计/05-技能规范.md
lou 2155f65c76 加"技能执行"示例驱动: 把 skill 真跑一遍 (选模型 / 拼 prompt / 校验输出 / 重试)
- 驱动/技能执行/: oneshot + system 解释器. 读自带 技能/*.json -> 按 tier 选模型 ->
  拼 prompt -> 调 OpenAI 兼容端点 -> 剥 JSON -> 逐条按档校验 -> 落盘 + 写 events
  main 档只锁外层 (plan 是数组 + 每步有 want); small 档锁死 (单值 want + 必须在契约
  清单里 + args 键白名单 + confidence 只许 0/0.5/1)
- 契约清单只读 PG 的 drivers 表拿 (不 import 别的驱动、不翻别人的文件夹);
  也支持 EFI_SKILL_CONTRACTS 显式给一份 (手工跑 / PG 不在时)
- 思考型模型把 max_tokens 吃光时, 把预算翻倍重试一次; 本机端点强制不走代理
- 驱动/Json解码: 补 provides ["Json解码:解析"] -- skill 样例里一直在用这个契约名, 之前没人提供
- 文档同步: README / 文档 02 / 文档 06 / 文档 10 (坑 27~30) / 设计 01 / 设计 05 (补记执行侧)
- .gitignore: 盖住 驱动/*/输出/ (运行时产物不进 git)
2026-09-17 12:39:10 +08:00

6.7 KiB
Raw Permalink Blame History

05 · 技能(Skill)规范 —— skill 归驱动管

老板 2026-09-16 的口径:"skill 是归驱动管的,所以只要样例就行,分主模型和小模型 skill"。 本文只定"放哪、长什么样、两档差在哪"谁执行、怎么调模型,留到 v0.2,本版一个样例都不执行。 分层依据见 01-驱动规范.md 第 7 节(引导器 → 内核 → 驱动 → 程序(Skill))。

1. 归谁管(先把边界说死)

管什么
内核 不知道 skill 的存在。内核管的是"确定性代码能力的接入与仲裁"(扫描/契约/启停/调用),skill 不在它的视野里
驱动 持有并解释自己的 skill:从哪读、给哪个模型、prompt 怎么拼、输出怎么校验、失败怎么重试,全是驱动自己实现
目录 驱动/<驱动名>/技能/*.json —— 一个 skill 一个文件,文件名不参与语义(name 字段才是名字)

为什么不让内核管:skill 天生带着"模型"这个概念(分档、prompt、温度、上下文…),一旦内核掺和, 内核就从"确定性调度器"变成"模型编排器",后面每换一个模型都要动内核。换模型只该动驱动和 skill 文件。

2. 声明字段(JSON,键用英文;值用中文)

字段 类型 必填 说明
efi int 声明版本,现在是 1(跟 配置.efi.json 同一套版本号习惯)
name str skill 名(人看、日志里打);建议和文件名一致,不一致以本字段为准
version str 这份 skill 自己的版本
tier str 模型档main(主模型)/ small(小模型)
description str 一句话:这份 skill 干什么
when [str] 触发条件;也要写"什么情况别用"(在 boundaries 里兜)
input obj {"说明": str, "schema": obj} —— 输入长什么样(谁提供也要写清)
steps [str] 执行步骤;两档写法差别最大的字段(见第 3 节)
output obj {"format": "json", "schema": obj, "说明": str}
examples [obj] few-shot[{"输入": …, "输出": …}]
boundaries [str] 边界与错误处理:画红线的那几条(不许编、不许猜、信息不足回问)
notes [str] 注意事项:给谁跑、坑在哪、为什么这么写

3. 两档差在哪(同一件事写两份)

main(主模型档) small(小模型档)
步骤 抽象:3 条左右,"读懂 → 挑 → 填",把规划权交给模型 写死:编号 5 条,每步只做一件事 + 一个判据("别的都别看")
输出结构 只锁外层plan 是数组、每步必须有 want;参数细节不预设 全锁死:单值 want(不是数组)、args 键白名单、confidence 只许 0 / 0.5 / 1
few-shot 1 条(示范格式) 2~3 条,必须含反例(信息不足 → 回问;多步请求 → 只做第一步)
兜底 允许用自己的常识补全参数 一律"与原话字面比对":原话里没有的值填 null,不许举例、不许编路径
执行权 允许多步(plan 是数组),要长上下文 一次只做一步
给谁跑 云端强模型 / 本地 27B+ 本地 4B~9B
换模型 不用改文件 不用改文件

一句话:main 靠模型聪明,small 靠结构稳。 这就是老板那句"结构稳不赖模型智商,深度靠换模型"的落法。

4. 样例在哪、怎么验

位置 内容
驱动/样板技能/配置.efi.json 声明这个驱动是 oneshotinterpreter: system、无契约
驱动/样板技能/技能.py 只列不执行:把自带的 skill 读出来打印(档次 / 步骤数 / 样例数 / 边界数)
驱动/样板技能/技能/请求解析-主模型.json main 档样例(任务:把一句话解析成 callswant + args,允许多步计划)
驱动/样板技能/技能/请求解析-小模型.json small 档样例(同一任务,锁死结构 + 3 条样例含 2 条反例)
驱动/技能执行/配置.efi.json + 执行.py 示例驱动(真的会跑):读 技能/ 下这一档的 skill → 按 tier 选模型 → 拼 prompt → 调 OpenAI 兼容端点 → 剥 JSON → 逐条按档校验 → 落盘 + 写 events。它把上面那三档"归驱动实现"的事做了一遍,写新驱动可以照抄
驱动/技能执行/技能/*.json 样板技能 同两份(驱动文件夹自包含:拷走整个文件夹就能跑,这也正是"驱动之间零耦合"的用法)
./.venv/bin/python 内核/内核.py 启动 样板技能    # 跑一遍
./.venv/bin/python 内核/内核.py 日志 样板技能    # 看它列出来的清单

选择"请求解析"当样例任务的原因:它正好是这个底座里主模型与小模型真实的分工 —— 主模型负责"该调谁、要不要多步",小模型负责"把一句话填进 want + args 这个固定结构"。 skill 自己不碰 PG、不发 calls(那是驱动的事),它只是声明。

5. 版本边界(内核侧 v0.1 明确不做;驱动侧 2026-09-17 起有参考实现)

不做 为什么 / 谁做
加载器 / 注册表 / 内核侧索引 内核不管 skill;驱动自己在启动时读自己目录下的 技能/
选模型、拼 prompt、温度、上下文配额 驱动实现(各驱动用的模型可能完全不同)
输出校验、重试、降级、记账 驱动实现;要留痕就写 events 表(kind 自己定,见 文档/08
skill 之间互相调用 / 组合 不需要:要串就由驱动编排,或让主模型在 plan 里排多步
权限、配额、沙箱 跟驱动同等待遇,v0.2 再说

补记(2026-09-17:上表第 1~3 条原来只写到"归驱动实现",现在 驱动/技能执行/ 已经把这 三件事真做了一遍(读 技能/ 下的文件 / 按 tier 选模型 / 拼 prompt / 逐条校验输出结构 / 思考型模型把 max_tokens 吃光时把预算翻倍重试一次 / 结果落盘 + 写 events)。 它是"示例驱动",不是规范的一部分 —— 内核侧依旧一行都不碰 skill,规矩没变,只是多了个能抄的东西。

改动这份规范时的连带清单驱动/样板技能/技能/*.json驱动/技能执行/技能/*.json(两份样例要一起改)→ 文档/02-写一个驱动.md"驱动可以带 skill"那节)→ 文档/06-架构与不变量.md(分层表里 Skill 那行)→ README.md(三层结构表)→ 技能 kernel-driver-framework