Langflow (tracing)

Langflow is a visual framework by DataStax for building multi-agent and RAG applications. It provides a drag-and-drop interface for composing LLM pipelines with components for models, prompts, tools, and data sources. Langflow is built on LangChain, so Respan tracing uses respan-instrumentation-langchain to capture component runs, underlying LangChain calls, tools, retrievers, and LLM generations — and gateway routing through the OpenAI-compatible Respan endpoint.

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 Langflow gateway setup to route this integration through the Respan gateway.

Setup

1

Install packages

pip install respan-ai respan-instrumentation-langchain langflow langchain langchain-openai python-dotenv
2

Set environment variables

export RESPAN_API_KEY="YOUR_RESPAN_API_KEY"
export RESPAN_BASE_URL="https://api.respan.ai/api"

RESPAN_API_KEY is used to export traces to Respan. Set OPENAI_API_KEY too when your Langflow components call provider-backed models.

3

Initialize and run

Pass LangChainInstrumentor() to Respan(instrumentations=[...]). Langflow is built on LangChain, so in Python component runs are traced automatically. Reuse one callback handler when you want independent component runs grouped into a single trace.

There are two ways to run Langflow with tracing: run custom-component code directly (as below), or run a flow you built in the Langflow UI. A UI flow must be exported first (Share → Export) to a flow.json before run_flow_from_json can load it — this quickstart ships no standalone flow file, so the runnable example uses component code directly.

from langchain_core.runnables import RunnableLambda
from respan import Respan
from respan_instrumentation_langchain import (
LangChainInstrumentor,
add_respan_callback,
get_callback_handler,
)
# Activates global instrumentation. Component runs are captured automatically;
# the shared handler groups independent component root runs into one trace.
respan = Respan(instrumentations=[LangChainInstrumentor()])
handler = get_callback_handler()
def langflow_config(name: str):
return add_respan_callback(
{
"run_name": name,
"tags": ["respan-langchain-example", "langflow", name],
"metadata": {
"example": name,
"framework": "langflow",
"langflow_component": "RoutingComponent",
},
},
handler,
)
route_department = RunnableLambda(
lambda input: f"{input['department']}-workspace"
)
get_weather = RunnableLambda(
lambda input: f"It is sunny in {input['city']}."
)
route = route_department.invoke(
{"department": "security"},
config=langflow_config("langflow_route_department"),
)
weather = get_weather.invoke(
{"city": "Dublin"},
config=langflow_config("langflow_get_weather"),
)
print(f"{route}: {weather}")
4

View your trace

Open the Traces page to see your Langflow workflow with component-level operations, LLM calls, retriever spans, and tool calls.

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, e.g. LangChainInstrumentor().
group_langflow_root_runsboolTrue via get_callback_handler()Groups independent Langflow component root runs into one trace.
include_contentboolTrueIncludes component inputs and outputs on spans.
include_metadataboolTrueIncludes Langflow tags, metadata, and serialized runnable details.
customer_identifierstr | NoneNoneDefault customer identifier for all spans.
metadatadict | NoneNoneDefault metadata attached to all spans.
environmentstr | NoneNoneEnvironment tag, e.g. "production".

Attributes

In Respan()

Set defaults at initialization — these apply to all spans.

from respan import Respan
from respan_instrumentation_langchain import LangChainInstrumentor
respan = Respan(
instrumentations=[LangChainInstrumentor()],
customer_identifier="user_123",
metadata={"service": "langflow-api", "version": "1.0.0"},
)

With propagate_attributes

Override per-request using a context scope.

from langflow.load import run_flow_from_json
from respan import propagate_attributes
def handle_request(user_id: str, question: str):
with propagate_attributes(
customer_identifier=user_id,
thread_identifier="conv_abc_123",
metadata={"plan": "pro"},
):
result = run_flow_from_json(flow="flow.json", input_value=question)
print(result)
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. Langflow runs are traced through LangChain callbacks. Use @workflow and @task (Python) or withWorkflow and withTask (TypeScript) when you want to group one or more flow executions inside a named application workflow.

from respan import workflow, task
@task(name="run_langflow_flow")
def run_langflow_flow(question: str):
return run_flow_from_json(flow="flow.json", input_value=question)
@workflow(name="langflow_request")
def pipeline(question: str):
print(run_langflow_flow(question))
pipeline("What is the meaning of life?")

Examples

Custom component callback grouping

Use one callback handler for the component invocation so multiple LangChain calls in the same custom component share a trace.

from respan_instrumentation_langchain import add_respan_callback, get_callback_handler
handler = get_callback_handler()
config = add_respan_callback(
{
"run_name": "langflow_component",
"tags": ["langflow", "custom-component"],
"metadata": {
"framework": "langflow",
"langflow_component": "RoutingComponent",
},
},
handler,
)
result = chain.invoke({"question": "Route this request"}, config=config)

Exported flows

Export the flow from the Langflow UI (Share → Export) to a flow.json first. Exported flows can then be run normally after Respan telemetry is initialized. For custom components inside the flow, pass add_respan_callback(...) when invoking LangChain runnables.

from langflow.load import run_flow_from_json
result = run_flow_from_json(
flow="path/to/your/flow.json",
input_value="Summarize this support request.",
)
print(result)