关于 continuous-learning
用于构建持续学习型 Agent 的技能,可从已完成会话中提炼可复用技能、规则和提示词改进。流程包括分析结果、验证候选模式,并整合经验证有效的模式。
主要功能
- 01记录会话并标注结果
- 02挖掘反复出现的成功模式
- 03用留出会话验证候选项
- 04生成并版本化可复用技能
- 05对技能变体进行 A/B 测试
适用场景
- 01改进重复的领域专属 Agent 任务
- 02在团队中共享有效做法
- 03测试并推广提示词或技能变更
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ itallstartedwithaidea/ agent-skills --skill continuous-learning安装后在 Claude Code 中输入/continuous-learning确认已加载。
详细介绍
持续学习
Agent Skills™ 的一部分,由 googleadsagent.ai™ 提供
描述
持续学习使 Agent 能够从已完成的会话中自动提取成功模式,并将其编纂为可复用的技能、规则和提示词优化。持续学习系统不再依赖手动编写技能,而是将每次 Agent 会话视为潜在的新能力来源。当 Agent 发现有效方法、解决新问题,或以可复现的方式从错误中恢复时,系统会捕获这种行为,并将其整合到 Agent 的技能库中。
这项技能编码了 Buddy™ 内置的学习飞轮,该飞轮位于 googleadsagent.ai™。跨会话模式挖掘已生成数十种专业的 Google Ads 分析技术,没有任何人类工程师明确编写过这些技术。系统会观察哪些工具序列能产生高质量结果、哪些提示词修改能提高准确性,以及哪些错误恢复策略有效,然后将这些观察结果整理成结构化技能,供未来会话使用。
学习流水线分为四个阶段:观察(记录带有结果注释的会话事件)、挖掘(识别跨会话中具有统计显著性的模式)、验证(使用留出的会话测试候选技能)和集成(将经过验证的技能部署到 Agent 的当前技能集中)。这相当于将科学方法应用于 Agent 行为:观察、提出假设、测试、部署。
适用场景
- 希望 Agent 能力随着时间推移自动提升,无需人工干预
- Agent 执行重复的特定领域任务,且不同会话中会逐渐显现规律
- 新团队成员需要受益于经验丰富的用户发现的模式
- 需要维护反映实际最佳实践的动态知识库
- 对不同的 Agent 方法进行 A/B 测试,并自动推广表现更佳的方法
- 通过自动推导技能,减少对手动提示词工程的依赖
工作原理
graph TD
A[Session Completion] --> B[Event Logger]
B --> C[Outcome Annotation]
C --> D[Pattern Mining Engine]
D --> E{Significant Pattern?}
E -->|Yes| F[Skill Template Generator]
E -->|No| G[Archive for Future Mining]
F --> H[Candidate Skill]
H --> I[Validation Suite]
I -->|Pass| J[Version + Deploy]
I -->|Fail| K[Refine Hypothesis]
K --> D
J --> L[Active Skill Set]
L --> M[A/B Test Monitor]
M -->|Winner| N[Promote to Default]
M -->|Loser| O[Deprecate]
每次会话完成后,学习循环便会启动。事件记录器会捕获完整的执行轨迹,并附上结果注释(成功、部分成功、失败、用户满意度信号)。模式挖掘引擎会定期分析累积的会话,寻找 Agent 行为与积极结果之间具有统计显著性的相关性。候选模式会转化为技能模板,即包含指令、示例和约束条件的结构化 SKILL.md 文件。验证阶段会使用留出的会话运行候选技能,以确认其能改善结果。经过验证的技能会进行版本管理并部署,同时通过 A/B 测试监控其相对表现。
实现
结果注释事件记录器:
@dataclass
class AnnotatedEvent:
session_id: str
event_type: str
content: dict
outcome_score: float # 0.0 = failure, 1.0 = success
user_feedback: str | None = None
class SessionLogger:
def __init__(self, store):
self.store = store
self.buffer = []
def log(self, event: AnnotatedEvent):
self.buffer.append(event)
async def flush(self, session_outcome: float):
for event in self.buffer:
if event.outcome_score == 0.0:
event.outcome_score = session_outcome
await self.store.append(event.session_id, asdict(event))
self.buffer.clear()
模式挖掘引擎:
class PatternMiner:
def __init__(self, min_occurrences=5, min_success_rate=0.8):
self.min_occurrences = min_occurrences
self.min_success_rate = min_success_rate
async def mine(self, sessions: list[list[AnnotatedEvent]]) -> list[dict]:
tool_sequences = self.extract_tool_sequences(sessions)
prompt_patterns = self.extract_prompt_patterns(sessions)
recovery_strategies = self.extract_recovery_patterns(sessions)
candidates = []
for pattern_set in [tool_sequences, prompt_patterns, recovery_strategies]:
for pattern in pattern_set:
if (pattern["occurrences"] >= self.min_occurrences
and pattern["success_rate"] >= self.min_success_rate):
candidates.append(pattern)
return sorted(candidates, key=lambda p: p["success_rate"] * p["occurrences"], reverse=True)
def extract_tool_sequences(self, sessions):
sequences = {}
for session in sessions:
tools = [e for e in session if e.event_type == "tool_call"]
for window in range(2, 5):
for i in range(len(tools) - window + 1):
seq = tuple(t.content.get("name", "") for t in tools[i:i+window])
outcome = sum(t.outcome_score for t in tools[i:i+window]) / window
if seq not in sequences:
sequences[seq] = {"occurrences": 0, "success_sum": 0}
sequences[seq]["occurrences"] += 1
sequences[seq]["success_sum"] += outcome
return [
{"type": "tool_sequence", "pattern": seq, "occurrences": s["occurrences"],
"success_rate": s["success_sum"] / s["occurrences"]}
for seq, s in sequences.items()
]
技能模板生成器:
SKILL_TEMPLATE = """# {name}
Part of [Agent Skills™](https://github.com/itallstartedwithaidea/agent-skills) by [googleadsagent.ai™](https://googleadsagent.ai)
## Description
{description}
## Use When
{use_when}
## Implementation
{implementation}
## Derived From
- Sessions analyzed: {sessions_analyzed}
- Pattern frequency: {frequency}
- Success rate: {success_rate:.0%}
- Generated: {generated_date}
"""
class SkillGenerator:
def __init__(self, model):
self.model = model
async def generate_skill(self, pattern: dict, examples: list) -> str:
prompt = f"""Generate a SKILL.md for the following discovered pattern:
Pattern type: {pattern['type']}
Pattern: {pattern['pattern']}
Success rate: {pattern['success_rate']:.0%}
Occurrences: {pattern['occurrences']}
Example sessions where this pattern succeeded:
{json.dumps(examples[:3], indent=2)}
Write a clear, actionable description, use-when conditions, and implementation guidance."""
content = await self.model.generate(prompt)
return SKILL_TEMPLATE.format(
name=pattern.get("name", "Discovered Pattern"),
version="1.0.0",
confidence=pattern["success_rate"],
description=content,
use_when="(see description)",
implementation="(see description)",
sessions_analyzed=pattern.get("sessions_analyzed", "N/A"),
frequency=pattern["occurrences"],
success_rate=pattern["success_rate"],
generated_date=datetime.utcnow().isoformat(),
)
A/B 测试框架:
interface SkillVariant {
id: string;
skillContent: string;
version: string;
metrics: { invocations: number; successes: number; avgScore: number };
}
class SkillABTest {
constructor(
private control: SkillVariant,
private treatment: SkillVariant,
private minSamples: number = 50,
) {}
selectVariant(sessionId: string): SkillVariant {
const hash = simpleHash(sessionId);
return hash % 2 === 0 ? this.control : this.treatment;
}
recordOutcome(variant: SkillVariant, score: number): void {
variant.metrics.invocations++;
variant.metrics.successes += score >= 0.8 ? 1 : 0;
variant.metrics.avgScore =
(variant.metrics.avgScore * (variant.metrics.invocations - 1) + score) /
variant.metrics.invocations;
}
getWinner(): SkillVariant | null {
if (this.control.metrics.invocations < this.minSamples) return null;
if (this.treatment.metrics.invocations < this.minSamples) return null;
const controlRate = this.control.metrics.successes / this.control.metrics.invocations;
const treatRate = this.treatment.metrics.successes / this.treatment.metrics.invocations;
const diff = Math.abs(controlRate - treatRate);
if (diff > 0.05) {
return controlRate > treatRate ? this.control : this.treatment;
}
return null;
}
}
最佳实践
- 标注结果,而不只是事件 — 没有成功/失败标签的原始事件日志对挖掘毫无用处;为每个重要事件附加结果评分。
- 要求具备统计显著性 — 观察到 3 次的模式只是个例;至少要求出现 5-10 次且成功率稳定,才将其提升为候选技能。
- 使用留出数据验证 — 绝不要只在生成某项技能的会话上测试它;使用留出的会话验证泛化能力。
- 为每项生成的技能进行版本管理 — 随着新数据的到来,自动生成的技能会不断演进;为其设置版本,以追踪改进并支持回滚。
- 全面部署前进行 A/B 测试 — 在一部分会话中,将新技能与当前默认技能进行对比;只有在明确证明效果有所提升后才予以推广。
- 限制自动生成的技能数量 — 过多的重叠技能会让 Agent 困惑;限制启用的技能数量,并弃用表现不佳的技能。
- 对影响重大的技能进行人工审核 — 关键领域的自动生成技能应在部署前由领域专家审核。
平台兼容性
| 功能 | Claude Code | Cursor | Codex | Gemini CLI |
|---|---|---|---|---|
| 会话日志记录 | ✅ Hooks | ✅ 扩展 | ✅ 自定义 | ✅ 自定义 |
| 模式挖掘 | ✅ 外部脚本 | ✅ 外部脚本 | ✅ 外部脚本 | ✅ 外部脚本 |
| 技能生成 | ✅ 兼容 SKILL.md | ✅ 原生支持 SKILL.md | ✅ 指令 | ✅ 系统提示词 |
| A/B 测试 | ✅ 自定义 | ✅ 自定义 | ✅ 自定义 | ✅ 自定义 |
| 自动部署 | ✅ 文件写入钩子 | ✅ 技能目录 | ⚠️ 手动 | ⚠️ 手动 |
相关技能
- 记忆持久化 - 会话数据持久化为跨会话模式挖掘提供原始材料
- 知识库注入 - 挖掘出的模式会作为可注入的知识部署,供未来的 Agent 会话使用
- 实体记忆管理 - 实体提取为模式挖掘流程提供结构化观察数据
- PMax 优化 - 从 Performance Max 广告系列数据中自动发现优化模式
关键词
持续学习、模式挖掘、技能生成、A/B 测试、反馈循环、自动改进、会话分析、知识推导、技能版本管理、Agent 技能
© 2026 googleadsagent.ai™ | Agent Skills™ | MIT License