Haystack (tracing)

Haystack is a Python framework for building production-ready LLM pipelines with retrieval, generation, routing, and evaluation components. Respan traces Haystack runs with respan-instrumentation-haystack, which activates the OpenInference Haystack instrumentor and exports pipeline, component, and LLM spans through the Respan tracing pipeline.

Create an account at platform.respan.ai and grab an API key.

Run npx @respan/cli setup to set up with your coding agent.

See Haystack gateway setup to route this integration through the Respan gateway.

Setup

1

Install packages

$pip install respan-ai respan-instrumentation-haystack haystack-ai
2

Set environment variables

$export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
$export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
$export HAYSTACK_CONTENT_TRACING_ENABLED="true"

OPENAI_API_KEY is used by Haystack’s OpenAI component. RESPAN_API_KEY exports traces to Respan. HAYSTACK_CONTENT_TRACING_ENABLED lets Haystack include prompt and response content in spans.

3

Initialize and run

1from haystack import Pipeline
2from haystack.components.builders import PromptBuilder
3from haystack.components.generators import OpenAIGenerator
4from respan import Respan
5from respan_instrumentation_haystack import HaystackInstrumentor
6
7respan = Respan(instrumentations=[HaystackInstrumentor()])
8
9pipeline = Pipeline()
10pipeline.add_component(
11 "prompt_builder",
12 PromptBuilder(template="Answer the following question: {{question}}"),
13)
14pipeline.add_component("generator", OpenAIGenerator(model="gpt-4o-mini"))
15pipeline.connect("prompt_builder", "generator")
16
17result = pipeline.run(
18 {"prompt_builder": {"question": "What is the capital of France?"}}
19)
20print(result["generator"]["replies"][0])
21
22respan.flush()
4

View your trace

Open the Traces page to see your pipeline run with pipeline spans, component spans, LLM calls, and inputs/outputs.

Configuration

ParameterTypeDefaultDescription
api_keystr | NoneNoneFalls back to RESPAN_API_KEY env var.
base_urlstr | NoneNoneFalls back to RESPAN_BASE_URL env var.
instrumentationslist[]Plugin instrumentations to activate, such as HaystackInstrumentor().
customer_identifierstr | NoneNoneDefault customer identifier for all spans.
metadatadict | NoneNoneDefault metadata attached to all spans.
environmentstr | NoneNoneEnvironment tag, such as "production".

HaystackInstrumentor(**kwargs) passes keyword arguments through to the underlying OpenInference Haystack instrumentor.

Attributes

In Respan()

Set defaults at initialization. These apply to all spans.

1from respan import Respan
2from respan_instrumentation_haystack import HaystackInstrumentor
3
4respan = Respan(
5 instrumentations=[HaystackInstrumentor()],
6 customer_identifier="user_123",
7 metadata={"service": "rag-api", "version": "1.0.0"},
8)

With propagate_attributes

Override per-request using a context scope.

1from respan import propagate_attributes
2
3with propagate_attributes(
4 customer_identifier="user_123",
5 thread_identifier="conversation_abc",
6 metadata={"plan": "pro"},
7):
8 result = pipeline.run(
9 {"prompt_builder": {"question": "What is retrieval-augmented generation?"}}
10 )
11 print(result["generator"]["replies"][0])
AttributeTypeDescription
customer_identifierstrIdentifies the end user in Respan analytics.
thread_identifierstrGroups related messages into a conversation.
metadatadictCustom key-value pairs. Merged with default metadata.

Decorators (optional)

Decorators are not required. Pipeline runs, components, and LLM calls are auto-traced by the instrumentor. Use @workflow and @task when you want to group multiple Haystack runs or add application-level steps around a pipeline.

1from respan import Respan, task, workflow
2from respan_instrumentation_haystack import HaystackInstrumentor
3
4respan = Respan(instrumentations=[HaystackInstrumentor()])
5
6@task(name="answer_question")
7def answer_question(question: str) -> str:
8 result = pipeline.run({"prompt_builder": {"question": question}})
9 return result["generator"]["replies"][0]
10
11@workflow(name="haystack_qa")
12def haystack_qa(question: str) -> str:
13 return answer_question(question)
14
15print(haystack_qa("What is the capital of France?"))
16respan.flush()

Examples

RAG pipeline

Retrieval and generation components are captured as separate spans.

1from haystack import Document, Pipeline
2from haystack.components.builders import PromptBuilder
3from haystack.components.generators import OpenAIGenerator
4from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
5from haystack.document_stores.in_memory import InMemoryDocumentStore
6
7document_store = InMemoryDocumentStore()
8document_store.write_documents(
9 [
10 Document(content="Python was created by Guido van Rossum."),
11 Document(content="Rust is focused on safety and performance."),
12 ]
13)
14
15template = """
16Documents:
17{% for document in documents %}
18- {{ document.content }}
19{% endfor %}
20
21Question: {{question}}
22Answer:
23"""
24
25pipeline = Pipeline()
26pipeline.add_component("retriever", InMemoryBM25Retriever(document_store=document_store))
27pipeline.add_component("prompt_builder", PromptBuilder(template=template))
28pipeline.add_component("generator", OpenAIGenerator(model="gpt-4o-mini"))
29pipeline.connect("retriever.documents", "prompt_builder.documents")
30pipeline.connect("prompt_builder", "generator")
31
32result = pipeline.run(
33 {
34 "retriever": {"query": "Who created Python?"},
35 "prompt_builder": {"question": "Who created Python?"},
36 }
37)
38print(result["generator"]["replies"][0])