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]

Edit this page on GitHub