首页
/ ECC Continuous Learning v2.1:基于 Instinct 与项目作用域隔离的 Agent 持续学习系统

ECC Continuous Learning v2.1:基于 Instinct 与项目作用域隔离的 Agent 持续学习系统

2026-09-08 19:01:08作者:郁楠烈Hubert

导读

Continuous Learning v2.1 是 ECC(Agent Harness Performance Optimization System)中负责「把 Claude Code 会话自动沉淀为可复用知识」的学习模块。它以 hooks 捕获每次工具调用,把用户习惯抽象成带置信度打分的原子化 instinct(本能),再通过 /evolve 聚类为完整的 skill、command 或 agent。v2.1 引入 project-scoped(项目级作用域) 存储,让 React 项目的约定只留在 React 项目里、Python 项目只留在 Python 项目里,而“总是校验输入”这类通用经验才全局共享,从根本上杜绝了跨项目知识污染。读完本文你将掌握:instinct 数据模型与置信度机制、项目检测与数据目录定位规则、hooks 观察链路与后台 observer 的完整配置、六个 instincts 命令与 instinct-cli.py 的用法,以及项目级 → 全局的 promote 提升流程。

一、从 v1 到 v2.1:为什么需要“原子 instinct + 项目隔离”

该技能模块以 skills/continuous-learning-v2/SKILL.md 为规范文档,仓库中同时维护了多语言译本,本主题的西班牙语版位于 docs/es/skills/continuous-learning-v2/SKILL.md。它当前标识为 version: 2.1.0origin: ECC,核心职责见其 frontmatter 描述:通过 hooks 观察会话、创建带置信度打分的原子 instinct,并将它们演化成 skills/commands/agents。

v2 对比 v1:从“概率观察”到“确定性观察”

特性 v1 v2
观察方式 Stop hook(会话结束时) PreToolUse/PostToolUse(100% 可靠)
分析载体 主上下文 后台 Agent(背景进程)
粒度 完整 skills 原子化 “instincts”
置信度 0.3–0.9 加权
演化路径 直接生成 skill Instinct → 聚类 → skill/command/agent
共享能力 导出 / 导入 instincts

v1 依赖 skill 做观察,而 skill 触发是概率性的,按文档原话“只有约 50–80% 的时间会触发”。v2 改为 hooks 之后,每一次工具调用都被确定性捕获,不再依赖模型判断,学习才具备完整性。

v2.1 对比 v2:引入项目作用域

特性 v2.0 v2.1
存储位置 全局(~/.claude/homunculus/ 项目级 ${XDG_DATA_HOME:-~/.local/share}/ecc-homunculus/projects/<hash>/
作用域 所有 instinct 到处生效 项目级 + 全局
项目检测 git remote URL / 仓库路径
提升(Promotion) N/A 项目 → 全局(在 2+ 个项目中出现时)
命令数量 4(status/evolve/export/import) 6(新增 promote/projects)
跨项目 存在污染风险 默认隔离

在 v2.1 之前,所有学到的模式会混在一起应用到你打开的所有仓库里,一个项目里的特例可能污染另一个项目的编码决策;v2.1 用「项目哈希目录 + 全局目录」把二者分开,并提供了 /promote 这条人工/自动的跨作用域晋升通道。

二、Instinct 数据模型:一个触发点 + 一条动作

An instinct 是一个“已被学习到的小行为”,典型 YAML 如下(来自 skills/continuous-learning-v2/SKILL.mddocs/es/skills/continuous-learning-v2/SKILL.md):

---
id: prefer-functional-style
trigger: "when writing new functions"
confidence: 0.7
domain: "code-style"
source: "session-observation"
scope: project
project_id: "a1b2c3d4e5f6"
project_name: "my-react-app"
---

# Prefer Functional Style

## Action
Use functional patterns over classes when appropriate.

## Evidence
- Observed 5 instances of functional pattern preference
- User corrected class-based approach to functional on 2025-01-15

instinct 的五个核心属性:

  • 原子性(Atomic)——一个触发条件,一条动作,保证可以被单独评估和组合;
  • 置信度加权(Confidence-weighted)——0.3 表示试探性,0.9 表示近乎确定;
  • 领域标签(Domain-tagged)——code-styletestinggitdebuggingworkflow 等,便于过滤和聚类;
  • 证据支撑(Evidence-backed)——记录了是由哪些观察创建的(如上例的 5 次功能式偏好观察与一次用户纠正);
  • 作用域感知(Scope-aware)——project(默认)或 global,这是 v2.1 的身份标识。

可以看到 YAML frontmatter 里带有 project_id/project_name,这意味着同样的模式在不同项目里会有独立的物理副本,各自累积各自的置信度。

三、工作原理:会话 → 观察 → 模式检测 → 演化

整条流水线在技能文档中以 ASCII 图给出,核心路径如下:

Session Activity(git 仓库中)
      │
      │ hooks 捕获 prompts + 工具使用(100% 可靠)
      │ + 检测项目上下文(git remote / 仓库路径)
      v
projects/<project-hash>/observations.jsonl
      (prompts、工具调用、结果、项目归属)
      │
      │ observer agent 后台读取分析
      v
模式检测:
  * 用户纠正 → instinct
  * 错误解决方式 → instinct
  * 重复工作流 → instinct
  * 作用域决策:project 还是 global?
      │
      │ 创建 / 更新
      v
projects/<project-hash>/instincts/personal/     ← 项目级
  * prefer-functional.yaml (0.7) [project]
  * use-react-hooks.yaml (0.9) [project]
instincts/personal/                            ← 全局
  * always-validate-input.yaml (0.85) [global]
  * grep-before-edit.yaml (0.6) [global]
      │
      │ /evolve 聚类 + /promote 提升
      v
projects/<hash>/evolved/ 与 evolved/(全局)
  * commands/new-feature.md
  * skills/testing-workflow.md
  * agents/refactor-specialist.md

观察钩子的底层实现(observe.sh)

hook 入口是 hooks/observe.sh,它属于本仓库 skill 目录,注册在插件 hooks/hooks.json 中。它做了几件在文档里看不到、但值得知道的工程细节:

  1. 从 stdin 读取 Claude Code 传入的 hook JSON,通过 HOOK_PHASE(来自命令行参数或 CLAUDE_HOOK_EVENT_NAME 环境变量)区分 pre/post,分别记录为 tool_starttool_complete
  2. 从 JSON 中提取 cwd 并执行 git rev-parse --show-toplevel,把嵌套子目录解析到仓库根,保证观察落到正确的项目上;
  3. 截断大输入输出(输入/输出各保留 5000 字符),避免 observations.jsonl 无限膨胀;
  4. 做密钥脱敏(secret scrubbing):用固定集合的 auth scheme(api_key/token/secret/password/authorization 等)+ 有界量词的正则把疑似密钥替换为 [REDACTED] 后再落盘——注释明确说明这是为了避免灾难性回溯导致 Python 进程 100% CPU(对应 issue #2278);
  5. 超时自我保护:解析与写入都设置了 8 秒 SIGALRM,确保在 hook 的 10 秒异步超时前自行退出,避免孤儿进程(issue #2300);
  6. 观测文件轮转归档:超过 10MB 时原子化 mvobservations.archive/,并且每会话自动清理 30 天以上的 observations-*.jsonl

多层自动化会话防护

为了避免“ECC 观察自己的 Haiku observer”这类自循环,observe.sh 在项目检测之前设置 5 层防护闸门:入口类型(CLAUDE_CODE_ENTRYPOINT,仅放行 cli/sdk-ts/claude-desktop/claude-vscode)、ECC_HOOK_PROFILE=minimal 时跳过、ECC_SKIP_OBSERVE=1 主动跳过、检测到 agent_id 时跳过、以及默认排除路径 observer-sessions,.claude-mem(可用 ECC_OBSERVE_SKIP_PATHS 覆盖)。这些闸门必须在 source detect-project.sh 之前返回,否则自动化会话会创建项目级元数据。

懒启动与信号节流

config.jsonobserver.enabled=true 时,observe.sh 并不等待定时器,而是在工具调用时用 flock(macOS 回退到 lockfile 或原子 mkdir)做“检查-启动”的原子操作,由 agents/start-observer.sh 拉起后台 observer。为了不每次都打断 observer,SIGUSR1 唤醒信号默认每 ECC_OBSERVER_SIGNAL_EVERY_N=20 条观察才发送一次(issue #521 针对每秒钟多次工具调用导致的并行分析风暴),并发读改写之间还加了锁防竞态(issue #2296)。

四、项目检测:同一仓库在不同机器上是同一项目

系统按优先级自动探测当前项目,完整逻辑见 scripts/detect-project.sh

  1. CLAUDE_PROJECT_DIR 环境变量(最高优先)——显式覆盖;即使该目录不是 git 仓库,也会按其绝对路径哈希生成项目身份;
  2. git remote get-url origin——哈希后生成可移植的项目 ID,同一仓库在不同机器上得到同一 ID;
  3. git rev-parse --show-toplevel——基于仓库路径的备选方案(机器相关);
  4. 全局回退——检测不到项目时,instinct 落入全局作用域。

每个项目得到一个 12 字符哈希 ID(如 a1b2c3d4e5f6)。哈希实现在 _clv2_detect_project 内:对 remote URL 做去凭证、去 git@ 前缀、去 .git 后缀的归一化后取 sha256(...).hexdigest()[:12];无 remote 时还尝试用 git worktree list --porcelain 找到主工作树根再哈希,保证 worktree 与主仓库归入同一项目。由于跨 shell 的哈希一致性很重要,注释明确说明:通过 Python 以 UTF-8 编码计算,避免 CP932/CP1252 等非 UTF-8 locale 对同一非 ASCII 路径算出不同 ID。

检测完成后,Python 会原子写两份 JSON 元数据:注册表 ${XDG_DATA_HOME:-~/.local/share}/ecc-homunculus/projects.json(映射 ID → name/root/remote/last_seen)以及每个项目目录内的 project.json 镜像。此外 detect-project.sh 还导出一组 _CLV2_PROJECT_* 变量及无前缀别名 PROJECT_ID/PROJECT_NAME/PROJECT_ROOT/PROJECT_DIR 供 observe.sh 使用。

五、数据目录解析规则与 v1 迁移

Continuous-learning-v2 刻意把 observer 数据放在 ~/.claude 之外,原因是 Claude Code 的敏感路径守卫会拦截在 ~/.claude 下的后台写入。目录解析逻辑集中在 scripts/lib/homunculus-dir.sh

  1. CLV2_HOMUNCULUS_DIR(必须为绝对路径,否则忽略并告警);
  2. $XDG_DATA_HOME/ecc-homunculus(要求 XDG_DATA_HOME 为绝对路径);
  3. 兜底 $HOME/.local/share/ecc-homunculus

Python 侧 scripts/instinct-cli.py 里的 _resolve_homunculus_dir() 实现了完全一致的优先级。

老用户若历史数据在 ~/.claude/homunculus,可一次性执行迁移脚本:

bash skills/continuous-learning-v2/scripts/migrate-homunculus.sh

该脚本 scripts/migrate-homunculus.sh 会先通过 pgrep -f 检查 observer-loop.sh 是否仍在运行(路径先做正则转义),运行中则拒绝迁移;源目相同或源不存在则直接退出;目标已存在且有内容时拒绝合并并报告两侧文件数,要求手动处理后再重跑。

六、快速上手:注册 hooks 与初始化目录

方式 A:以插件方式安装(推荐)

Claude Code v2.1+ 会自动加载插件自带的 hooks/hooks.json,其中已注册好 observe.sh无需settings.json 中再加 hooks 块。文档特别提醒:若此前曾手动把 observe.sh 复制进 ~/.claude/settings.json,应删除重复的 PreToolUse/PostToolUse 块——重复注册会导致 hook 双重执行,并因 ${CLAUDE_PLUGIN_ROOT} 只在插件管理的 hooks/hooks.json 条目内可用而产生解析错误。

方式 B:手动安装到 ~/.claude/skills

~/.claude/settings.json 中加入:

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "~/.claude/skills/continuous-learning-v2/hooks/observe.sh"
      }]
    }],
    "PostToolUse": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "~/.claude/skills/continuous-learning-v2/hooks/observe.sh"
      }]
    }]
  }
}

目录结构初始化

系统会在首次使用时自动创建目录,也可手动预建全局骨架:

# 全局目录
mkdir -p "${XDG_DATA_HOME:-$HOME/.local/share}/ecc-homunculus"/{instincts/{personal,inherited},evolved/{agents,skills,commands},projects}
# 项目级目录会在 hook 首次于 git 仓库运行时自动创建

七、六个 Slash 命令与 CLI 用法

技能文档给出六个会话内命令:

/instinct-status     # 展示已学到的 instincts(项目级 + 全局)及置信度
/evolve              # 把相关 instincts 聚类成 skills/commands,并给出提升建议
/instinct-export     # 把 instincts 导出为文件
/instinct-import     # 从他人文件导入 instincts
/promote             # 把项目级 instincts 提升到全局作用域
/projects            # 列出所有已知项目及其 instincts 数量

对应仓库中的命令文档分别为 commands/instinct-status.mdcommands/instinct-export.mdcommands/instinct-import.md(另有 evolve/promote/projects 命令)。

当你想脱离会话界面直接管理时,instinct-cli.py 是同一能力的命令行后端。从 scripts/instinct-cli.py 的模块 docstring 可以看到完整命令面:

status   - Show all instincts (project + global) and their status
import   - Import instincts from file or URL
export   - Export instincts to file
evolve   - Cluster instincts into skills/commands/agents
promote  - Promote project instincts to global scope
projects - List all known projects and their instinct counts
prune    - Delete pending instincts older than 30 days (TTL)

其中 status 输出时会把置信度渲染成进度条(/,无法编码时回退 #/.),方便快速浏览各 instinct 的强弱。

八、配置项与后台 Observer 的平台限制

编辑 config.json(仓库内默认)或 ${homunculus目录}/config.json 控制后台 observer:

{
  "version": "2.1",
  "observer": {
    "enabled": false,
    "run_interval_minutes": 5,
    "min_observations_to_analyze": 20
  }
}
配置键 默认值 说明
observer.enabled false 是否启用后台 observer agent
observer.run_interval_minutes 5 observer 多久分析一次观测数据
observer.min_observations_to_analyze 20 达到该观测条数才触发分析

其余行为(观察捕获、instinct 阈值、项目作用域、提升条件)默认由 instinct-cli.pyobserve.sh 的代码内默认值控制。

平台支持:Linux / macOS / WSL2 才真正后台化

后台 observer 在 Linux、macOS、WSL2 下可以脱离 hook 存活;但在原生 Windows(Git Bash/MSYS2)下,observe.sh 启动时虽报告成功,进程却会随 spawning hook 退出、其 Job Object 关闭而被回收,因此 observer.enabled: true 在那里实际上不生效(仓库文档标注见 issue #2489)。observe.sh 会在连续多次发现 observer 未能存活后,向 observer-start.log 写入一次解释性警告,相关阈值可用环境变量调整:

环境变量 默认值 说明
ECC_OBSERVER_NOSURVIVE_WARN_AFTER 3 连续 N 次未能存活后才记录警告

值得注意 observe.sh 里对这条警告的严谨处理:计数文件做全数字校验(避免前导零被 bash 当作八进制)、只在“恰好等于阈值”时写一次日志(防止越过阈值后每条工具调用重复告警)、日志不可写时回退到 stderr。

九、数据目录布局(全局 vs 项目级)

${XDG_DATA_HOME:-~/.local/share}/ecc-homunculus/
+-- identity.json           # 你的画像、技术层级
+-- projects.json           # 注册表:项目 hash -> name/path/remote
+-- observations.jsonl      # 全局观测(回退用)
+-- instincts/
|   +-- personal/           # 全局自动学习到的 instincts
|   +-- inherited/          # 全局导入的 instincts
+-- evolved/
|   +-- agents/             # 全局生成的 agents
|   +-- skills/             # 全局生成的 skills
|   +-- commands/           # 全局生成的 commands
+-- projects/
    +-- a1b2c3d4e5f6/       # 项目 hash(源自 git remote URL)
    |   +-- project.json    # 项目级元数据镜像(id/name/root/remote)
    |   +-- observations.jsonl
    |   +-- observations.archive/
    |   +-- instincts/
    |   |   +-- personal/   # 项目特有、自动学习
    |   |   +-- inherited/  # 项目特有、导入
    |   +-- evolved/
    |       +-- skills/
    |       +-- commands/
    |       +-- agents/
    +-- f6e5d4c3b2a1/       # 另一个项目

该结构与 detect-project.sh 里自动创建的 mkdir -p 序列(instincts/personalinstincts/inheritedobservations.archiveevolved/{skills,commands,agents})完全一致。

十、作用域决策指南

文档用一张表界定了什么该留在项目里、什么该上到全局:

模式类型 作用域 示例
语言/框架约定 project “使用 React hooks”、“遵循 Django REST 模式”
文件结构偏好 project “测试放 __tests__/”、“组件放 src/components/”
代码风格 project “用函数式风格”、“偏好 dataclasses”
错误处理策略 project “用 Result 类型处理错误”
安全实践 global “校验用户输入”、“SQL 消毒”
通用最佳实践 global “先写测试”、“始终处理错误”
工具工作流偏好 global “Edit 前先 Grep”、“Write 前先 Read”
Git 实践 global “Conventional commits”、“小而聚焦的提交”

判据很直观:跟具体技术栈绑定的经验留在项目,跨栈普适的工作方法上全局

十一、Instinct 提升:从项目级到全局

当一个 instinct 以高置信度在多个项目重复出现时,它就有资格晋升到全局作用域。

自动提升条件(auto-promotion criteria):

  • 同一 instinct ID 出现在 2+ 个项目中;
  • 平均置信度 ≥ 0.8。

/evolve 命令会主动推荐满足条件的候选;也可用 CLI 直接操作:

# 提升指定 instinct
python3 instinct-cli.py promote prefer-explicit-errors

# 自动提升全部符合条件的 instincts
python3 instinct-cli.py promote

# 只预览、不落盘
python3 instinct-cli.py promote --dry-run

这条“项目内高频出现 → 全局化”的路径,正是 v2.1 区分于 v2 的核心增量:先在隔离环境中验证模式的普适性,再决定是否广播给所有项目。

十二、置信度评分:0.3 到 0.9 的演化

置信度随时间演化,是 instinct 能否被采纳的准绳:

分数 含义 行为
0.3 试探性(Tentative) 仅建议,不强制执行
0.5 中等(Moderate) 相关时应用
0.7 强(Strong) 自动批准应用
0.9 近乎确定(Near-certain) 核心行为

置信度上升的时机:

  • 模式被反复观察;
  • 用户没有纠正被建议的行为;
  • 来自其他来源的相似 instinct 相互印证。

置信度下降的时机:

  • 用户显式纠正该行为;
  • 模式在长时间内不再出现;
  • 出现矛盾证据。

配合 instinct-cli.py status 的进度条渲染,开发者可以一眼看出哪些行为已经“板上钉钉”、哪些仍在试探期。

十三、为什么用 Hooks 而不是 Skill 做观察

技能文档引用了 v1 时代的教训:

“v1 relied on skills to observe. Skills are probabilistic — they fire ~50-80% of the time based on Claude's judgment.”

(v1 依赖 skills 观察,而 skills 是概率性的——基于 Claude 的判断,只有约 50–80% 时间会触发。)

Hooks 则 100% 确定性触发,意味着:

  • 每一次工具调用都被观察;
  • 没有模式被漏掉;
  • 学习是全量的。

十四、隐私边界与脱敏实现

隐私承诺同样写进了规范:

  • 观察数据只留在本机
  • 项目级 instincts 按项目相互隔离;
  • 只有 instincts(模式) 可被导出,原始观察数据永远不导出;
  • 不分享真实代码或对话内容;
  • 导出与提升都由你掌控。

在实现层面,这份承诺被 hooks/observe.sh 落到了实处:写盘前对工具输入输出执行正则密钥脱敏(替换为 [REDACTED]),解析失败的原始 JSON 兜底日志同样先过脱敏再落盘;同时 scripts/detect-project.sh 在哈希 remote URL 前会剥离内嵌凭证,避免仓库地址里的 token 进入项目 ID 与注册表。

十五、向后兼容与渐进迁移

v2.1 与 v2.0、v1 完全兼容:

  • 既有全局 instincts 可用 scripts/migrate-homunculus.sh~/.claude/homunculus/instincts/ 迁移;
  • v1 遗留的 ~/.claude/skills/learned/ skills 仍可工作;
  • Stop hook 继续运行(其内容同样汇入 v2 数据流);
  • 可并行运行,渐进切换。

结语

Continuous Learning v2.1 的工程取舍非常清晰:用 hooks 的确定性取代 skill 的概率性、用原子 instinct + 置信度取代整块 skill 的生搬硬套、用项目级与全局的双层存储隔离环境特例与普适经验。如果你希望 Claude Code 在编码风格、错误处理与工作流偏好上越用越懂你,同时又不把 A 仓库的习惯错误地带进 B 仓库,那么在本仓库 skills/continuous-learning-v2/SKILL.md 及配套的 hooks/observe.shscripts/instinct-cli.py 中,可以找到一整套可直接上手的落地方案。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391