cmdc_skill_engine Changelog

Copy Markdown View Source

本项目遵循 Semantic VersioningKeep a Changelog 规范。

[0.3.0] - 2026-05-22

多租户 Skill 数据切片 + :telemetry 事件契约。

向后兼容的 minor 版本(除 Store.Backend behaviour 签名变更外), 集成方零改动可平滑升级;多租户场景显式传 :scope 即可启用硬隔离。

Added

:telemetry 事件契约(CMDCSkillEngine.Telemetry

暴露 4 个标准事件:

  • [:cmdc_skill_engine, :analyzer, :analyze, :start]
  • [:cmdc_skill_engine, :analyzer, :analyze, :stop] — 含 duration_ms / task_completed / suggestion_count / fallback?
  • [:cmdc_skill_engine, :evolution, :emitted] — 含 evolution_type / skill_id / scope / parent_skill_ids
  • [:cmdc_skill_engine, :store, :record_updated] — 含 operation (:save | :counters_incremented)

所有事件 metadata 自动注入 :schema_version(当前 1)。提供 attach_logger/1 用于开发期;生产建议直接 :telemetry.attach_many/4 接入 Langfuse / Datadog / Phoenix Channel 等。

多租户切片(:scope

CMDCSkillEngine.Store 公共 API 全部新增 :scope keyword(默认 "global"):

{:ok, _} = Store.list_active(scope: "tenant_a")
{:ok, _} = Store.get_record(id, scope: "tenant_a")
{:ok, _} = Store.get_records(ids, scope: "tenant_a")
{:ok, _} = Store.get_version_chain(id, scope: "tenant_a")
:ok      = Store.update_counters(id, [selections: 1], scope: "tenant_a")
  • ETS 后端:表 key 形如 {scope, skill_id}list_active(scope:):ets.match_object/2 直接命中目标 scope(基线 p99 ≤ 16µs,100 scope × 100 records / scope 场景,详见 benchmark/scope_lookup.exs
  • SQLite 后端:新增 scope / metadata 列 + 复合索引 (scope, skill_id)list_active(scope:) 在 100 scope × 100 records 数据上 p99 ≤ 1 ms(远低于 5 ms 契约)
  • 跨 scope 查询返回 :not_found —— 强制租户隔离

CMDCSkillEngine.Types.SkillRecord 新增字段:

  • :scope :: String.t(),默认 "global" —— 数据切片维度
  • :metadata :: map(),默认 %{} —— 集成方自由扩展字段(建议 "<namespace>.<field>" 命名空间约定)

CMDCSkillEngine.Analyzer / SkillRanker / SkillRanker.Semantic 自动 从 ctx.user_data.user_id(或 ctx.scope)提取 scope,与 cmdc_memory_pg EpisodicMemoryBackend 的租户切片维度对齐。

CMDCSkillEngine.register_skill/2 新增 :scope / :metadata 选项:

CMDCSkillEngine.register_skill(skill, scope: tenant_id, metadata: %{"studio.created_by" => "..."})

SQLite idempotent migration

升级 v0.2 → v0.3 老 .db 时,启动通过 PRAGMA table_info 探测缺失列, 自动 ALTER TABLEscope / metadata 列;新建 .db 走 CREATE TABLE 全字段,零副作用。老数据自动归入 scope = "global"

Benchmark

  • benchmark/scope_lookup.exs — ETS / SQLite 多 scope 切片读 / list 基线 脚本,详见 benchmark/README.md 实测表

Changed (Breaking — Backend behaviour)

  • CMDCSkillEngine.Store.Backend callback 签名加 scope 参数(hard break vs v0.2.x):

    • get_record(state, scope, skill_id)(从 get_record(state, skill_id)
    • list_all(state, scope)(从 list_all(state)
    • update_counters(state, scope, skill_id, increments)(从 update_counters(state, skill_id, increments)
    • save_record(state, record) — 签名不变(scope 由 record.scope 字段 携带)
    • reset/1 / init/1 / terminate/1 — 签名不变

    内置 ETS + SQLite 后端已迁移;第三方 backend 实现需要按新签名适配。

  • CMDCSkillEngine.Store 公共 API 全部加 :scope keyword(默认 "global"), 调用方零改动可平滑升级。

  • CMDCSkillEngine.Analyzer.handle_event(:session_end, ...) 自动透传 scope 到 process_analysis/2Store.get_record(scope: ...) 调用链。

  • CMDCSkillEngine.Evolver.evolve/2 新建 SkillRecord 时自动从 context[:scope] 继承 scope;lookup_parent/2 限定同 scope 查找。

Migration

  • 老调用方零改动:所有 Store API 默认 scope = "global",行为完全等价 v0.2.x
  • 老 .db 文件:首次启动自动 idempotent migration,归入 scope = "global"
  • 第三方 Backend 实现者:按 CMDCSkillEngine.Store.Backend 新 callback 签名 调整即可(参考 CMDCSkillEngine.Store.Backend.ETS / Backend.SQLite

Notes

  • 跨 scope 聚合查询(list_all_scopes/0scope: :all 特殊值)暂不支持, 留 v0.4+ 按集成方实际需求评估
  • metadata 字段命名空间约定(如 "studio.tenant_name")当前不强制校验, 留首次冲突时收紧

[0.2.2] - 2026-05-18

Patch release — repository URL normalization + documentation cleanup. No code changes, no behavior changes.

  • Repository URL → https://github.com/tupleyun/cmdc_skill_engine
  • Module moduledoc rewritten to neutral technical description
  • CHANGELOG sections rewritten to neutral technical descriptions

[0.2.1] - 2026-05-16

Compatibility patch — 让 cmdc_skill_engine 与 cmdc 0.4 主线生态 对齐,并补 benchmark 工具链(v0.2.0 后 commit 但未发布)。

Changed — cmdc 依赖范围升级

  • {:cmdc, "~> 0.2"}{:cmdc, "~> 0.4"}
    • 背景~> 0.2 严格语义 >= 0.2.0 and < 0.3.0 阻塞与 cmdc 0.3/0.4 共存。用户同时引入 cmdc 0.4 + cmdc_skill_engine 0.2 会 触发 Hex 版本冲突
    • 兼容性核实:本库依赖的 cmdc 抽象(CMDC.Plugin behaviour + CMDC.SystemPrompt Skills 注入接口)都在 v0.1 起稳定,且 v0.2-v0.4 无 breaking change(除 v0.3 #B21 facade tuple,本库不调 facade)
    • 无运行时行为变更

Added — Benchmark 工具链

  • 新增 benchmark/quality_update.exs — 100 skills × 10 轮 quality_update 传播 Benchee suite(Store + QualityTracker 热路径性能基线)
  • benchmark/README.md — benchmark 运行指引
  • :benchee, ~> 1.3 加入 dev / test 依赖

Migration

  • 老用户仍用 cmdc 0.2 → 锁 {:cmdc_skill_engine, "0.2.0"} 即可
  • 想用 cmdc 0.4 → 升级到 {:cmdc_skill_engine, "~> 0.2.1"}

[0.2.0] - 2026-04-25

真实自进化闭环 —— Agent learning & adaptation:质量追踪 + 自动停用 + FIX/DERIVED/CAPTURED 三动作进化。

Added

  • CMDCSkillEngine.Store.Backend behaviour — 存储后端抽象层,定义 init/1 / get_record/2 / save_record/2 / list_all/1 / update_counters/3 / reset/1 / terminate/1 契约。
  • CMDCSkillEngine.Store.Backend.ETS — v0.1 的默认后端,单节点开发/测试首选。
  • CMDCSkillEngine.Store.Backend.SQLite — 基于 exqlite 的持久化后端,自动 创建 schema + 索引,支持 JSON 字段序列化(lineage / recent_analyses / tags)。
  • CMDCSkillEngine.Analyzer.LLM — ReqLLM generate_object/4 驱动的结构化 分析器;强制输出 task_completed / execution_note / tool_issues / skill_judgments / evolution_suggestions;自带超时控制与 :generate_fn 注入钩子便于离线测试。
  • CMDCSkillEngine.SkillRanker.Semantic — 新的 Selector 实现,结合 BM25 关键词相关性、effective_rate 质量反馈与可选 ReqLLM.embed/3 语义向量 相似度(:embedding_model 未配置时自动退化为 BM25 + 质量加权)。
  • CMDCSkillEngine.QualityTracker.should_deactivate?/2 + update_from_analysis/3 — 新增自动停用规则:达到 min_samples 后,若 applied_rate < applied_mineffective_rate < effective_mintrend != :improving,自动把 is_active = false
  • CMDCSkillEngine.Evolver fix 链长度上限(默认 5);超过时返回 {:error, {:fix_chain_too_long, generation, max_depth}},防止进化链 失控膨胀。
  • example/skill_evolution_demo.exs — 10 轮会话的完整自进化演示,无 LLM 依赖,可 mix run 复现。
  • test/cmdc_skill_engine/stress_test.exs — 1000 轮收敛压力测试,验证 QualityTracker 能在合理轮次内识别并停用低质量 Skill。

Changed

  • CMDCSkillEngine.Store 重构为委托结构:GenServer state 保存 {backend_module, backend_state},所有 CRUD 操作通过 Backend 契约转发; 公共 API 完全向后兼容。
  • CMDCSkillEngine.Analyzer 集成 LLM 路径:当 analysis_model 是 LLM spec(非 nil / "builtin" / "manual" / "rule" / "")时,:session_end 走 LLM 分析;任何失败(超时 / HTTP / schema / 异常)自动降级到规则分析, 不打断 Agent 正常结束流程。
  • CMDCSkillEngine.Analyzer state 新增 :messages 字段,累积 :before_prompt / :after_response 消息,作为 LLM 分析上下文。
  • CMDCSkillEngine.QualityTracker.update_from_analysis/2 改为三元参数版本 update_from_analysis/3(第三参数可选 keyword()),保持对现有调用方 向后兼容。
  • Application.start/2 支持 :start_store 配置开关,测试环境默认关闭 自动启动以避免与 ExUnit 测试隔离冲突。

Fixed

  • Store GenServer 初始化时默认启动逻辑与测试隔离机制冲突,导致多个测试 互相竞争同一 ETS 表 —— 现通过 start_store: false(test 环境)+ test_helper.exs 里的单次 start_link + Process.unlink/1 修复。

Deps

  • 新增 {:exqlite, "~> 0.27"}{:jason, "~> 1.4"}(SQLite backend
    • JSON 序列化)

测试覆盖

  • 105 个测试全部通过(3 个 @moduletag :stress 压力测试默认排除)
  • Store Backend 契约共 32 个测试(ETS × 16 + SQLite × 16)
  • Analyzer.LLM 10 个单元测试(全部通过 :generate_fn stub,无真实 LLM)
  • Analyzer 集成 15 个测试(LLM 命中 + 失败降级 + 规则关键字保护)
  • SkillRanker.Semantic 9 个测试(BM25 / 质量回退 / embedding 注入)
  • QualityTracker 15 个测试(计数器 + trend + deactivation 门控)
  • Evolver 10 个测试(FIX / DERIVED / CAPTURED + fix chain 上限)

[0.1.0] - 2026-04-23

Added

  • 初始版本:ETS Store、规则 Analyzer、QualityTracker、Evolver (FIX/DERIVED/CAPTURED)、SkillRanker(按 effective_rate 排序)。
  • 完整数据模型:SkillRecord / SkillLineage / ExecutionAnalysis / SkillJudgment / EvolutionSuggestion。