docs: add Self-Evolution feature documentation

This commit is contained in:
chengyongru 2026-04-10 01:41:40 +08:00
parent 57453d2d30
commit fc2638d994

202
docs/SELF_EVOLUTION.md Normal file
View File

@ -0,0 +1,202 @@
# Self-Evolution
The self tool allows the agent to inspect, modify, and invoke its own runtime state — enabling adaptive behavior where the agent tunes itself to the task at hand.
**This feature is disabled by default.** It is intended for advanced users who understand the implications of letting an LLM modify its own runtime parameters.
## Enabling
Add to your `config.yaml`:
```yaml
tools:
self_evolution: true
```
All changes are in-memory only. Restarting the agent restores defaults.
## What It Does
The agent gains a `self` tool with the following actions:
### `inspect` — View Runtime State
Without a key, returns a summary of configurable parameters.
```
self(action="inspect")
# → max_iterations: 40
# context_window_tokens: 65536
# model: 'anthropic/claude-sonnet-4-20250514'
```
With a dot-path key, navigates into nested objects:
```
self(action="inspect", key="subagents._running_tasks")
# → subagents: 2 running — ['a1b2c3', 'd4e5f6']
self(action="inspect", key="web_config.enable")
# → web_config.enable: True
self(action="inspect", key="context.build_system_prompt")
# → method build_system_prompt() — use 'call' action to invoke
```
### `modify` — Change Runtime Parameters
For attributes that already exist on the loop, the change takes immediate effect via `setattr`. For new keys, the value is stored in a free-form `_runtime_vars` dictionary.
```
self(action="modify", key="max_iterations", value=80)
# → Set max_iterations = 80 (was 40)
self(action="modify", key="provider_retry_mode", value="persistent")
# → Set provider_retry_mode = 'persistent' (was 'standard')
self(action="modify", key="my_custom_flag", value=True)
# → Set _runtime_vars.my_custom_flag = True
```
**Restricted parameters** (type and range validated):
| Parameter | Type | Range |
|-----------|------|-------|
| `max_iterations` | int | 1100 |
| `context_window_tokens` | int | 4,0961,000,000 |
| `model` | str | min 1 character |
All other attributes are freely modifiable without type constraints.
### `call` — Invoke Methods
Call any reachable method on the agent loop or its sub-objects. Supports both sync and async methods.
```
self(action="call", method="subagents.get_running_count")
# → 0
self(action="call", method="context.build_system_prompt")
# → <full system prompt text>
self(action="call", method="subagents.cancel_by_session",
args={"session_key": "weixin:user123"})
# → 2
```
### `list_tools` — Show Registered Tools
```
self(action="list_tools")
# → Tools (12):
# read_file: Read a file from the workspace
# write_file: Write content to a file
# ...
```
### `manage_tool` — Register/Unregister Tools
```
self(action="manage_tool", name="web_search", manage_action="unregister")
# → Unregistered tool 'web_search'
self(action="manage_tool", name="web_search", manage_action="register")
# → Re-registered tool 'web_search'
```
The `self` tool itself cannot be unregistered (lockout prevention).
### `snapshot` / `restore` / `list_snapshots` — Config Templates
Save and restore named configuration snapshots:
```
self(action="snapshot", name="coding_mode")
# → Snapshot 'coding_mode' saved
self(action="modify", key="max_iterations", value=100)
self(action="modify", key="context_window_tokens", value=131072)
self(action="snapshot", name="high_capacity")
# → Snapshot 'high_capacity' saved
self(action="restore", name="coding_mode")
# → Restored snapshot 'coding_mode'
self(action="list_snapshots")
# → Snapshots (2): ['coding_mode', 'high_capacity']
```
Snapshots capture all restricted parameter values and `_runtime_vars`. They are stored in memory and lost on restart.
### `reset` — Restore Defaults
```
self(action="reset", key="max_iterations")
# → Reset max_iterations = 40 (was 80)
self(action="reset", key="my_custom_flag")
# → Deleted _runtime_vars.my_custom_flag
```
## Safety Model
### What is blocked
Only attributes that would cause hard crashes or lockout:
- `bus` — corrupts message routing
- `provider` — corrupts all LLM calls
- `_running` — main loop control flag
- Internal self-tool state (`_config_defaults`, `_runtime_vars`, `_config_snapshots`, etc.)
- Dunder attributes (`__class__`, `__dict__`, etc.)
### What is NOT blocked
Everything else — `tools`, `subagents`, `sessions`, `context`, `consolidator`, `dream`, `runner`, `commands`, `web_config`, `exec_config`, `workspace`, etc.
The design philosophy: since all changes are in-memory and lost on restart, the risk is low. The agent should be free to experiment.
### Runtime safeguards
| Safeguard | Limit |
|-----------|-------|
| `_runtime_vars` key cap | 64 keys |
| Value size limit | 1,024 total elements (recursive) |
| Nesting depth limit | 10 levels |
| Callable values | Rejected |
| Non-JSON-safe types | Rejected |
| Watchdog | Validates restricted params each iteration, auto-resets invalid values |
## Use Cases
### Adaptive performance tuning
The agent can increase `context_window_tokens` or `max_iterations` mid-conversation when it detects a complex task, and restore defaults afterward.
### Dynamic tool management
Disable tools that are noisy for a specific task (e.g., `web_search` during a coding session), then re-enable them later.
### Configuration templates
Save optimal configurations for different task types and switch between them:
```
snapshot("coding") → high iterations, large context
snapshot("chat") → low iterations, small context
snapshot("research") → web tools enabled, medium context
```
### Subagent monitoring
Observe running subagent tasks and cancel stale ones:
```
inspect("subagents._running_tasks")
call("subagents.cancel_by_session", args={"session_key": ...})
```
### Debugging
Inspect the current system prompt, check token usage, or view session state from within the agent loop.