为什么要做技能系统
AI 代码编辑器发展到今天,一个绕不开的问题是:如何让 AI 的能力可定制、可扩展、可复用?
大多数编辑器的 AI 能力是固定的——对接几个大模型,内置一些预设的 System Prompt,用户能做的选择有限。如果你想针对自己的项目定制一套 AI 工作流(比如自动按规范审查代码、一键生成 API 文档、智能定位 Bug),要么改源码,要么只能手动拼凑 Prompt。
IfAI v0.4.2 的核心工作,就是给出一个系统性的答案:技能系统(Skill System) 。
技能市场:从概念到可用
本期最大的工程量花在了技能系统的 UI 重构上,经过 7 个 Phase 的迭代,终于达到了可用的状态。
架构设计
技能的本质是一份结构化的 YAML/Markdown 文件,包含 id、name、description、system_prompt、tags、version 等元数据。后端由 Rust 解析和加载,前端 React 负责展示和交互。
.ifai/skills/
├── bug-hunter/
│ └── skill.md # Markdown + YAML frontmatter
├── code-review/
│ └── skill.json # JSON 格式
└── pivo-implement/
└── skill.json
技能格式兼容 Claude Code 的 SKILL.md 标准,这意味着你在 Claude Code 生态中创建的技能,理论上可以直接迁移过来。
UI 层的 Phase 7 重构
这期把技能面板从侧边栏的一个小面板,重构为全屏布局,类似 IDE 中的设置页面或插件市场:
- 左侧列表(288px) :展示所有技能,支持网格和列表两种视图切换
- 右侧详情面板(flex-1) :展示选中技能的完整信息
- 搜索与筛选:技能市场支持关键词搜索 + 分类标签过滤(精选/开发/测试/文档/PIVO);已安装技能支持按状态过滤(全部/已激活/已安装/未激活)
- 批量操作:复选框多选后可以批量激活/取消
- 技能编辑器:支持创建、编辑、查看、预览四种模式,带表单校验
这个重构不是简单的 UI 调整——背后涉及 zustand store 的 selector 模式适配(27 个测试用例全部重写)、虚拟列表的缓存策略、以及技能状态在 store 和 UI 之间的同步逻辑。
技能的生命周期
一个技能从安装到生效,经历以下流程:
- 发现:通过技能市场浏览或搜索
- 安装:下载到项目的
.ifai/skills/目录 - 激活:启用后,AI 对话时会自动加载对应的 system_prompt
- 执行:用户发送消息时,激活的技能 Prompt 会作为上下文注入
- 卸载:带确认弹窗,移除本地文件
流式输出性能:一个容易被忽视的工程问题
SSE(Server-Sent Events)流式输出是 AI 编辑器的核心交互方式,但在长文本生成场景下,性能问题会以不易察觉的方式累积。
问题的本质
v0.4.2 之前,每次 SSE 事件到达都会触发一次独立的解析和 UI 更新。对于一个 3000 token 的回复,可能触发数百次 setState,每次都伴随日志 I/O。实测发现,日志写入占了 CPU 时间的约 15% 。
这不是算法问题,是工程层面的资源竞争。
BatchEventStream 的解决思路
引入了事件队列机制:SSE 事件先入队,然后以 batch 为单位批量解析和处理,减少单次回调的频率。同时:
- Rust 后端的 DeepSeek Frame 日志从每 10 帧输出降至仅前 3 帧
- Tool call delta / TextDelta 日志完全移除
- 前端 WorkflowInlineMonitor 的高频日志全量清理
- 使用
requestAnimationFrame节流 UI 更新
效果:日志 I/O 从 ~15% 降至 <1% ,长文本生成场景的流畅度有可感知的改善。
工具调用竞态:一个典型的前后端同步问题
这期修了一个比较隐蔽的 Bug:后端已经发送了 tool_call 事件,但前端收到 finish 事件时,toolCallsCount 仍然是 0,导致审批组件不显示。
根因是:finish 事件到达时,buffer 中的数据还没来得及同步到 store。修复方案很简单——在处理 finish 事件前强制同步一次 buffer:
// finish 事件处理前强制同步 buffer
self.sync_buffer();
这种竞态问题在异步流式系统中很常见,难的不是修复,而是定位。类似的还有流式输出时多个 text segment 同时显示"生成中..."脉冲动画的问题——实际上只需要让最后一个 segment 传递 isStreaming=true 即可。
E2E 测试框架 v2.0:用元编程对抗测试膨胀
随着功能增长,E2E 测试的维护成本急剧上升。v0.4.2 引入了一套元编程驱动的测试框架:
// 声明式场景定义
const scenario = new ScenarioBuilder()
.withHistory(10000, 'realistic') // 10000 条历史消息
.withStreaming('continuous', 'fast', 50) // 持续快速流式输出
.build();
框架自动采集渲染时间、滚动 FPS、内存变化等指标。基于这套框架,完成了 10000 条消息的压测和 200 条长历史 + 真实 AI 流式响应的性能基线测试。
测试指标
| 维度 | 数据 |
|---|---|
| Vitest | 132 passed, 0 failed, 15 skipped |
| E2E | 409+ passed, 0 failed, 243 skipped |
| Bug 修复 | 10 项 |
| 性能优化 | 4 项 |
| Git 提交 | 50+ commits |
写在最后
IfAI v0.4.2 的核心叙事是技能系统的产品化——从一个技术原型迭代到具备搜索、筛选、批量操作、编辑器等完整功能的可用系统。这背后是 7 个 Phase 的持续重构和 27 个测试用例的覆盖保障。
流式性能优化和工具调用竞态修复则代表了另一类工程工作:在用户无感知的地方持续打磨,让基础体验更加稳定。
下个版本(v0.4.3)会重点推进远程技能市场和流式输出架构重构,后者计划将 1230 行的流式处理代码压缩到 300 行以内。
IfAI 是一个基于 Tauri 2.0 + React 19 构建的开源 AI 代码编辑器,GitHub 地址:github.com/peterfei/if…