google / google/adk-python

[Feature Request] Memory plugins: optional flag to promote recurring patterns into SKILL.md artifacts

未关闭
#5,398 4 条评论 0 个 reaction 已指派 2 人 已被 @wukath 认领 在 GitHub 查看
needs review services
主要语言
Python
星标
21.5k
派生
4k
平均合并
1 天 14 小时
30 天内合并 PR
37

描述

**Component:** services (memory), skills
**Type:** feature request / research
**Status:** proposal, seeking maintainer input before implementation

## Summary

Add an opt-in flag on ADK memory plugins (e.g. `VertexAiMemoryBankService`, `GoodmemPlugin`, and any `BaseMemoryService` implementation) that enables **procedural pattern detection** in addition to today's semantic memory generation. When a recurring, generalizable workflow is detected across a user's sessions, the plugin emits a candidate `SKILL.md` (agentskills.io spec) that can be reviewed and loaded via `SkillToolset` in future runs.

Concretely: memories today answer "what does the user prefer?" This proposes memories that can also answer "what workflow does the user keep re-deriving, and should that be a Skill?"

## Motivation

ADK already has the two primitives needed to close this loop, but they do not talk to each other:

1. **Memory generation** (`v1.15.0` added a service endpoint to generate memory from a session; Memory Bank has a `(Callback): ADK triggers memory generation` hook; `GoodmemPlugin` does this automatically per turn). These extract **semantic facts** — user preferences, entities, history.
2. **Skills** (`google.adk.skills`, `SkillToolset`, `load_skill_from_dir`, v1.25.0+) encode **procedural knowledge** — step-by-step instructions loaded on demand via L1/L2/L3 progressive disclosure.

Today, the only way a Skill enters the system is:
- A human writes `SKILL.md` by hand, or
- An agent is explicitly prompted via a "meta-skill" pattern to write one (see the Google Developers blog "Developer's Guide to Building ADK Agents with Skills").

Neither captures the real signal: **the same user re-asking the agent to do the same kind of thing across sessions.** That pattern is sitting in Memory Bank / GoodMem's embedding store, already segmented by user/app scope, already being summarized for semantic memory. The plugin is the correct place to notice it.

### Concrete example (the trigger for this issue)

When a developer repeatedly uses an agent to scaffold ADK agents — asking for `LlmAgent` setup, `SequentialAgent` compositions, `SkillToolset` wiring, common callback patterns, etc. — the memory plugin today stores facts like "user builds ADK agents" and "user prefers Python." It does not notice that across 14 sessions the same 6-step scaffolding procedure was re-derived, nor propose: *"I've seen this pattern enough times to extract it. Want me to write `skills/adk-scaffold/SKILL.md`?"*

This is exactly the procedural memory gap that Anthropic-style skills and agentskills.io were designed for. The plugin already has the data.

## Proposed API

Non-breaking, opt-in, defaults to off.

```python
from google.adk.memory import VertexAiMemoryBankService

memory_service = VertexAiMemoryBankService(
project="my-project",
location="us-central1",
agent_engine_id="...",
# NEW
skill_generation=SkillGenerationConfig(
enabled=True,
min_pattern_occurrences=3, # require N recurrences before proposing
min_session_span=2, # across at least N distinct sessions
output_dir="./skills/generated", # where candidate SKILL.md files land
mode="propose", # "propose" | "auto_load" | "disabled"
spec_version="agentskills.io/v1",
),
)
```

Same shape extends to `GoodmemPlugin` and any custom `BaseMemoryService`.

### Behavior by mode

| Mode | Behavior |
|---|---|
| `disabled` (default) | No change from today. |
| `propose` | Plugin writes `SKILL.md` candidates to `output_dir` and surfaces them via a structured event. Human/agent reviews before loading. |
| `auto_load` | Plugin writes and immediately registers via `SkillToolset.add_skill()`. Higher risk — gated behind explicit config. |

### Emitted SKILL.md shape

Must conform to the same spec `load_skill_from_dir` consumes, so generated skills are indistinguishable from handwritten ones:

```markdown
---
name: adk-agent-scaffold
description: Scaffold a new ADK LlmAgent with tool wiring and callbacks. Use when the user asks to create a new agent, set up an agent skeleton, or wire tools into an agent.
metadata:
generated_by: memory_plugin
source_sessions: ["sess_abc", "sess_def", "sess_ghi"]
pattern_confidence: 0.87
version: "0.1-draft"
---

## Instructions
[synthesized from recurring session patterns]
```

The `metadata.generated_by` field matters: downstream tooling, eval suites, and reviewers need to distinguish generated candidates from vetted skills.

## Open research questions

This is filed as a **research task** because several non-trivial questions need maintainer input before an implementation PR makes sense.

1. **Pattern detection method.** Options, not mutually exclusive:
- **Embedding clustering** on user turns (cheap, already computed by Memory Bank / GoodMem).
- **Event-graph similarity** across sessions — same tool-call sequences, same sub-agent routes. ADK already has the `Event` stream; this is the highest-fidelity signal.
- **LLM-as-judge** over N candidate sessions, prompted to extract a generalized procedure. Expensive but produces the highest-quality SKILL.md body.
- Likely a pipeline: cluster → rank → LLM-synthesize for top-K candidates only.

2. **Generalization vs. overfitting.** A user who asked "scaffold an ADK agent" three times in slightly different ways is a clear pattern. A user who asked the exact same question three times is a FAQ, not a skill. How does the detector separate *procedural patterns that generalize* from *repeated specific queries*?

3. **Scoping.** Skills generated from one user's sessions may leak private details (internal endpoints, API keys in example code, org-specific project names). Need a redaction pass, and the scope boundaries (`user_id`, `app_name`) from Memory Bank's existing scope dictionary should carry through.

4. **Drift and invalidation.** When ADK's own APIs change (e.g. the `load_memory` schema churn in #160, the v1.25 skill API itself), user-generated SKILL.md files pinned to old patterns become wrong. Needs either a version-pin field or a staleness signal. Probably both.

5. **Interaction with `EventsCompactionConfig` and static instructions.** Both landed recently (v1.15). The pattern detector needs to run *before* compaction destroys the signal, or needs to index off compacted summaries. Open question which.

6. **Review surface.** Where does the human actually see "you have 3 candidate skills"? Options: `adk web` UI, a CLI `adk skills review`, a structured event in the runner's event stream. Probably all three eventually, but the MVP should pick one.

7. **Evaluation.** How do we tell if generated skills are actually useful? Natural fit: run the existing `adk eval` against the same prompt set with and without the generated skill loaded. Any regression → skill gets flagged.

## Why this belongs in the memory plugin, not elsewhere

A reasonable objection: "this is a skill-authoring tool, put it in `google.adk.skills`." Counter-argument:

- The **signal** (recurring user patterns across sessions) lives in the memory service's data, not in the skills module.
- Memory plugins already have the callback surface (`after_agent_callback`, the `memories.ingest_events` path added in the latest release) and the scope discipline (user/app isolation).
- Making it a memory-plugin flag lets any `BaseMemoryService` implementation opt in — VertexAi, GoodMem, RAG, custom — without each one reinventing pattern detection.

The skill-authoring side (`models.Skill`, `load_skill_from_dir`) stays untouched and just consumes what the plugin produces.

## Prior art

- **Google Developers Blog** — "Developer's Guide to Building ADK Agents with Skills" describes a manual meta-skill pattern where agents write SKILL.md at runtime. This proposal is the *automated, memory-driven* version.
- **Anthropic's skill-creator pattern** — skills generated from observed interaction traces. Same idea, different runtime.
- **Memory Bank's own consolidation** — already merges/updates semantic memories (e.g. "I like 71 degrees" + "warmer in mornings" → consolidated memory). Extending consolidation to produce procedural artifacts is a natural next step.

## Non-goals

- Not proposing any change to the agentskills.io spec itself.
- Not proposing `auto_load` as default — that mode exists in the config but should ship behind explicit opt-in and ideally a capability flag on the runtime.
- Not proposing this replaces handwritten skills. Generated skills are candidates, not ground truth.

## Requested from maintainers

1. Is this direction something ADK wants in-tree, or better as a community plugin (e.g. a `SkillPromotionPlugin` alongside `GoodmemPlugin`)?
2. Is the right integration point `BaseMemoryService` (so every memory backend inherits it) or a separate `BasePlugin` that consumes memory service output?
3. Any existing internal work on this at Google that would make a community PR redundant?

Happy to prototype against `InMemoryMemoryService` + `SkillToolset` as a proof of concept if there's maintainer interest.

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。