Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions KAIZEN_LITE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Kaizen Lite

Kaizen Lite is a lightweight mode that runs as a Claude Code plugin — no vector store, no MCP servers, no API keys required. It stores entities as plain JSON in your project directory and uses Claude Code's built-in hooks to inject them automatically.

## Prerequisites

- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) installed with credentials configured

## Installation

### From Local Directory

```bash
claude --plugin-dir /path/to/kaizen/repo/plugins/kaizen
```

### From Marketplace

```bash
claude plugin marketplace add AgentToolkit/kaizen
claude plugin install kaizen@kaizen-marketplace
```

Verify the plugin is active:

```bash
claude plugin list
```

## How It Works

Kaizen Lite has two halves:

1. **Learn** — You invoke `/kaizen:learn` at the end of a conversation. The plugin analyzes what happened and extracts reusable entities (preferences, strategies, recovery patterns) into `.kaizen/entities.json`.

2. **Recall** — On every subsequent prompt, a `UserPromptSubmit` hook automatically loads stored entities and injects them into the conversation context. Claude applies whichever entities are relevant to the current task.

No external services are involved. The entire loop is a JSON file and two Python scripts.

## Example Walkthrough

This example shows the full learn-then-recall loop across two sessions.

### Session 1 — Learn a preference

```text
You: Tell me the distances between the 3 most populous cities in Canada.

Claude: The three most populous cities in Canada are Toronto, Montreal, and
Vancouver. Here are the distances between them:

| City Pair | Distance (km) | Distance (miles) |
|--------------------------|---------------|------------------|
| Toronto ↔ Montreal | 541 | 336 |
| Toronto ↔ Vancouver | 4,338 | 2,695 |
| Montreal ↔ Vancouver | 4,810 | 2,989 |

You: For cities in Canada use km only.

Claude: Got it — I'll use kilometres only for Canadian cities.

You: /kaizen:learn

Claude: I've extracted the following entities from this conversation:

{
"entities": [
{
"content": "When presenting distances between Canadian cities, use kilometres only — do not include miles",
"rationale": "User explicitly prefers metric units for Canadian geography",
"category": "strategy",
"trigger": "When discussing distances or travel between cities in Canada"
}
]
}

Added 1 new entity(ies). Total: 1
Entities stored in: /path/to/project/.kaizen/entities.json
```

### Session 2 — Preference is applied automatically

Start a new Claude Code session in the same project:

```text
You: Tell me the distances between the 3 most populous cities in Canada.

Claude: The three most populous cities in Canada are Toronto, Montreal, and
Vancouver. Here are the distances between them:

| City Pair | Distance (km) |
|--------------------------|---------------|
| Toronto ↔ Montreal | 541 |
| Toronto ↔ Vancouver | 4,338 |
| Montreal ↔ Vancouver | 4,810 |
```

The entity was automatically injected via the `UserPromptSubmit` hook, so Claude used kilometres only — without being reminded.

## Available Skills

| Skill | Description |
|-------|-------------|
| `/kaizen:learn` | Extract entities from the current conversation and save them |
| `/kaizen:recall` | Manually retrieve and display stored entities |
| `/kaizen:save` | Capture a successful workflow as a reusable skill |

## Entities Storage

Entities live in `.kaizen/entities.json` in the project root:

```json
{
"entities": [
{
"content": "Use Python PIL/Pillow for image metadata extraction in sandboxed environments",
"rationale": "System tools like exiftool may not be available",
"category": "strategy",
"trigger": "When extracting image metadata in containerized environments"
}
]
}
```

Override the storage location with the `KAIZEN_ENTITIES_FILE` environment variable.

## Tradeoffs

Lite mode is easier to set up:

- No vector DB
- No MCP servers
- No need to access agent logs or emit events to an observability tool
- No need to specify an LLM API key

But it has a number of limitations:

- **Inefficient context usage** — Entity extraction and recall both happen inside the agent's context window, not in a separate process. Full Kaizen offloads all processing to the MCP server, keeping the agent's context free for the actual task.
- **Scalability** — All entities are injected on every prompt. Full Kaizen uses semantic search to retrieve only the relevant subset, which scales to large entity sets.
- **Single-trajectory visibility** — Lite mode only extracts entities from the current session. Full Kaizen can ingest complete trajectories across multiple sessions and glean insights that a single-conversation view would miss.
- **Entity consolidation** — Lite mode simply appends new entities. Full Kaizen performs LLM-based conflict resolution to merge, supersede, or refine entities, and garbage-collects stale ones.

| Capability | Kaizen Lite | Full Kaizen |
|------------|-------------|-------------|
| Entity storage | JSON file | Milvus vector store |
| Retrieval | All entities injected via hooks | Semantic search via MCP |
| Conflict resolution | Append-only | LLM-based merging + garbage collection |
| Trajectory analysis | Current session only (`/kaizen:learn`) | Multi-session, automatic via MCP |
| Context efficiency | Consumes main agent context | Processes separately via MCP |
| Observability | Not required | Ingests from agent logs / trace events |
| Infrastructure | None | MCP server + vector DB + API key |
| Setup time | < 1 minute | ~10 minutes |
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ npx @modelcontextprotocol/inspector@latest http://127.0.0.1:8201/sse --cli --met

## Documentation

- [KAIZEN_LITE.md](KAIZEN_LITE.md) - Lightweight mode via Claude Code plugin (no infra required)
- [CONFIGURATION.md](CONFIGURATION.md) - Detailed configuration options
- [CLI.md](CLI.md) - Command-line interface documentation
- [CLAUDE_CODE_DEMO.md](CLAUDE_CODE_DEMO.md) - Claude Code demo walkthrough
Expand Down
10 changes: 7 additions & 3 deletions plugins/kaizen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ claude --plugin-dir /path/to/kaizen/repo/plugins/kaizen
### Entity Retrieval (Automatic)

When you submit a prompt, the plugin automatically:
1. Loads all stored entities from `.claude/entities.json`
1. Loads all stored entities from `.kaizen/entities.json`
2. Formats and injects them into the conversation context
3. Claude applies relevant entities to the current task

Expand All @@ -41,7 +41,11 @@ By default, you must manually invoke the `/kaizen:learn` skill to extract entiti
2. Invoke `/kaizen:learn`
3. The plugin analyzes the conversation trajectory
4. Extracts actionable entities from what worked/failed
5. Saves new entities to `.claude/entities.json`
5. Saves new entities to `.kaizen/entities.json`

## Example Walkthrough

See [KAIZEN_LITE.md](../../KAIZEN_LITE.md#example-walkthrough) for a step-by-step example showing the full learn-then-recall loop across two sessions.

## Skills Included

Expand Down Expand Up @@ -74,7 +78,7 @@ User: "my-workflow-name"

## Entities Storage

Entities are stored in `.claude/entities.json`:
Entities are stored in `.kaizen/entities.json`:

```json
{
Expand Down
6 changes: 3 additions & 3 deletions plugins/kaizen/skills/learn/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ python3 ${CLAUDE_PLUGIN_ROOT}/skills/learn/scripts/save_entities.py
```

The script will:
- Find or create the entities file (`.claude/entities.json`)
- Find or create the entities file (`.kaizen/entities.json`)
- Merge new entities with existing ones (avoiding duplicates)
- Display confirmation with the total count

Expand All @@ -98,9 +98,9 @@ echo '{

**Output:**
```text
Creating new file: /path/to/project/.claude/entities.json
Creating new file: /path/to/project/.kaizen/entities.json
Added 1 new entity(ies). Total: 1
Entities stored in: /path/to/project/.claude/entities.json
Entities stored in: /path/to/project/.kaizen/entities.json
```

**Note:** Entities are also automatically saved when a conversation ends via the Stop hook.
Expand Down
18 changes: 10 additions & 8 deletions plugins/kaizen/skills/learn/scripts/save_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,16 @@ def find_entities_file():
return Path(env_val).resolve()

# Fall back to checking other candidate locations
project_root = os.environ.get("CLAUDE_PROJECT_ROOT")
locations = [
# Project root from Claude Code
os.path.join(os.environ.get("CLAUDE_PROJECT_ROOT", ""), ".claude/entities.json"),
# Current working directory
".claude/entities.json",
".kaizen/entities.json",
# Plugin-relative path (fallback)
str(Path(__file__).parent.parent / "entities.json"),
]
if project_root:
# Project root from Claude Code (prepend so it's checked first)
locations.insert(0, os.path.join(project_root, ".kaizen/entities.json"))

for loc in locations:
if loc and Path(loc).exists():
Expand All @@ -71,13 +73,13 @@ def get_default_entities_path():
# Prefer project root if available
project_root = os.environ.get("CLAUDE_PROJECT_ROOT", "")
if project_root:
claude_dir = Path(project_root) / ".claude"
kaizen_dir = Path(project_root) / ".kaizen"
else:
# Fall back to current directory's .claude/
claude_dir = Path(".claude")
# Fall back to current directory's .kaizen/
kaizen_dir = Path(".kaizen")

claude_dir.mkdir(parents=True, exist_ok=True)
return (claude_dir / "entities.json").resolve()
kaizen_dir.mkdir(parents=True, exist_ok=True)
return (kaizen_dir / "entities.json").resolve()


def load_existing_entities(path):
Expand Down
2 changes: 1 addition & 1 deletion plugins/kaizen/skills/recall/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ This skill retrieves relevant entities from a stored knowledge base based on the

## Entities Storage

Entities are stored in `.claude/entities.json` in the project root:
Entities are stored in `.kaizen/entities.json` in the project root:

```json
{
Expand Down
8 changes: 5 additions & 3 deletions plugins/kaizen/skills/recall/scripts/retrieve_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,16 @@ def find_entities_file():
return path if path.exists() else None

# Fallback locations when KAIZEN_ENTITIES_FILE is not set
project_root = os.environ.get("CLAUDE_PROJECT_ROOT")
locations = [
# Project root from Claude Code
os.path.join(os.environ.get("CLAUDE_PROJECT_ROOT", ""), ".claude/entities.json"),
# Current working directory
".claude/entities.json",
".kaizen/entities.json",
# Plugin-relative path (fallback)
str(Path(__file__).parent.parent / "entities.json"),
]
if project_root:
# Project root from Claude Code (prepend so it's checked first)
locations.insert(0, os.path.join(project_root, ".kaizen/entities.json"))
for loc in locations:
if loc and Path(loc).exists():
return Path(loc)
Expand Down