Concepts
Reasoning Traces (System 2 Memory)
Part of the expertise layer. Read the overview →
SmartMemory captures reasoning traces - the chain-of-thought process behind decisions, not just the final outcomes. This enables agents to learn from how problems were solved.
Why Reasoning Traces Matter
Traditional memory systems store:
- ✅ What was decided
- ❌ Why it was decided
With reasoning traces, SmartMemory stores both:
Input: "Fix the login bug"
Reasoning: Thought → Action → Observation → Decision → Conclusion
Output: "Added null check on line 42"Step Types
| Type | Description | Example |
|---|---|---|
thought | Internal reasoning | "I think the issue is in authentication" |
action | Action taken | "Let me search for the login function" |
observation | Result observed | "Found null pointer in token validation" |
decision | Decision point | "I will add a null check" |
conclusion | Final answer | "Fixed by adding validation" |
reflection | Meta-reasoning | "This approach worked because..." |
Extraction Modes
1. Explicit Markers
When text contains explicit markers, they are parsed directly:
Thought: I need to analyze this bug.
Action: Searching for the error pattern.
Observation: Found the issue in line 42.
Conclusion: Added null check to fix.2. Implicit Detection
For natural language without markers, the LLM detects reasoning patterns:
Let me think about this... First, I should check the logs.
The error shows a null pointer. This means we need validation.
Therefore, I'll add a null check before the call.Usage
Automatic Extraction
Reasoning extraction runs during ingest() when you opt in with the
extract_reasoning flag:
memory = SmartMemory()
# Traces are automatically extracted during ingestion
memory.ingest("Thought: Analyzing the bug...", extract_reasoning=True)Manual Extraction
from smartmemory.plugins.extractors.reasoning import ReasoningExtractor
extractor = ReasoningExtractor()
result = extractor.extract("""
Thought: The tests are failing on CI.
Action: Checking the test logs.
Observation: Missing environment variable.
Conclusion: Added the variable to CI config.
""")
trace = result['reasoning_trace']
print(f"Steps: {len(trace.steps)}")
print(f"Quality: {trace.evaluation.quality_score}")Quality Evaluation
Traces are evaluated before storage:
| Metric | Description | Threshold |
|---|---|---|
quality_score | Overall quality (0-1) | ≥ 0.4 to store |
has_loops | Repeated reasoning | Penalized |
has_redundancy | Similar steps | Penalized |
step_diversity | Variety of step types | Bonus |
if trace.evaluation.should_store:
# Quality passes threshold
memory.add(trace)Task Context
Each trace captures context for filtered retrieval:
trace.task_context = TaskContext(
goal="Fix authentication bug",
task_type="debugging", # code_generation, analysis, problem_solving
domain="python", # javascript, frontend, backend, database
complexity="medium" # low, medium, high
)Searching by Context
# Find similar debugging experiences
results = memory.search(
"authentication error",
memory_type="reasoning"
)Linking to Artifacts
Reasoning traces can be linked to resulting code/docs:
trace.artifact_ids = ["commit_abc123", "doc_readme_update"]This creates a CAUSES relationship in the knowledge graph.
Configuration
from smartmemory.plugins.extractors.reasoning import ReasoningExtractorConfig
config = ReasoningExtractorConfig(
min_quality_score=0.4, # Minimum quality to store
min_steps=2, # Minimum steps for valid trace
use_llm_detection=True, # Enable implicit detection
model_name="gpt-4o-mini" # LLM for detection
)
extractor = ReasoningExtractor(config=config)