AI 的持续学习:从会话中提取可复用知识
作者注:本文基于 ECC 项目的持续学习系统,展示如何让 AI 编码助手从每次会话中自动积累和进化。项目开源地址:github.com/affaan-m/ECC
摘要
最浪费资源的事情,是让 AI 反复学习同一个教训。ECC(Everything Claude Code)项目的持续学习系统通过 Stop Hook 自动提取会话中的有效模式,将其沉淀为可复用的 Skills。本文系统介绍持续学习的工作流、模式提取算法、置信度评分机制,以及如何将个人调试技巧转化为团队知识资产。文章包含 Python 实现的模式提取器和 Skill 生成器代码。
关键词:持续学习、知识提取、模式识别、Skill 进化、Stop Hook
一、问题的本质:AI 在重复学习
1.1 资源浪费的量化
假设团队每天与 AI 进行 20 次会话,每次会话中 AI "重新发现"一个已知的调试技巧:
📊 每日浪费估算 ├── 会话数: 20 次 ├── 每会话重复知识: 2-3 个 ├── 每个知识重新解释: 50-100 tokens ├── 每日浪费 Token: ~4,000 ├── 每月浪费 Token: ~120,000 └── 年化浪费: 大量时间和成本1.2 人类 vs AI 的学习差异
| 维度 | 人类开发者 | AI 助手 |
|---|---|---|
| 记忆存储 | 大脑 + 笔记 | 仅当前上下文 |
| 跨会话记忆 | 自然延续 | 完全重置 |
| 知识分享 | 文档、口传 | 无法自动分享 |
| 模式识别 | 需要刻意总结 | 可以自动化 |
持续学习的目标:让 AI 具备"跨会话积累知识"的能力。
二、ECC 持续学习工作流
2.1 整体流程
图 1:持续学习工作流 —— 从会话发现到 Skill 沉淀的完整链路
2.2 为什么用 Stop Hook?
ECC 明确选择Stop Hook而非UserPromptSubmit:
| 维度 | UserPromptSubmit | Stop Hook |
|---|---|---|
| 触发频率 | 每次用户消息 | 会话结束一次 |
| 对体验的影响 | 增加每次响应延迟 | 无感知 |
| 信息完整性 | 片段化 | 完整的会话上下文 |
| 处理复杂度 | 需实时处理 | 可批量处理 |
三、模式提取算法
3.1 什么是"可复用模式"
可复用模式包括但不限于:
- 调试技巧:“遇到 X 错误时,检查 Y 配置”
- 代码模式:“在 Python 中处理 Z 场景的标准写法”
- 架构决策:“本项目选择 A 方案而非 B 方案的原因”
- 工具使用:“使用 C 工具的特定参数组合”
3.2 Python 模式提取器
#!/usr/bin/env python3""" 模式提取器 —— 从会话日志中提取可复用知识 功能: 1. 解析会话日志 2. 识别有效/无效方法 3. 计算模式置信度 4. 生成 Skill 草稿 """importrefromtypingimportList,Dict,OptionalfromdataclassesimportdataclassfrompathlibimportPath@dataclassclassPattern:"""提取的模式"""category:str# 'debug', 'coding', 'architecture', 'tool'description:strevidence:str# 支持证据confidence:float# 0-1occurrences:int# 出现次数classPatternExtractor:""" 模式提取器 从会话文本中提取可复用的知识模式 """# 模式识别关键词PATTERN_MARKERS={"debug":["解决","修复","debug","排查","原因","由于"],"coding":["模式","写法","实现","函数","类","推荐"],"architecture":["架构","设计","决策","选择","方案","对比"],"tool":["工具","命令","参数","配置","使用","运行"],}# 有效性标记EFFECTIVE_MARKERS=["成功","有效","解决","通过","worked","fixed"]INEFFECTIVE_MARKERS=["失败","无效","不行","错误","failed","error"]def__init__(self,confidence_threshold:float=0.7):self.confidence_threshold=confidence_thresholddefextract(self,session_text:str)->List[Pattern]:""" 从会话文本提取模式 Args: session_text: 完整的会话文本 Returns: 提取的模式列表 """patterns=[]lines=session_text.split('\n')# 提取调试模式debug_patterns=self._extract_debug_patterns(lines)patterns.extend(debug_patterns)# 提取代码模式code_patterns=self._extract_code_patterns(lines)patterns.extend(code_patterns)# 提取架构决策arch_patterns=self._extract_architecture_patterns(lines)patterns.extend(arch_patterns)# 过滤低置信度return[pforpinpatternsifp.confidence>=self.confidence_threshold]def_extract_debug_patterns(self,lines:List[str])->List[Pattern]:"""提取调试模式"""patterns=[]fori,lineinenumerate(lines):ifany(kwinlineforkwin["解决","修复","fixed"]):# 向前查找问题描述context=self._get_context(lines,i,3)# 判断是否有效is_effective=any(kwincontextforkwinself.EFFECTIVE_MARKERS)ifis_effective:patterns.append(Pattern(category="debug",description=self._summarize_debug(context),evidence=context[:200],confidence=0.8,occurrences=1))returnpatternsdef_extract_code_patterns(self,lines:List[str])->List[Pattern]:"""提取代码模式"""patterns=[]# 查找代码块后的解释in_code_block=Falsecode_content=[]forlineinlines:ifline.strip().startswith('```'):ifin_code_block:# 代码块结束ifcode_content:pattern=self._analyze_code_pattern(code_content)ifpattern:patterns.append(pattern)code_content=[]in_code_block=notin_code_blockelifin_code_block:code_content.append(line)returnpatternsdef_extract_architecture_patterns(self,lines:List[str])->List[Pattern]:"""提取架构决策"""patterns=[]fori,lineinenumerate(lines):ifany(kwinlineforkwin["决定","选择","采用","使用"]):context=self._get_context(lines,i,2)# 判断是否包含理由has_reason=any(kwincontextforkwin["因为","由于","reason","because"])ifhas_reason:patterns.append(Pattern(category="architecture",description=line.strip()[:150],evidence=context[:200],confidence=0.75ifhas_reasonelse0.5,occurrences=1))returnpatternsdef_get_context(self,lines:List[str],index:int,radius:int)->str:"""获取上下文"""start=max(0,index-radius)end=min(len(lines),index+radius+1)return'\n'.join(lines[start:end])def_summarize_debug(self,context:str)->str:"""总结调试模式"""# 简化:返回前 100 个字符returncontext[:100].replace('\n',' ')def_analyze_code_pattern(self,code_lines:List[str])->Optional[Pattern]:"""分析代码模式"""code='\n'.join(code_lines)# 启发式:超过 3 行的代码块可能包含模式iflen(code_lines)<3:returnNonereturnPattern(category="coding",description=f"代码模式 ({len(code_lines)}行)",evidence=code[:300],confidence=0.6,occurrences=1)classSkillGenerator:""" Skill 生成器 将提取的模式转换为 SKILL.md 格式 """defgenerate(self,pattern:Pattern,skill_name:str)->str:""" 生成 Skill 内容 Args: pattern: 提取的模式 skill_name: Skill 名称 Returns: Markdown 格式的 SKILL.md 内容 """returnf"""---name:{skill_name}description:{pattern.description}origin:auto-extracted confidence:{pattern.confidence}---# {skill_name}## 使用场景(根据模式自动分类:{pattern.category})## 模式描述{pattern.description}## 证据{pattern.evidence[:500]}
## 注意事项 - 此 Skill 从会话自动提取,置信度为 {pattern.confidence} - 建议人工审查后使用 - 出现次数: {pattern.occurrences} ## 待完善 - [ ] 补充更详细的使用步骤 - [ ] 添加更多示例 - [ ] 验证在不同场景的有效性 """ def save(self, skill_name: str, content: str, base_dir: str = "skills") -> str: """保存 Skill 到文件""" skill_dir = Path(base_dir) / skill_name skill_dir.mkdir(parents=True, exist_ok=True) skill_file = skill_dir / "SKILL.md" skill_file.write_text(content, encoding='utf-8') return str(skill_file) # ========== 使用示例 ========== if __name__ == "__main__": # 模拟会话文本 session_text = """ 用户: 数据库连接超时怎么解决? 助手: 这个问题通常由连接池配置不当引起。检查一下 max_connections 是否设置合理。 用户: 我把 max_connections 从 10 改成 50,问题解决了! 助手: 很好。另外建议开启连接复用,避免频繁创建连接。 用户: 好的。还有一个问题,Python 中处理大量数据的最佳方式是什么? 助手: 推荐使用生成器模式,避免一次性加载所有数据到内存。 ```python def process_large_file(path): with open(path) as f: for line in f: yield process_line(line)用户: 这个方案有效,内存占用降低了很多。
“”"
extractor = PatternExtractor(confidence_threshold=0.6) patterns = extractor.extract(session_text) print("=" * 60) print("🔍 提取的模式") print("=" * 60) generator = SkillGenerator() for i, pattern in enumerate(patterns): print(f"\n{i+1}. [{pattern.category}] 置信度: {pattern.confidence}") print(f" 描述: {pattern.description[:80]}...") # 生成 Skill skill_name = f"auto-pattern-{i+1}" content = generator.generate(pattern, skill_name) path = generator.save(skill_name, content, "/tmp/skills") print(f" 💾 已保存: {path}")--- ## 四、置信度评分机制 ### 4.1 评分维度 | 维度 | 权重 | 说明 | |------|------|------| | **证据充分性** | 30% | 是否有明确的解决证据 | | **可复用性** | 25% | 是否通用而非特定场景 | | **简洁性** | 20% | 描述是否清晰简洁 | | **验证次数** | 15% | 是否在多次会话中出现 | | **领域相关性** | 10% | 是否属于核心开发领域 | ### 4.2 人工审查工作流 ```mermaid graph LR A[自动提取模式] --> B{置信度 >= 0.9?} B -->|是| C[自动入库] B -->|否| D[人工审查队列] D --> E[开发者审查] E --> F{有效?} F -->|是| G[完善后入库] F -->|否| H[丢弃] G --> I[提升置信度]图 2:置信度驱动的审查工作流 —— 高置信度自动入库,低置信度人工审查
五、总结
持续学习不是让 AI 变成"全知全能",而是避免重复学习同一课。
| 阶段 | 关键动作 | 产出 |
|---|---|---|
| 会话中 | 标记有效/无效方法 | 原始数据 |
| 会话结束 | Stop Hook 提取模式 | 候选模式 |
| 定期审查 | 人工验证和完善 | 高质量 Skill |
| 团队共享 | 同步到 skills/ 目录 | 组织知识 |
参考资料
- ECC continuous-learning Skill
- ECC 详细指南:the-longform-guide.md(持续学习章节)
- Pattern Recognition in Software Engineering
- Knowledge Management Systems
- ECC v1.2 发布说明:Instinct-based Learning
本文完。你的 AI 助手在学习吗?
