让每个命令都能精准路由:HagiCode Preset Task 的多技能支持实战

OpenSpec 中文简明教程 - 1 基本概念与简单示例 🧠 OpenSpec 是一个轻量级的规范驱动开发框架,帮助人类与 AI 编程助手在写代码前就达成一致,确保开发过程可控、可审查、可追踪。 阅读详情

agiCode 的 preset task 是一套插件化的小工具系统。用户不必手敲命令,只要在可视化面板里填几个字段,点一下,就能创建一个自动任务会话。每个 preset 本质上是一个目录,里面通常长这样:

  • manifest.json:preset 的身份信息
  • panel.json:可视化面板的表单定义
  • commands.json:实际要执行的命令清单
  • task-preset.json 或 prompts.json:任务参数和技能要求

这套东西用起来确实方便,可我们很快就撞上了一个别扭的地方。

早期版本里,skill 只能在 preset 层级的 requirements 数组里声明。什么意思呢?就是同一个 preset 内的所有命令,共享同一份技能要求罢了。听起来好像没啥,可实际用起来是这样的场景:

一个 preset 里有五条命令,其中第一条想走 last30days 这个 skill,第三条想走 ui-master,剩下三条不需要任何 skill。在旧设计下做不到。你想让不同命令路由到不同 skill,就得把这些命令硬拆成好几个 preset,配置一下就膨胀了。

这就是提案 extend-preset-task-multiple-skills-support 想解决的问题:让每条命令独立声明自己依赖的 skill,并且把这种绑定在 UI 上可视化出来。

关于 HagiCode

本文分享的方案,来自我们在 HagiCode 项目里的实践经验。HagiCode 是一个 AI 代码助手项目,preset task 系统正是它面向用户的快捷操作入口。下面讲的每一处改动,都是我们实际踩坑、实际优化出来的——毕竟纸上得来终觉浅。项目源码在 HagiCode-org/site,感兴趣的可以先去点个 Star。

先把问题想清楚:为什么不是一张映射表

动手之前,最容易想到的方案是:再开一张 commandSkillMappings 映射表,把"命令 ID → skill"的关系单独存起来。听起来很干净,职责分离嘛。

可仔细一琢磨就发现不对劲。

commands.json 里每条命令已经有一个 ID,映射表里又得把这个 ID 抄一遍。两份文件、同一个 ID,只要哪天有人改了命令忘了同步映射表,数据就漂移了。这种"为了分离而分离"的设计,后期维护成本远大于它带来的那点整洁感。到头来,只是徒增烦恼而已。

所以我们最终选了一条更直接的路:把可选的 skill 字段直接放到命令定义上。一条命令自己声明自己绑哪个 skill,就近维护,谁也不会跟谁失联。

这个决定背后,还有一条更重要的设计原则,值得单独拎出来说。

核心一:两层数据职责分离

这是整个改造里最关键的一个认知。

很多人第一反应是:既然命令上有了 skill,那做 requirement check(技能门禁检查)的时候,是不是应该去扫每个命令的 skill 字段?

不是。

我们刻意把这件事拆成了两层:

  • commands.json 的 skill 字段:只负责声明绑定。它告诉系统"这条命令要绑哪个 skill",用于渲染 prompt 前导和 UI 展示。
  • task-preset.json 的 requirements 数组:才是权威枚举。它是真正的门禁,决定一个 preset 需要满足哪些技能才能运行。

换句话说,skill 回答的是"绑哪个、渲染什么",requirements 回答的是"到底允不允许跑"。两件事,别混在一起。

这么分的好处,是 check 逻辑天然简单。因为门禁始终基于 preset 层的 requirements,按 CacheKey 去重,多条命令绑同一个 skill 也只会探测一次,不会重复打点。命令级 skill 不引入任何额外的探测开销。

这条原则,也是我们否决映射表方案的根本原因——映射表会让人误以为"绑定即门禁",把两层职责又搅回去了。聪明反被聪明误,不过如此。

核心二:命令定义长什么样

改造后的命令定义,就是在原来的基础上多了一个可选的 skill 字段。以 last30days 这个 bundled preset 为例,它的 commands.json 大致长这样:

 
{
"$schema": "../../schemas/commands.schema.json",
"version": "1.1",
"commands": [
{
"id": "research",
"skill": "last30days",
"prompt": "调研一下最近30天大家对 {topic} 的真实讨论"
},
{
"id": "summarize",
"prompt": "把上面的调研结果整理成一份摘要"
}
]
}

几个要点说明:

  • version 升到了 1.1,对应的 schema 也加了可选 skill 字段。
  • 第一条命令 research 绑了 last30days skill,执行时会路由到这个技能。
  • 第二条命令 summarize 没绑 skill,它只是一条普通指令,走默认路径。
  • 注意这里没有在命令里写任何 requirement。真正的门禁,在 task-preset.json 的 requirements 里:
 
{
"requirements": [
{
"key": "last30days",
"cacheKey": "skill:last30days"
}
]
}

research 命令绑的 last30days 必须出现在这份 requirements 里,否则就出问题了——这正是下一节要讲的硬约束。强扭的瓜不甜。

核心三:加载期的交叉校验

光在数据上声明绑定还不够,得有人兜底,防止"命令绑了一个 skill,可 requirements 里压根没声明"这种孤儿绑定溜到线上。

这个兜底就是 ValidateCommandSkills。它在 preset 包加载的时候跑一遍,逐条检查每个命令的 skill 是否都能在 preset 层的 requirements 里找到对应项。找不到,就判定为非法包,直接禁用整个 preset,并抛出诊断码 command-skill-not-in-requirements。

为什么要禁用整个包,而不是只跳过那条命令?因为 preset 是一个整体,命令之间往往有依赖关系(前一条的输出喂给下一条)。如果悄悄跳过一条,后面的命令拿到空输入,行为就完全不可控了。毕竟人心隔肚皮,代码也隔肚皮。宁可让用户看到明确的报错,也不要让任务在半路上莫名其妙地跑歪。这一点,马虎不得。

这个校验是在加载期完成的,也就是说问题在 preset 注册的那一刻就会被发现,不会拖到用户真正点"运行"才暴雷。对用户体验来说,早报错永远好过晚报错。

核心四:prompt 前导的幂等拼接

接下来,是执行链路上最微妙的一环。

当一条命令绑了 skill,比如 last30days,系统在真正执行前,要把这个 skill 信息"拼"到命令前面,形成一个完整的单行指令交给执行器。这个过程由 CombineCommandSkillPrelude 负责。

举个具体的例子。research 命令的 prompt 是"调研一下最近30天大家对 {topic} 的真实讨论",绑的 skill 是 last30days,那么最终交给执行器的指令大致是:

 
/last30days 调研一下最近30天大家对 {topic} 的真实讨论

也就是在 prompt 前面加了 /last30days 这个前导。执行器看到这个前导,就知道要先把上下文切到 last30days 这个 skill 上。

这里有个容易踩的坑:幂等性。

为什么要强调幂等?因为有些场景下,prompt 本身可能已经带了这个 skill 前导(比如用户手动写了一半,或者从别的地方拷过来的)。如果系统傻乎乎地再拼一次,就会变成 /last30days /last30days 调研...,执行器要么报错要么行为异常。

所以 CombineCommandSkillPrelude 在拼接前会先检测一下,如果前缀已经存在,就不重复加。这一步看似不起眼,可能挡掉一类很隐蔽的 bug。

值得一提的是,这整套前导注入逻辑都在 preset 定义层(PresetTaskCatalogProvider 里的 BuildCommandPrelude)完成,SessionsController 这边的会话创建代码完全不用动。这也是职责分离带来的好处——执行入口保持稳定,技能路由的复杂度被收敛在定义层内部。

核心五:前端怎么把绑定展示出来

后端把数据模型和执行链路都理顺了,最后一步,是让用户在界面上能"看见"这种绑定。毕竟一个功能如果用户感知不到,那约等于没做。

前端这边做了三件事。

第一,命令选择器上加徽标。 在 command-picker 里,每条绑了 skill 的命令旁边会显示一个小徽标,标明它依赖哪个 skill。用户扫一眼就知道哪条命令是"带技能"的,哪条是普通命令。

第二,requirement-check 摘要区块。 面板上有一个专门的摘要区域,列出当前 preset 需要满足的所有 skill 要求,以及每条命令分别绑了哪个。这个区块的数据来源于 commandSkillsByRequirementKey 这个映射——把命令按它绑的 requirement key 分组聚合,方便用户一眼对照"要求"和"实际绑定"是不是对得上。画虎不成反类犬,大概就是这样——所以聚合逻辑要做得直给,别花哨。

第三,失败时的一键安装深链。 如果 requirement check 发现某个 skill 没装,用户不必自己去翻文档找安装入口。界面直接给出一个深链按钮,点一下跳到对应的安装流程。这一步把"发现问题"和"解决问题"之间的距离压到了最短。

前端类型这边也很克制,命令类型只是加了一个 skill?: string,并且做了归一化处理(|| undefined),避免空字符串这种边界值在后续判断里惹麻烦。

实践:五步走完整套改造

把前面零零碎碎的点串起来,整套改造其实就是五步:

  1. 扩展 schema:commands.schema.json 加上可选 skill 字段,版本号升到 1.1。
  2. 解析 + 校验:NormalizeCommands 负责解析命令定义,ValidateCommandSkills 做交叉校验,命令 skill 必须能在 preset 层 requirements 里找到。
  3. 注入前导:BuildCommandPrelude 在执行前把 /skill 前导幂等地拼到命令前,不需要改动 SessionsController。
  4. 迁移 bundled preset:last30days 和 ui-master 这两个内置 preset 的 commands.json 改一下,给相应命令补上 skill 字段。迁移只动 commands.json,不碰其他文件。
  5. 前端可视化:类型补字段、command-picker 加徽标、requirement-check 加摘要区块、失败时给一键安装深链。

几条实践中的注意事项,单独列一下:

  • 一条命令只能绑一个 skill。这是当前的约束。如果一个场景真的需要一条命令触发多个技能,逃生舱是在 preset 层的 requirements 里声明多个 skill,让它们在 preset 级别共存。
  • 校验失败的诊断码是 command-skill-not-in-requirements,排查问题时直接搜这个码。
  • 前端归一化记得 || undefined,别让空串混进判断逻辑。
  • 迁移时只动 commands.json,requirements 那边保持不动,避免引入意外变更。
  • 后端测试覆盖三类场景:命令 skill 在 requirements 里(通过)、不在(禁用包)、多条命令绑同一 skill(去重正常)。

总结

这次 preset task 的多技能支持改造,表面上只是给命令加了个 skill 字段,可它背后牵出的是一个挺值得琢磨的设计问题:绑定和门禁,到底该不该分开?

我们的答案是分开。skill 字段只管"绑哪个、渲染什么",requirements 才管"允不允许跑"。这两层职责一旦搅在一起,无论是用映射表还是别的什么形式,都会让后续的校验、去重、UI 展示变得别扭。分开之后,每层都简单了:门禁永远基于一份权威枚举,绑定就近维护不会漂移,前导拼接幂等可控,UI 只是把已经清晰的数据展示出来。

回头看,整个改造没有用什么花哨的技术,靠的就是把职责切干净,然后把每一层该兜的底兜住。HagiCode 的 preset task 系统经过这一轮打磨,总算能让每条命令都精准路由到它该去的 skill 了。说到底,事情本来就该这么简单……

一分钟了解OpenSpec (规格) OpenSpec是由Fission AI开源的轻量级规范驱动开发(SDD, Spec-Driven Development)CLI工具。它专为AI编程助手(如Cursor、Claude Code)设计,核心是**“先约定,后编码”:在AI写代码前,先通过结构化规范文档达成共识,让开发过程可预测、可审计、可协作**。轻量无侵入:单CLI、无依赖、不改造项目、1分钟接入存量友好:增量Spec、不重构旧文档、1→n王者完全可控:每步审查、AI按图施工、零返工协作利器。 阅读详情

相关推荐

五分钟带你认识并安装使用OpenSpec

随着AI 的野蛮发展,随之孵化出来各种新概念、新技能、新模式也是层出不穷前有vibecoding,后有claude ,前有cursor3 后有小龙虾,前有SKILL 后有dify,前后MCP 后有langgraph/langchain……(名词不分先后)这些新名词让刚刚接触AI 的童鞋们痛苦不已,这都是些啥呀~没关系,了解我的童鞋都知道。

十年老程序猿,AI 疯狂研究专家,前沿硬核知识分享 1403

OpenSpec详解

明确需求:变更前先明确"为什么"和"是什么"可视化提案:所有重要变更都有可审查的提案文档保持同步:规范与代码始终保持一致可追溯性:完整的变更历史和决策记录规范即真相,变更即提案,简单性优先。通过遵循三阶段工作流(创建、实施、归档)和使用 CLI 工具,开发团队可以更系统地管理需求和变更,特别是在与 AI 编码助手协作时。OpenSpec对于需要明确需求管理和变更追踪的项目,它提供了一个实用的框架。

insist211314的博客 1万+

实测避坑:华为Atlas 300I DUO推理卡部署Qwen1.5,性能对比3090与完整配置流程

本文深度评测华为Atlas 300I DUO推理卡在部署Qwen1.5-14B大模型时的性能表现,并与RTX 3090进行对比。通过实测数据展示硬件参数、部署流程及性能优化建议,揭示国产AI加速卡在LLM推理中的独特优势与适用场景,为开发者提供完整的配置指南和避坑方案。

weixin_29083475的博客 799

openspec详解

openspec

lanSeFangZhou的博客 4727

手把手教你用XC7A35T FPGA搭建低成本机器视觉系统(含开发板选型指南)

本文详细介绍了如何利用AMD(原Xilinx)Artix-7系列中的XC7A35T FPGA芯片,搭建一套低成本的机器视觉系统。内容涵盖从芯片选型深度剖析、开发板(如黑金AX7035B)对比指南,到使用Vivado创建工程、编写图像处理模块(如RGB转灰度),以及资源优化和与上位机(如OpenCV)协同工作的完整流程,旨在为开发者提供一套可实践的高性价比硬件加速视觉解决方案。

beta5的博客 353

基于知识图谱的电影推荐系统——Neo4j&Python

也可直接从这里下载:链接: https://pan.baidu.com/s/1l6wjwcUzy5G_dIlVDbCkpw 提取码: pkq6。修改main.py中的driver,输入自己数据库的用户名与密码。系统会询问是否需要重新加载并创建知识图谱,在第一次时输入1。

weixin_46351593的博客 6356

程序员必看让AI编程100%可控!从1到N的开发神器OpenSpec规范驱动开发完整实战指南!支持Cursor、Claude Code、Codex!比SpecKit更强大!三分钟实现iOS项目迭

下面用一个真实案例,带你完整走一遍OpenSpec流程。我有一个名为ForestFocus的iOS应用,是一个专注计时器(类似番茄钟)。用户专注25分钟,就能种一棵树。现在我想添加自定义时长功能:让用户可以选择15分钟、45分钟、90分钟等不同的专注时长,而不是固定的25分钟。AI编码助手很强大,但当需求模糊时,它会变得不可预测。OpenSpec通过引入规范驱动的工作流,确保在写代码前,人和AI就要做什么达成一致。AI正在改变软件开发的方式,但它不是魔法。

m0_71165399的博客 8356

allegro转AD-(附工具)

本文介绍了将Allegro的.brd文件转换为Altium Designer可用的.alg文件的操作流程。首先需要下载专用转换工具,然后通过运行.bat脚本将.brd文件转换为.alg格式。最后在Altium Designer中使用导入向导完成文件转换,生成可用的PCB设计文件。整个过程简单快捷,只需三个步骤即可实现Allegro到Altium Designer的工程文件转换。

weixin_50120208的博客 1717

OpenSpec 功能详解:5 分钟搞懂 AI 编程的“规范驱动“核心

摘要:OpenSpec作为规范驱动开发工具,通过规范注入机制让AI按照项目规范工作。其核心原理是:1) 根据AI工具类型生成特定目录结构;2) 通过关键词触发加载规范文件;3) 采用三阶段工作流(提案-实现-归档)。"时灵时不灵"现象主要源于:触发词缺失、工具支持差异或知识分层不当。最佳实践包括明确使用触发词、合理组织规范文件、必要时手动修改规范。OpenSpec的价值在于让AI从"项目小白"成长为熟悉业务的开发伙伴。(149字)

Dearzh的博客 2806

基于STM32的家用新风系统智能控制器 | 保姆式教程 开源可复刻

本项目基于STM32F103C8T6核心控制器,完整实现了家用新风系统智能控制器的全功能开发,覆盖多传感器数据采集、双模式控制、PID调速、异常报警、掉电记忆等核心功能,全程采用保姆式无跳步教学,从硬件选型、接线、CubeMX配置、代码开发、调试排坑全流程拆解,跟着步骤一步步操作,就能顺利完成项目复刻

ZhongWeiXiang9的博客 467

动手学Moveit2 | 运行配置好的机械臂功能demo

通过这个小demo你可以直观的感受moveit2的强大,但还有很多需要我们探索的,比如机械臂是如何规划的,规划的过程中如何结合环境信息,规划的时候机械臂如何求解,如何和真实的机械臂对接等等,这些都需要你来进一步探索,今天就到这里,明天给大家秀一下小仙女焊的fishbot运控板。

生活不止眼前的苟且 8881

OpenSpec:规范驱动AI编程新范式

OpenSpec是一个轻量级开源规范驱动开发框架,由Fission AI团队设计,旨在解决AI编程中的需求模糊和偏移问题。它采用双文件夹模型(specs/和changes/)实现结构化规范管理,提供5阶段工作流:创建提案、编写规范、AI实施、测试验证和归档更新。通过CLI工具,开发者可以快速初始化项目、创建变更提案并生成符合规范的代码。示例展示了如何使用OpenSpec指导React登录组件开发,从规范编写到AI代码生成再到验证归档的全流程。该框架强调人类开发者主导、AI严格执行的开发模式,提升开发效率和代

ZhangJiqun&191cm&85kg 6639

LIS2DH三轴加速度传感器原理图设计,已量产(加速度传感器)

最近在做一款可穿戴设备原型时,选了 LIS2DH 这款加速度计 —— 比起之前常用的 ADXL345,它在低功耗和稳定性上的优化刚好戳中了可穿戴设备 “续航 + 可靠” 的核心需求。下面结合这次画的原理图,聊聊这个小模块的硬件设计细节。

不脱发的程序猿 389

OpenSpec:终于有工具能管住那些不听话的AI了

OpenSpec是一款专为AI编程助手设计的规范驱动开发工具。简单来说,就是在AI写代码之前,先让它明确知道要做什么、怎么做,避免后面的各种返工和修改。这个工具最大的亮点就是完全免费开源,无需任何API密钥,而且支持市面上几乎所有主流的AI编程工具,包括Claude Code、Cursor、GitHub Copilot、Windsurf等等。OpenSpec这个工具解决的是一个很实际的痛点,而且解决得很优雅。它不是要替代AI编程助手,而是让这些工具变得更好用、更可靠。

王乐平 技术博客 3091

【华为OD机试真题】18、喊7的次数重排 | 机试真题+思路参考+代码解析(C++、Java、Py)

题目描述 >喊7是一个传统的聚会游戏,N个人围成一圈,按顺时针从1到N编号。   编号为1的人从1开始喊数,下一个人喊的数字为上一个人的数字加1,但是当将要喊出来的数字是7的倍数或者数字本身含有7的话,不能把这个数字直接喊出来,而是要喊”过”。   假定玩这个游戏的N个人都没有失误地在正确的时机喊了”过”,当喊到数字K时,可以统计每个人喊”过”的次数。   现给定一个长度为N的数组,存储了打乱顺序的每个人喊”过”的次数,请把它还原成正确的顺序,即数组的第i个元素存储编号i的人喊

KJ.JK 4168

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

OpenSpec 新手入门教程

OpenSpec 新手入门教程 规范驱动的AI编码助手开发方法 目录 什么是OpenSpec? 为什么需要OpenSpec? 准备工作 快速开始 核心概念 完整工作流程 实际示例 支持的AI工具 常用命令 团队采用指南 常见问题 什么是OpenSpec? OpenSpec 是一个为AI编码助手设计的

gujiachun的专栏 4447

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

OpenSpec原理解析与使用详解

OpenSpec是一款AI驱动的规范开发工具,通过结构化流程提升代码质量和效率。其核心采用"规范先行"理念,在编码前明确技术栈、接口定义等需求细节,减少模糊提示导致的返工。工具提供从提案起草到归档的全流程自动化管理,支持版本追溯确保规范与代码同步。结合Claude Code使用时,能基于规范文档生成高质量代码,实现规范驱动的高效开发。适用于规模化项目开发与团队协作,但也需注意规范维护成本和探索性需求的适配。通过Markdown格式的规范文档与命令行工具,OpenSpec在代码生成与验证间

技术人集结地 6876

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

OpenSpec 实战:用规范驱动开发破解 AI 编程协作难题

OpenSpec是一个面向AI编程助手的规范驱动开发框架,通过"规范→执行→验证"的闭环流程提升开发效率。其核心是让AI先撰写结构化规范(包括功能描述、测试用例等),再基于规范生成代码并自动验证。该框架特别适合功能迭代和多人协作场景,能有效解决企业级项目改造和团队协作的难题。 使用流程包括:1)安装OpenSpec CLI工具;2)初始化项目并选择AI工具;3)通过/openspec命令创建提案、执行需求和归档变更。框架会生成规范的目录结构,包含specs(规范文档)和changes(变

长河的博客 3222

OpenSpec详细介绍与使用指南

OpenSpec 是 Fission-AI 开源的轻量级规范驱动开发(SDD)框架,专为 AI 编程助手(Claude Code、Cursor、Copilot 等)设计,核心是“先对齐、再编码”,通过本地文件+结构化提案管理 AI 辅助开发全流程,解决 AI 上下文丢失、需求模糊、变更不可追溯的痛点,且具备轻量无侵入、跨工具兼容、易上手的特点,优先适配现有项目(棕地项目)的增量开发。

2301_77007887的博客 1579
上一篇: 【机器人 / 强化学习】SERL:让真机强化学习从“难用”走向“可复现”的强化学习框架 ---- 算法篇(SAC)
下一篇: Avalonia 制作复杂布局动画
代号隐神5
博客等级 码龄147天 0粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值