Launch Week 3: Five days of launches

PDFs in Traces

Capture the PDFs sent to your models, and add documents to any trace or span

Overview

Confident AI captures the PDFs in your traces and displays each one as an embedded preview in a span's input or output, with a link to open the full document in a new tab. This is useful for document-heavy use cases, such as contract review, invoice extraction, or report summarization, where you need to see the exact document a model was given to judge its answer.

PDFs get onto a trace in two ways:

  1. Automatically, from the model calls recorded by a supported integration
  2. Manually, by adding Media at the span or trace level

Capture PDFs from Model Calls

If you're using a supported integration, you don't need to do anything extra. Send PDFs to your model the way your provider SDK expects them, and as long as init() has run, they're captured with the rest of the messages:

main.py
import base64
from pathlib import Path

from confident_trace import init, shutdown
from openai import OpenAI

init()
client = OpenAI()

document = base64.b64encode(Path("report.pdf").read_bytes()).decode()

try:
    response = client.chat.completions.create(
        model="gpt-4.1",
        messages=[{
            "role": "user",
            "content": [
                {"type": "text", "text": "Summarize this report."},
                {
                    "type": "file",
                    "file": {
                        "filename": "report.pdf",
                        "file_data": f"data:application/pdf;base64,{document}",
                    },
                },
            ],
        }],
    )
    print(response.choices[0].message.content)
finally:
    shutdown()

Here, the OpenAI integration records the file part on the LLM span, and the report is displayed as a preview in the span's input. Every other supported integration works the same way, so an Anthropic document block, a Gemini inline file, or a LangChain file content block is captured just like this. If you pass the PDF as a URL instead of inline data, the span records the URL as a reference.

Add PDFs to Traces & Spans

For PDFs that aren't part of a model call, such as a document your app loaded or a file a user uploaded, wrap the file in Media and add it at the span or trace level. A PDF can be a value on its own, or part of a string:

main.py
from confident_trace import Media, init, span, update_span, shutdown

init()

@span(type="tool")
def read_policy(path: str):
    policy = Media.from_file(path)
    update_span(input=policy)
    return "Refunds are accepted within 30 days of purchase."

try:
    read_policy("refund-policy.pdf")
finally:
    shutdown()

Here, the PDF becomes the span's input on its own, and the text the tool returns is captured as the span's output, so you can check the extracted text against the source document. To place a PDF inside a string instead, use it in an f-string, such as update_span(input=f"Summarize {policy}").

update_trace() takes PDFs the same way, if you'd rather put the document on the trace's input or output. To create a PDF from a URL, bytes, or base64 instead of a local file, see Create Media.

Next Steps

With PDFs in your traces, see how images and audio are captured.

Ready to monitor AI in production?Connect traces, alerts, dashboards, and evals in one production workflowBook a demo

Last updated on

Built byConfident AI