LlamaIndex (tracing)
LlamaIndex is a framework for building LLM applications with your own data. The existing respan-instrumentation-llama-index package traces both LlamaIndex Core and the standalone llama-index-workflows runtime, including workflow runs and steps, indexes, query engines, retrievers, LLM calls, embeddings, and agent tool use.
Set up Respan
Create an account at platform.respan.ai and grab an API key .
Paste this into your coding agent:
Help me set up Respan tracing with the LlamaIndex integration.
Follow https://www.respan.ai/docs/integrations/llama-index.mdSetup
Install packages
pip install respan-ai respan-instrumentation-llama-index llama-index llama-index-workflows llama-index-llms-openai llama-index-embeddings-openaiSet environment variables
export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"OPENAI_API_KEY is used for the LlamaIndex OpenAI LLM. RESPAN_API_KEY exports traces to Respan.
Initialize and run
import asyncio
from workflows import Workflow, step
from workflows.events import Event, StartEvent, StopEvent
from respan import Respan
from respan_instrumentation_llama_index import LlamaIndexInstrumentor
respan = Respan(instrumentations=[LlamaIndexInstrumentor()])
class DraftEvent(Event):
text: str
class DocsWorkflow(Workflow):
@step
async def draft(self, event: StartEvent) -> DraftEvent:
return DraftEvent(text=f"Draft a note about {event.topic}.")
@step
async def finalize(self, event: DraftEvent) -> StopEvent:
return StopEvent(result=f"{event.text} Respan traced both steps.")
async def main():
result = await DocsWorkflow().run(topic="LlamaIndex Workflows")
print(result)
asyncio.run(main())View your trace
Open the Traces page to see a workflow root with nested step spans. LlamaIndex Core operations appear in the same trace tree when a workflow step invokes a query engine, retriever, LLM, embedding model, agent, or tool.
Configuration
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key | str | None | None | Falls back to RESPAN_API_KEY env var. |
base_url | str | None | None | Falls back to RESPAN_BASE_URL env var. |
instrumentations | list | [] | Plugin instrumentations to activate, for example LlamaIndexInstrumentor(). |
customer_identifier | str | None | None | Default customer identifier for all spans. |
metadata | dict | None | None | Default metadata attached to all spans. |
environment | str | None | None | Environment tag, for example "production". |
capture_content | bool | True | LlamaIndexInstrumentor option. Set to False to omit workflow inputs/results, prompts, responses, document content, and embedding vectors. |
Attributes
In Respan()
Set defaults at initialization. These apply to all spans emitted by the LlamaIndex instrumentor.
from respan import Respan
from respan_instrumentation_llama_index import LlamaIndexInstrumentor
respan = Respan(
instrumentations=[LlamaIndexInstrumentor()],
customer_identifier="user_123",
metadata={"service": "rag-api", "version": "1.0.0"},
)With propagate_attributes
Override per request using a context scope.
from llama_index.core import Document, SummaryIndex
from respan import Respan, propagate_attributes, workflow
from respan_instrumentation_llama_index import LlamaIndexInstrumentor
respan = Respan(instrumentations=[LlamaIndexInstrumentor()])
@workflow(name="rag_request")
def run_query(question: str):
index = SummaryIndex.from_documents([
Document(text="Respan captures traces from LlamaIndex applications.")
])
return index.as_query_engine().query(question)
def handle_request(user_id: str, question: str):
with propagate_attributes(
customer_identifier=user_id,
thread_identifier="conv_abc_123",
metadata={"plan": "pro"},
):
response = run_query(question)
print(response)| Attribute | Type | Description |
|---|---|---|
customer_identifier | str | Identifies the end user in Respan analytics. |
thread_identifier | str | Groups related messages into a conversation. |
metadata | dict | Custom key-value pairs. Merged with default metadata. |
Decorators (optional)
Respan decorators are not required for LlamaIndex instrumentation. Core query engines, retrievers, agents, tools, embeddings, and LLM calls are captured automatically. Standalone Workflows runs and @step methods also emit their own workflow and task spans. Use Respan @workflow and @task only when you want an additional application-level grouping around several operations.
from llama_index.core import Document, SummaryIndex
from respan import Respan, task, workflow
from respan_instrumentation_llama_index import LlamaIndexInstrumentor
respan = Respan(instrumentations=[LlamaIndexInstrumentor()])
@task(name="build_index")
def build_index():
return SummaryIndex.from_documents([
Document(text="Respan traces LlamaIndex index and query operations."),
Document(text="LlamaIndex combines retrievers, query engines, and agents."),
])
@workflow(name="rag_pipeline")
def rag_pipeline(question: str):
index = build_index()
return index.as_query_engine().query(question)
print(rag_pipeline("Summarize the documents."))
respan.flush()Examples
Query engine
Query engines are captured with nested retriever, synthesizer, and LLM spans.
from llama_index.core import Document, SummaryIndex
index = SummaryIndex.from_documents([
Document(text="Respan captures traces for LLM calls and workflow steps."),
Document(text="LlamaIndex can combine query engines, retrievers, and tools."),
])
query_engine = index.as_query_engine()
response = query_engine.query("What do the documents say?")
print(response)Embeddings
Embedding calls are captured as embedding logs. When content capture is enabled, the full returned vector is recorded in the canonical entity output so retrieval behavior can be reproduced and inspected.
from llama_index.embeddings.openai import OpenAIEmbedding
embedding_model = OpenAIEmbedding(model="text-embedding-3-small")
embedding = embedding_model.get_text_embedding(
"LlamaIndex uses embeddings to retrieve relevant document chunks."
)
print(len(embedding))Tool-use agent
LlamaIndex ReAct agents emit agent, tool, and LLM spans in the same trace tree.
import asyncio
from llama_index.core.agent.workflow import ReActAgent
from llama_index.core.tools import FunctionTool
def multiply_numbers(a: int, b: int) -> int:
return a * b
multiply_tool = FunctionTool.from_defaults(
fn=multiply_numbers,
name="multiply_numbers",
description="Multiply two integers and return the product.",
)
agent = ReActAgent(
tools=[multiply_tool],
system_prompt="Use tools when arithmetic is required.",
streaming=False,
)
async def main():
response = await agent.run(
user_msg="Use the multiply_numbers tool to calculate 7 multiplied by 6."
)
print(response)
asyncio.run(main())Gateway
See LlamaIndex gateway setup to route this integration through the Respan gateway.