Table of Contents
- Advanced Capabilities
- 1. Multi-Agent Systems
- 2. Custom Tool Development
- 3. Prompt System Customization
- Component Architecture
- Creating Custom Components
- Template Management
- Context-Specific Overrides
- Further Reading
- 4. Memory Architecture
- 5. RAG Integration
- 6. Event Sourcing and Audit
- 7. Resilience Patterns
- 8. Performance Tuning
- Token Budget Optimization
- Tick Rate Tradeoffs
- Multi-Action Loop Limits
- Model Selection
- Further Reading
- Architecture Reference
Advanced Capabilities
This guide covers advanced features for developers building sophisticated AI systems. Each section provides an overview and links to detailed architecture documentation.
1. Multi-Agent Systems
Sub-agent delegation allows your main assistant to spawn specialized assistants for complex tasks.
Overview
The delegation model supports three personality insulation modes:
| Mode | Main Assistant | Sub-Agents |
|---|---|---|
none |
Full context shared | Same context as main |
orchestrator |
Preserves personality | Task-focused, minimal context |
delegate |
Aggregates results | Independent personalities |
Quick Setup
-
Create the delegate assistant:
> aisetup/init helper > aisetup/config helper set llm_provider openrouter > aisetup/config helper set llm_auth_token sk-or-v1-YOUR_KEY > aisetup/config helper set llm_model openai/gpt-4o-mini > aisetup/start helper -
Tag the delegate for discovery:
> tag helper_script = specialist_assistant -
Configure the main assistant:
> aisetup/config mybot set sub_agents_enabled true > aisetup/config mybot set sub_agent_budget 3 > aisetup/config mybot set delegate_assistant_tag specialist_assistant > aisetup/config mybot set personality_insulation orchestrator
Now mybot can use the delegate_task tool to assign work to helper.
Use Cases
- Research delegation: Main assistant delegates API lookups to a research-focused sub-agent
- Building delegation: Orchestrator directs a builder sub-agent to construct rooms
- Multi-personality: Different sub-agents handle different game domains
Further Reading
- Architecture-Sub-Agent-Delegation - Full delegation system design
- Data-Flow-09-Self-Management-Operations - Task execution flow
2. Custom Tool Development
Extend the assistant's capabilities by creating custom tools.
Tool Structure
from evennia.contrib.base_systems.ai.tools import Tool, ToolCategory, TOOL_REGISTRY
class WeatherTool(Tool):
"""Check or modify the weather in a location."""
name = "weather"
description = "Check or set the weather conditions"
category = ToolCategory.SAFE_CHAIN # or TERMINAL, DANGEROUS, ASYNC_REQUIRED
parameters = {
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": ["check", "set"],
"description": "Whether to check or set the weather"
},
"weather": {
"type": "string",
"enum": ["sunny", "cloudy", "rainy", "stormy"],
"description": "Weather to set (only for 'set' action)"
},
"location": {
"type": "string",
"description": "Room dbref to affect (default: current location)"
}
},
"required": ["action"]
}
timeout = 10 # seconds
def execute(self, character, **kwargs):
action = kwargs.get("action")
location = kwargs.get("location")
# Resolve location
if location:
from evennia.utils import search
room = search.search_object(location)
room = room[0] if room else character.location
else:
room = character.location
if action == "check":
weather = room.db.weather or "unknown"
return {
"success": True,
"result": f"The weather in {room.key} is {weather}."
}
elif action == "set":
weather = kwargs.get("weather", "sunny")
room.db.weather = weather
return {
"success": True,
"result": f"Set weather in {room.key} to {weather}."
}
return {"success": False, "error": f"Unknown action: {action}"}
# Register the tool
TOOL_REGISTRY.register(WeatherTool)
Category Selection Guide
| Category | Use When |
|---|---|
SAFE_CHAIN |
Read-only, no side effects, can loop |
TERMINAL |
Produces output that needs user response |
DANGEROUS |
Modifies game state, should limit to one per tick |
ASYNC_REQUIRED |
Network calls, database writes, blocking I/O |
Registration
Tools can be registered:
- At import time (add to game
server/conf/at_initial_setup.py) - Via a custom app's
ready()method - Manually via
TOOL_REGISTRY.register(MyTool)
Further Reading
- Architecture-Tool-System - Tool registry, validation, categories
- Data-Flow-06-Tool-Execution - Execution flow and error handling
3. Prompt System Customization
Customize how prompts are assembled for different contexts.
Component Architecture
The prompt is built from ordered components:
| ID | Component | Purpose |
|---|---|---|
| 0 | System Prompt | Core LLM instructions |
| 1000 | Character Context | Persona, projects, session memory |
| 1500 | Entity Context | Active entity profiles, working memory |
| 2000 | Semantic Memories | Retrieved facts from Mem0 |
| 3000 | Context Buffer | Ambient room messages |
| 4000 | Goals | Active goals with hierarchy |
| 5000 | Conversation History | Token-budgeted chat |
| 7000 | Tool Result | Current tool execution result |
Creating Custom Components
from evennia.contrib.base_systems.ai.prompt_registry import get_prompt_registry
registry = get_prompt_registry()
# Create a custom component
registry.create_component(
key="lore_context",
name="World Lore",
content="The world of Mystara is a land of ancient magic...",
after_static=1000 # Insert after CHARACTER_CONTEXT
)
Template Management
Create a custom template:
> aisetup/template mybot create my_persona
List templates:
> aisetup/template mybot list
Apply a template:
> aisetup/template mybot apply my_persona
Context-Specific Overrides
Different contexts can have different component configurations:
> aisetup/context mybot reflection set component_overrides '{"semantic_memories": {"enabled": false}}'
Further Reading
- Architecture-Prompt-System - Component IDs, templates, registry
- Architecture-Context-System - Context types and layered configuration
4. Memory Architecture
The assistant uses a three-tier memory system inspired by cognitive architecture research.
Tier 1: Entity Profiles
Long-term knowledge about specific entities (players, NPCs, objects).
from evennia.contrib.base_systems.ai.helpers import (
create_entity_profile,
add_entity_observation,
update_relationship_metric
)
# Create profile
profile = create_entity_profile(character, "#123", "player")
# Add observation (episodic - Pf)
add_entity_observation(character, "#123", "Prefers formal speech", source="direct")
# Update relationship
update_relationship_metric(character, "#123", delta=+0.1, interaction="helpful")
During sleep consolidation, observations (Pf) are synthesized into attributes (Pa).
Tier 2: Working Memory
Active conversation context for ongoing interactions.
from evennia.contrib.base_systems.ai.helpers import (
start_conversation,
add_message_to_conversation,
add_pending_action
)
start_conversation(character, "#123", topic="quest_help")
add_message_to_conversation(character, "#123", "Can you help?", role="user")
add_pending_action(character, "#123", "Explain quest mechanics", priority=1)
Tier 3: Episodic Index
Journal entries with hybrid scoring (recency + importance + relevance).
from evennia.contrib.base_systems.ai.helpers import search_episodic_memory
results = search_episodic_memory(
entries=character.db.journal["entries"],
query="combat training",
days_back=7,
min_importance=5,
alpha_recency=1.0,
alpha_importance=1.0,
alpha_relevance=1.0
)
Further Reading
- Architecture-Memory-and-Sleep - Three-tier design, sleep phases
- Data-Flow-03-Memory-Consolidation - Consolidation process
- Data-Flow-05-Entity-Profile-System - O-Mem patterns
5. RAG Integration
Retrieval-Augmented Generation with Qdrant for semantic journal search.
Setup
-
Install dependencies:
pip install qdrant-client[fastembed] -
Start Qdrant:
docker run -d --name qdrant -p 6333:6333 qdrant/qdrant:latestOr use the provided docker-compose:
cd evennia/contrib/base_systems/ai docker-compose -f docker-compose.qdrant.yml up -d -
Enable RAG:
> aisetup/rag mybot enable > aisetup/rag mybot config set qdrant_host localhost
Embedding Providers
| LLM Provider | Default Embedding | Notes |
|---|---|---|
| openai | OpenAI API | Uses same token |
| anthropic | FastEmbed (local) | ONNX-based, no API |
| openrouter | FastEmbed (local) | ONNX-based, no API |
| ollama | Ollama | Same server |
Explicit configuration:
> aisetup/rag mybot config set rag_embedding_provider fastembed
Rebuild Collections
After significant journal changes:
> aisetup/rag mybot rebuild
Further Reading
- Architecture-RAG-Implementation - Qdrant client, embedding providers
- qdrant-deployment.md - Production deployment guide
6. Event Sourcing and Audit
Full audit trail with time-travel debugging capability.
Setup
pip install eventsourcing eventsourcing-django
Enable:
> aisetup/config mybot set eventsourcing_enabled true
Event Types
- ToolExecuted
- GoalCreated, GoalUpdated, GoalCompleted
- ReflectionRecorded
- EmergencyStopTriggered, EmergencyStopCleared
- TickCompleted
- ConfigurationChanged
Audit Commands
> aiaudit mybot # Stats summary
> aiaudit/events mybot=20 # Last 20 events
> aiaudit/replay mybot = 50 # View state at version 50
> aiaudit/tools mybot # Tool usage statistics
Archiving
> aiaudit/clear mybot = confirm
This archives events to server/archives/ai_events/ and starts fresh.
Further Reading
- Architecture-Event-Sourcing - Aggregate design, event replay
7. Resilience Patterns
Built-in resilience for production deployments.
Circuit Breaker
The circuit breaker prevents cascading failures when LLM providers are down.
States:
- CLOSED: Normal operation
- OPEN: Service failing, reject immediately (fail fast)
- HALF_OPEN: Testing recovery with limited requests
Configuration:
# In code (advanced)
from evennia.contrib.base_systems.ai.resilience import CircuitBreaker, CircuitBreakerConfig
config = CircuitBreakerConfig(
failure_threshold=5, # Failures to trip OPEN
success_threshold=2, # Successes to close from HALF_OPEN
timeout_seconds=60.0, # Time before HALF_OPEN test
)
Error Classification
Errors are classified for appropriate handling:
| Category | Retry? | Circuit Breaker? | Examples |
|---|---|---|---|
| AUTH | No | No | 401, 403 |
| TRANSIENT | Yes | Yes | 429, 500, 502, 503, 504, timeouts |
| BUSINESS_LOGIC | No | No | 400, 404, validation errors |
Retry Configuration
> aisetup/config mybot set-extra max_retries 5
Default: 3 attempts with exponential backoff and jitter.
Further Reading
- Architecture-Resilience-System - Circuit breaker, error classification
8. Performance Tuning
Token Budget Optimization
Reduce context size:
> aisetup/config mybot set max_history 30
> aisetup/config mybot set max_context_tokens 50000
Aggressive compaction:
> aisetup/config mybot set compact_sleep_threshold 0.6
> aisetup/config mybot set compact_preserve_window 15
Tick Rate Tradeoffs
| Tick Rate | API Calls/Hour | Best For |
|---|---|---|
| 5s | 720 | Interactive testing |
| 15s | 240 | Normal operation |
| 30s | 120 | Cost-conscious |
| 60s | 60 | Background tasks |
Multi-Action Loop Limits
More iterations = more API calls but fewer ticks needed:
> aisetup/config mybot set max_iterations_per_tick 3
Model Selection
| Model | Speed | Cost | Capability |
|---|---|---|---|
| gpt-4o-mini | Fast | Low | Good for most tasks |
| gpt-4o | Medium | Medium | Strong reasoning |
| claude-3-haiku | Very fast | Low | Simple tasks |
| claude-3.5-sonnet | Medium | Medium | Complex tasks |
Further Reading
- Architecture-Token-Management - Token counting, budget analysis
Architecture Reference
For deep technical understanding, see:
| Topic | Document |
|---|---|
| System overview | Architecture-Overview |
| Core engine | Architecture-Core-Engine |
| Context types | Architecture-Context-System |
| Tool system | Architecture-Tool-System |
| Memory/sleep | Architecture-Memory-and-Sleep |
| Prompt assembly | Architecture-Prompt-System |
| Self-management | Architecture-Self-Management |
Last updated: 2025-12-09