nanobot/docs/SELF_EVOLUTION.md
2026-04-10 01:41:40 +08:00

203 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.