Launch Week 02 wrapped — explore all five launches

Set Input/Output

Learn how to supply input and output of your LLM application in a trace

Overview

Both traces and spans have inputs and outputs, which you can set dynamically within your application using the update_current_span/updateCurrentSpan and update_current_trace/updateCurrentTrace function respectively.

Set Trace I/O

By default, the input and output of a trace is defaulted to the input arguments of the first span and the output of the last span you've wrapped/decorated. You can however override the input and output on spans at runtime.

main.py
from openai import OpenAI
from deepeval.tracing import observe, update_current_trace

client = OpenAI()

@observe()
def llm_app(query: str):
    res = client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": query}]
    ).choices[0].message.content

    update_current_trace(input=query, output=res)
    return res

llm_app("Write me a poem.")

The input and output can be ANY TYPE, and is useful for visualization on the UI (even more so if you're using conversation threads).

Set Span I/O

By default, the input and output of a span is defaulted to the input arguments and output of the function/method you're mapping. You can however override the input and output on spans at runtime.

main.py
from openai import OpenAI
from deepeval.tracing import observe, update_current_span

client = OpenAI()

@observe()
def llm_app(query: str):
    res = client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": query}]
    ).choices[0].message.content

    update_current_span(input=query, output=res)
    return res

llm_app("Write me a poem.")

This example is the same as the one for tracing except for the update_current_trace, and that's not a mistake. You can set input and outputs the same way as you do for traces, and if a trace's I/O is not set it defaults to the I/O of the root span.

The input and output can be ANY TYPE for custom span types, and is useful for visualization on the UI.

I/O for Streamed Responses

If your @observe-decorated function uses yield to stream its response, the trace output won't be captured automatically — the return value is a generator, not the final text. Collect the streamed chunks and set the output explicitly:

main.py
from deepeval.tracing import observe, update_current_trace

@observe()
def stream_response(query: str):
    chunks = []
    for chunk in llm.stream(query):
        chunks.append(chunk)
        yield chunk

    update_current_trace(input=query, output="".join(chunks))

Without this, the trace will appear on Confident AI with no output. See the troubleshooting page for more details.

I/O for Threads

For multu-turn AI apps that create a thread from the traces, it is highly recommended that you provide the strings instead, where the input will represent the user input, and output representing the AI generated output. You can also leave out any input or output for consecutive user/LLM behaviors.

You will also need the input and output to run online evaluations on a thread, as these will be used as the turns for a conversational test case.

Next Steps

With your trace and span I/O configured, connect traces into conversations or start evaluating them.

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

Last updated on

Built byConfident AI