Executable programs and extensions
Last updated
Find slow steps in a local agent with Langfuse
Break one response's time into model, retrieval, and tool steps to decide where to investigate.
Langfuse displays trace events that an application explicitly sends. With a local instance and Python SDK v4, point the API1 base URL at that instance and instrument function calls with @observe. Installing Langfuse does not automatically trace arbitrary Ollama requests. Instrumented inputs and outputs can contain personal or document data, so choose recorded fields deliberately and mask sensitive values.
Use Langfuse to see which part of a local agent takes time: model calls, file reads, or tools. Python SDK trace events show the start, end, and duration of each step. The example traces a local Ollama request and a synthetic file read without storing prompt2 or response content.
Break end-to-end latency into processing steps
A slow agent does not always mean slow token3 generation. Retrieval, file reads, tool waits, retries, and response generation can all contribute. Recording each step in a Langfuse trace lets you compare which segment grew for the same test input.

Start the local instance and prepare SDK instrumentation
In the repository root's docker-compose.yml, replace every value marked # CHANGEME. Restrict the web service's ports to 127.0.0.1:3000:3000 and set NEXTAUTH_URL to http://localhost:3000. Run docker compose up -d and docker compose ps, then confirm the port shows 127.0.0.1:3000->3000/tcp.
When Ready appears in docker compose logs -f langfuse-web, open http://localhost:3000 in a browser. Create the first user on the signup screen, then generate public and secret keys under the project's Settings → API Keys.
git clone https://github.com/langfuse/langfuse.git langfuse-local
cd langfuse-local
# 저장소 루트 docker-compose.yml에서 # CHANGEME 값을 바꾸고 NEXTAUTH_URL을 맞춰요.ports:
- "127.0.0.1:3000:3000"docker compose up -d
docker compose ps
docker compose logs -f langfuse-web
Record model and tool steps with SDK v4
Install langfuse and requests, then set the project's public and secret API keys, LANGFUSE_BASE_URL=http://localhost:3000, and an already-installed Ollama model ID. @observe creates the parent request span; context managers from get_client() record Ollama generation and file-read tool observations beneath it. The sample omits input/output bodies and records only status and character count as metadata.
python -m venv .venv
source .venv/bin/activate
python -m pip install -U langfuse requests
export LANGFUSE_PUBLIC_KEY='pk-lf-project-key'
export LANGFUSE_SECRET_KEY='sk-lf-project-secret'
export LANGFUSE_BASE_URL='http://localhost:3000'
export OLLAMA_MODEL='YOUR_INSTALLED_MODEL_ID'After setting the environment variables, save the code below as run_trace.py. It calls Ollama once with a fixed prompt and reads a synthetic text file. The trace records duration and status for the two steps.
import os
from pathlib import Path
import requests
from langfuse import get_client, observe, propagate_attributes
MODEL = os.environ['OLLAMA_MODEL']
langfuse = get_client()
@observe(name='local-agent-request', as_type='span', capture_input=False, capture_output=False)
def run_trace():
with propagate_attributes(trace_name='local-agent-toy', session_id='toy-session-1'):
with langfuse.start_as_current_observation(as_type='generation', name='ollama-chat', model=MODEL) as generation:
response = requests.post('http://127.0.0.1:11434/api/chat', json={'model': MODEL, 'stream': False, 'messages': [{'role': 'user', 'content': 'Reply with exactly: local trace test'}]}, timeout=120)
response.raise_for_status()
generation.update(metadata={'http_status': response.status_code})
with langfuse.start_as_current_observation(as_type='tool', name='read-toy-file') as tool:
text = Path('fixture.txt').read_text(encoding='utf-8')
tool.update(metadata={'file': 'fixture.txt', 'characters': len(text)})
print('Ollama status:', response.status_code, '| fixture characters:', len(text))
run_trace()
langfuse.flush()printf '%s\n' 'Synthetic fixture for a local tracing example.' > fixture.txt && python run_trace.pyInspect a trace with a fixed, non-sensitive input
When local-agent-toy appears in Traces, open it and inspect the parent span, its ollama-chat generation and read-toy-file tool children, their durations, and recorded metadata.
For an initial 401/403, check that the public and secret keys came from the same project and that the API URL is http://localhost:3000. For a connection error, check service status and the PORTS value in docker compose ps; for Ollama, check curl http://127.0.0.1:11434/api/tags.
Only the synthetic prompt and fixture are used; document text and model output are not set as trace input/output.

Terminology notes
API — A defined interface that lets other code call a program’s functions.
Back to the textPrompt — The input text sent to a model. For generative models it describes the desired result and strongly shapes the output.
Back to the textToken — A unit into which a model divides input or output for processing.
Back to the text
Frequently asked questions
- What should you check first in this article?
- Langfuse displays trace events that an application explicitly sends. With a local instance and Python SDK v4, point the API base URL at that instance and instrument function calls with `@observe`. Installing Langfuse does not automatically trace arbitrary Ollama requests. Instrumented inputs and outputs can contain personal or document data, so choose recorded fields deliberately and mask sensitive values.
Read next
Executable programs and extensions
Local LLM·RAG quality evaluation: Verifying changed settings with DeepEval
Executable programs and extensions
Local AI Agent Security: Check Permissions, Network Paths, and Secrets
Executable programs and extensions
How to Back Up and Restore a Local LLM You Already Use
Executable programs and extensions
What Is LiLiCorr? Speculative decoding for Bolt and Super VL
