Trace Recording & Test Generation
Record every tool call and auto-generate pytest tests from production traces.
Recording Traces
Enable trace recording to capture every tool call — arguments, results, timing, errors, and guard decisions. The production default is a SQLite trace store, while JSONL remains available for import/export and replay workflows.
python
from agentguard import guard
@guard(record=True, trace_backend="sqlite", trace_dir="./traces", session_id="session-001")
def search(query: str) -> dict:
return api.search(query)
# Every call to search() now produces a trace entry in ./traces/agentguard_traces.db
result = search("climate change papers")
Trace File Format
When you export traces to JSONL, each line in the file is a complete trace record:
json
{{
"timestamp": "2025-01-15T10:30:45.123Z",
"session_id": "session-001",
"tool_name": "search",
"call_id": "c8f2a1b3",
"args": {{"query": "climate change papers"}},
"result": {{"papers": [...], "total": 42}},
"elapsed_ms": 234.5,
"guards": {{
"input_valid": true,
"output_valid": true,
"hallucination_score": 0.05,
"retries": 0
}},
"error": null
}}
Console Reporter
Get a real-time summary of guard activity:
python
from agentguard import guard
from agentguard.reporting import ConsoleReporter
reporter = ConsoleReporter(verbose=True)
@guard(record=True, reporter=reporter)
def my_tool(x: str) -> str:
return x.upper()
# Output:
# [agentguard] my_tool("hello") → "HELLO" (12.3ms) ✓
# [agentguard] my_tool(123) → ValidationError: expected str ✗
Auto Test Generation
Generate pytest tests directly from production traces. Record real interactions, then replay them as regression tests.
python
from agentguard.testing import TestGenerator
generator = TestGenerator(traces_dir="./traces", backend="sqlite")
generator.generate_tests(
output="./tests/test_tools_generated.py",
session_id="session-001",
)
This produces test files like:
python
# Auto-generated by agentguard from SQLite-backed or exported traces
import pytest
from your_module import search
class TestSearch:
def test_search_climate_change_papers(self):
result = search("climate change papers")
assert isinstance(result, dict)
assert "papers" in result
assert "total" in result
def test_search_empty_query(self):
with pytest.raises(ValidationError):
search("")
bash
# Or use the CLI
agentguard generate ./traces --output ./tests/test_tools_generated.py
agentguard generate ./traces --backend sqlite --session session-001 --output ./tests/test_tools_generated.py
agentguard traces serve ./traces --port 8765
JSON Reports
python
from agentguard.core.trace import TraceStore
from agentguard.reporting.json_report import JsonReporter
store = TraceStore(directory="./traces", backend="sqlite")
report = JsonReporter(store).generate()
print(report["summary"]["total_calls"])
print(report["summary"]["success_rate"])
# Export as JSON
JsonReporter(store).save("./reports/daily-2025-01-15.json")
OpenTelemetry
Export traces to any OpenTelemetry-compatible backend (Jaeger, Zipkin, Datadog, etc.):
python
from agentguard import guard
from agentguard.integrations.otel import configure_otel
# Configure OpenTelemetry export
configure_otel(
service_name="my-agent",
endpoint="http://localhost:4317", # OTLP endpoint
export_format="grpc", # or "http"
)
# All guarded tools automatically emit OTel spans
@guard(validate_input=True, detect_hallucination=True)
def search(query: str) -> dict:
return api.search(query)
💡 Install the OTel extra
OpenTelemetry support requires the otel extra: pip install awesome-agentguard[otel]