Self-Learning Agents
Sagewai agents can improve over time through five complementary mechanisms. Each mechanism is independent — enable only the ones you need. All five work without requiring an LLM for the learning operations themselves.
Prerequisites: Memory & RAG · Context Engine · Next: Directives
The Five Learning Mechanisms
1. Auto-Learn (MemoryBridge)
Set auto_learn=True on an agent and it will extract facts from conversations and store them in the Context Engine automatically. Extraction runs every N turns, controlled by learn_every_n_turns.
from sagewai import UniversalAgent
agent = UniversalAgent(
name="assistant",
model="gpt-4o",
auto_learn=True,
learn_every_n_turns=5, # Extract after every 5 turns
)
# After chatting, the agent remembers:
# - Decisions made ("we chose PostgreSQL")
# - User preferences ("I prefer Python")
# - Key events ("deadline is March 15th")
# - Action items ("TODO: set up CI pipeline")
The MemoryBridge receives conversation history and delegates to a FactExtractor. Three extractors are available:
| Extractor | Needs LLM? | Speed | Quality |
|---|---|---|---|
RuleBasedFactExtractor | No | Instant | Good for structured facts |
LLMFactExtractor | Yes | ~1–2s | Best for nuanced extraction |
HybridFactExtractor | Optional | Fast + enhanced | Rules first, LLM fills gaps |
RuleBasedFactExtractor uses pattern matching to detect decisions, preferences, events, and action items with no API calls. HybridFactExtractor runs rules first and optionally does an LLM pass for anything the rules missed.
2. Episodic Memory
Agents can record task executions — what they did, what worked, and what they learned — and retrieve those records when a similar task comes up later.
from sagewai.context import EpisodeStore, Episode, InMemoryVectorStore
episodes = EpisodeStore(vector_store=InMemoryVectorStore()) # vector store enables semantic retrieval
# After completing a task, store the episode
episode = Episode(
goal="Research competitor pricing",
context_used=["pricing-doc-chunk-1", "market-report-chunk-5"],
actions_taken=["searched context", "queried web", "compiled report"],
outcome="Generated 3-page pricing analysis",
success=True,
lessons=["Financial data older than 6 months is unreliable",
"Compare at least 3 competitors for credible analysis"],
)
await episodes.capture(episode)
# Next time a similar task comes up, retrieve relevant episodes
similar = await episodes.retrieve("analyze competitor pricing", top_k=3)
# Agent now has lessons learned from previous attempts
Episodes are stored with embeddings, so retrieval is semantic. An agent working on "pricing comparison" will find episodes tagged "competitor pricing analysis" even when the exact words differ.
3. Self-Correction (Exemplar Store)
When an agent makes a mistake and a correction is provided, SelfCorrectionStrategy stores the failure as an exemplar. On future tasks that resemble the failure, the exemplar is injected as a one-shot "don't do this, do this instead" guide.
from sagewai.core.self_correction import SelfCorrectionStrategy, FailureExemplar
# SelfCorrectionStrategy wraps any base strategy and automatically:
# 1. Detects output validation failures via OutputValidator
# 2. Stores the error + correction as a FailureExemplar
# 3. On similar future tasks, includes the exemplar as a 1-shot example
# 4. Prevents the same mistake from recurring (max_corrections configurable)
Failed attempts are not discarded. They become training signal that shapes future behavior without any manual intervention.
4. Knowledge Graph Building
Each conversation incrementally adds entities and relations to a structured knowledge graph stored in NebulaGraph (or an in-memory fallback).
from sagewai.intelligence import GLiNEREntityExtractor, HeuristicRelationExtractor
# Entity extraction (zero-shot, runs locally)
ner = GLiNEREntityExtractor(
labels=["person", "organization", "technology", "date"]
)
# Relation extraction (co-occurrence heuristic)
rel = HeuristicRelationExtractor()
# Process a conversation
entities = await ner.extract(text)
# [Entity("PostgreSQL", "technology", 0.95), Entity("Alice", "person", 0.91)]
relations = await rel.extract(text, entities)
# [RelationTriple("Alice", "uses", "PostgreSQL", confidence=0.87)]
The graph accumulates structure over time. Agents can traverse it to answer questions like "who works on what?" or "what technologies does team X use?" — queries that vector search alone cannot answer reliably.
5. Memory Consolidation
Over time, the memory store can accumulate duplicate or contradictory facts. MemoryConsolidator deduplicates by similarity, applies time-based decay, and flags contradictions for review.
from sagewai.intelligence import MemoryConsolidator
consolidator = MemoryConsolidator(
embedder=embedder,
similarity_threshold=0.9, # Merge facts >90% similar
decay_rate=0.01, # 1% decay per day
)
# Dedup: "We use PostgreSQL" and "Our DB is PostgreSQL" -> merged
result = await consolidator.deduplicate_facts(all_facts)
# Decay: old facts lose importance, recent facts stay strong
weighted = consolidator.apply_decay(facts, ages_days=[0, 7, 30, 90])
# Contradictions: "We use MySQL" vs "We migrated to PostgreSQL" -> flagged
contradictions = await consolidator.detect_contradictions(
new_facts, existing_facts
)
On NebulaGraph, superseded facts — such as a technology migration — are marked with valid_from and superseded_at timestamps rather than deleted. History is preserved; relevance scoring adjusts automatically.
LLM-Independent Learning
Every component in the learning pipeline has a local fallback. Your agents can learn without any external API:
| Component | LLM Required? | Offline Alternative |
|---|---|---|
| Fact extraction | No | RuleBasedFactExtractor (regex patterns) |
| Entity extraction | No | GLiNEREntityExtractor (50 MB local model) |
| Embeddings | No | SentenceTransformerEmbedder (80 MB local model) |
| Relation extraction | No | HeuristicRelationExtractor (co-occurrence) |
| Graph building | No | Uses the extractors above |
| Memory consolidation | No | MemoryConsolidator (cosine similarity) |
| Summarization | No | SemanticSummarizer (embedding-scored extractive) |
Install the intelligence extras to unlock offline learning:
pip install sagewai[intelligence]
Configuration
IntelligenceConfig controls which provider each component uses:
from sagewai.intelligence import IntelligenceConfig
config = IntelligenceConfig(
embedding_provider="auto", # local -> API -> hash fallback
extraction_provider="auto", # GLiNER -> LLM fallback
fact_extraction_provider="hybrid", # rules + optional LLM
summarizer_provider="semantic", # embedding-scored extractive
)
The "auto" setting tries local providers first, falls back to API-based providers if available, and uses deterministic fallbacks as a last resort. Agents keep working even without network access.
Observability
The learning pipeline emits events through the SDK's event system. Hook into on_memory_store, on_fact_extracted, and on_episode_stored for custom observability, or use the admin console:
- Context Engine dashboard — See stored documents and extracted facts
- Knowledge Graph explorer — Browse entities and their relations interactively
- Agent Runs — Track which memories were retrieved and used in each response
- Cost Analytics — Compare intelligence layer costs against LLM costs
How It All Fits Together
User Message
|
v
Agent receives message
|
+---> [Retrieve] Search context + episodes + graph
| |
| v
| Inject relevant memories into prompt
|
v
LLM generates response
|
+---> [Learn] MemoryBridge extracts facts (every N turns)
| |
| v
| Store facts + build graph + update episodes
|
v
Return response to user
The retrieve-then-learn cycle runs automatically when auto_learn=True. No additional code is needed beyond the agent constructor.
What's Next
- Context Engine — How documents and facts are stored and retrieved
- Memory and RAG — Vector store and graph store architecture
- Directives — Use
@memoryand@contextdirectives in prompts - Admin Panel — Monitor learning through the admin dashboard