Three independent systems: Profile (passive learning), Recall (active search), History Window (cost control).
Passive user preference learning triggered every N messages.
agent = Agent(llm="openai", profile=True)
async for event in agent("query", user_id="alice"):
...How it works:
- Every 5 user messages, LLM analyzes conversation
- Generates/updates JSON profile with user patterns
- Profile prepended to system prompt on next turn
- Fire-and-forget async—doesn't block conversation
Profile format:
{
"who": "senior backend engineer",
"style": "direct, technical",
"focus": "distributed systems",
"interests": "Rust, Go, performance",
"misc": "likes cats, morning person",
"_meta": {"last_learned_at": 1699564800.0, "messages_processed": 10}
}Human-readable, transparent, deletable.
Active agent-initiated search across conversation history.
agent = Agent(llm="openai", tools=tools()) # Recall included by defaultHow it works:
- Agent calls
recall(query="python debugging")when needed - SQLite fuzzy search (no embeddings)
- Returns top 3 cross-conversation matches
- Excludes current conversation
Why SQLite not embeddings:
- No vector DB infrastructure
- Transparent & queryable
- No embedding latency/cost
- 80% semantic value at 20% complexity
Cost control for Replay mode. Sliding window on conversation history.
agent = Agent(llm="openai", mode="replay", history_window=20)| Session | No Window | Window=20 | Savings |
|---|---|---|---|
| 50 turns | ~15k tokens | ~6k tokens | 60% |
| 100 turns | ~50k tokens | ~6k tokens | 88% |
When to use:
- Long sessions in Replay mode →
history_window=20 - Resume mode →
history_window=None(full history is cheap)
| System | Type | Trigger | Purpose |
|---|---|---|---|
| Profile | Passive | Every N messages | Ambient preferences |
| Recall | Active | Agent decides | Past interaction search |
| History Window | Cost control | Always | Limit context size |
# Full-featured
agent = Agent(
llm="openai",
mode="resume",
profile=True,
tools=tools(),
)
# user_id passed per-call: agent("query", user_id="alice")
# Cost-optimized
agent = Agent(
llm="openai",
mode="replay",
history_window=10,
)
# Stateless
agent = Agent(llm="openai") # No user_id → ephemeralfrom cogency.context import profile
current = await profile.get(user_id, storage=storage)
formatted = await profile.format(user_id, storage=storage)
learned = await profile.learn_async(user_id, storage=storage, llm=llm)