- 驱动/技能执行/: 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)
6.7 KiB
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 |
声明这个驱动是 oneshot、interpreter: system、无契约 |
驱动/样板技能/技能.py |
只列不执行:把自带的 skill 读出来打印(档次 / 步骤数 / 样例数 / 边界数) |
驱动/样板技能/技能/请求解析-主模型.json |
main 档样例(任务:把一句话解析成 calls 的 want + 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。