traceAI OTEL Tracing

Learn how to leverage traceAI OTEL tracing decorators and methods to instrument your functions, chains, agents, and tools with OpenTelemetry. These utilities complement or replace standard OpenTelemetry instrumentation code, making the process more straightforward and efficient.

Installation

Ensure you have FI Instrumentation Library installed:
pip install fi-instrumentation-otel

Setting Up Tracing

Initialize your tracing environment with the following setup:
from fi_instrumentation import register, FITracer
from fi_instrumentation.fi_types import ProjectType

# Setup OTel via our register function
trace_provider = register(
    project_type=ProjectType.EXPERIMENT,
    project_name="FUTURE_AGI",
    project_version_name="openai-exp",
)

tracer = FITracer(trace_provider.get_tracer(__name__))

Using your Tracer

The tracer object provides two main approaches for instrumentation:

1. Function Decoration

Use decorators to trace complete functions:
Python
@tracer.chain
def my_func(input: str) -> str:
    return "output"
When using this method, the entire function execution will be visible as a Span in Future AGI. Function parameters and return values automatically populate input and output attributes, while the status is set automatically.

2. Code Block Tracing

Utilize context managers to trace specific code segments:
Python
from opentelemetry.trace.status import Status, StatusCode

with tracer.start_as_current_span(
    "my-span-name",
    fi_span_kind="chain",
) as span:
    span.set_input("input")
    span.set_output("output")
    span.set_status(Status(StatusCode.OK))
The code within this clause will be captured as a Span in Future AGI. Here the input, output, and status must be set manually. This method is particularly useful when you need to monitor specific portions of your code rather than entire functions.

FI Span Kinds

FI Span Kinds denote the possible types of spans you might capture, and will be rendered different in the Future AGI UI. The possible values are:
Span KindUse
CHAINGeneral logic operations, functions, or code blocks
LLMMaking LLM calls
TOOLCompleting tool calls
RETRIEVERRetrieving documents
EMBEDDINGGenerating embeddings
AGENTAgent invocations - typically a top level or near top level span
RERANKERReranking retrieved context
UNKNOWNUnknown
GUARDRAILGuardrail checks
EVALUATOREvaluators

Chains

Using Context Managers

from opentelemetry.trace.status import Status, StatusCode

with tracer.start_as_current_span(
    "my-span-name",
    fi_span_kind="chain",
) as span:
    span.set_input("input")
    span.set_output("output")
    span.set_status(Status(StatusCode.OK))

Using Decorators

Python
@tracer.chain
def decorated_chain_with_plain_text_output(input: str) -> str:
    return "output"

decorated_chain_with_plain_text_output("input")

Using JSON Output

Python
@tracer.chain
def decorated_chain_with_json_output(input: str) -> Dict[str, Any]:
    return {"output": "output"}

decorated_chain_with_json_output("input")

Overriding Span Name

Python
@tracer.chain(name="decorated-chain-with-overriden-name")
def this_name_should_be_overriden(input: str) -> Dict[str, Any]:
    return {"output": "output"}

this_name_should_be_overriden("input")

Agents

Using Context Managers

with tracer.start_as_current_span(
    "agent-span-with-plain-text-io",
    fi_span_kind="agent",
) as span:
    span.set_input("input")
    span.set_output("output")
    span.set_status(Status(StatusCode.OK))

Using Decorators

Python
@tracer.agent
def decorated_agent(input: str) -> str:
    return "output"

decorated_agent("input")

Tools

Using Context Managers

with tracer.start_as_current_span(
    "tool-span",
    fi_span_kind="tool",
) as span:
    span.set_input("input")
    span.set_output("output")
    span.set_tool(
        name="tool-name",
        description="tool-description",
        parameters={"input": "input"},
    )
    span.set_status(Status(StatusCode.OK))

Using Decorators

Python
@tracer.tool(
    name="tool-name",
    description="tool-description",
    parameters={"input": "input"},
)
def decorated_tool(input: str) -> str:
    return "output"

decorated_tool("input")

LLM

Using Context Managers

with tracer.start_as_current_span(
    "llm-span",
    fi_span_kind="llm",
) as span:
    span.set_input("input")
    span.set_output("output")
    span.set_status(Status(StatusCode.OK))

Using Decorators

Python
@tracer.llm
def decorated_llm(input: str) -> str:
    return "output"

decorated_llm("input")

Retriever

Using Context Managers

with tracer.start_as_current_span(
    "retriever-span",
    fi_span_kind="retriever",
) as span:
    span.set_input("input")
    span.set_output("output")
    span.set_status(Status(StatusCode.OK))

Using Decorators

Python
@tracer.retriever
def decorated_retriever(input: str) -> str:
    return "output"

decorated_retriever("input")