Skip to main content

LLM Tracing

Debug and understand your document extraction by capturing detailed traces of LLM interactions.

Overview​

LLM Tracing provides visibility into how your documents are processed, similar to tools like LangSmith but integrated directly into DocuDevs. When enabled, traces capture:

  • LLM Calls: Prompts sent to the model and responses received
  • Tool Calls: Any tool invocations (e.g., knowledge base searches)
  • Token Usage: Prompt, completion, and total token counts
  • Timing: Duration of each operation
  • Page Images: References to document page thumbnails shown to the LLM

Enabling Tracing​

Tracing is opt-in and must be enabled per request by setting trace=true.

from docudevs.docudevs_client import DocuDevsClient
import os

client = DocuDevsClient(token=os.getenv('API_KEY'))

# Enable tracing when processing a document
job_guid = await client.submit_and_process_document(
document=document_bytes,
document_mime_type="application/pdf",
prompt="Extract invoice data",
trace=True # Enable LLM tracing
)

# Wait for processing to complete
result = await client.wait_until_ready(job_guid)

# Retrieve the trace
trace = await client.get_trace(job_guid)
if trace:
print(f"Total tokens used: {trace['total_tokens']}")
print(f"LLM calls: {trace['total_llm_calls']}")
for event in trace['events']:
print(f" {event['type']}: {event['name']}")

Trace Data Structure​

A trace contains high-level summary information and a list of events:

{
"id": "trace-uuid",
"name": "Document Extraction",
"start_time": "2024-01-15T10:30:00Z",
"end_time": "2024-01-15T10:30:15Z",
"status": "completed",
"job_id": "job-guid",
"extraction_mode": "SIMPLE",
"llm_level": "DEFAULT",
"total_tokens": 4521,
"total_llm_calls": 2,
"total_tool_calls": 0,
"events": [...]
}

Event Types​

TypeDescription
llm_startLLM call initiated with prompt/messages
llm_endLLM call completed with response and token usage
tool_startTool invocation started
tool_endTool invocation completed
chain_startProcessing chain started
chain_endProcessing chain completed
errorError occurred during processing

LLM Event Details​

LLM events include detailed information:

{
"id": "event-uuid",
"type": "llm_end",
"name": "ChatOpenAI",
"timestamp": "2024-01-15T10:30:05Z",
"duration_ms": 2340,
"model": "gpt-4o",
"messages": [
{
"role": "system",
"content": "You are a document extraction assistant..."
},
{
"role": "user",
"content": [
{"type": "text", "text": "Extract the following..."},
{"type": "image", "image_ref": {"page_index": 0}}
]
}
],
"response": "Based on the document...",
"prompt_tokens": 1234,
"completion_tokens": 567,
"total_tokens": 1801
}

Retrieving Page Images​

Messages may contain image_ref objects referencing document pages. You can retrieve these images:

# Get a specific page thumbnail
image_bytes = await client.get_image(job_guid, page_index=0)
if image_bytes:
with open("page_0.png", "wb") as f:
f.write(image_bytes)

Map-Reduce Tracing​

For large documents processed with map-reduce, tracing captures all chunk processing:

job_guid = await client.submit_and_process_document_map_reduce(
document=large_document,
document_mime_type="application/pdf",
prompt="Extract line items",
pages_per_chunk=5,
trace=True # Traces all chunks
)

trace = await client.get_trace(job_guid)
print(f"Processed in {len(trace['events'])} events")

Best Practices​

When to Use Tracing​

  • Development: Always enable during prompt development
  • Debugging: When extraction results are unexpected
  • Optimization: To analyze token usage and identify improvements
  • Auditing: When you need a record of LLM interactions

When NOT to Use Tracing​

  • Production at Scale: Tracing adds storage overhead
  • Sensitive Data: Traces contain full prompts and responses
  • High-Volume Batch: Consider sampling instead

Performance Considerations​

  • Traces are stored in blob storage alongside job results
  • Enabling tracing has minimal impact on processing time
  • Storage size depends on document complexity and LLM verbosity

API Reference​

Get Trace​

GET /job/trace/{guid}

Returns the trace data for a job, or 404 if tracing was not enabled.

Get Page Image​

GET /job/image/{guid}/{pageIndex}

Returns a PNG thumbnail of the specified page (0-indexed).

SDK Methods​

get_trace​

async def get_trace(self, guid: str) -> dict | None:
"""Get the LLM trace for a job.

Returns:
The trace data as a dict, or None if no trace is available.
"""

get_image​

async def get_image(self, guid: str, page_index: int) -> bytes | None:
"""Get a page thumbnail image for a job.

Returns:
The image bytes (PNG), or None if not found.
"""