실행 프로그램과 확장
최종 업데이트
Langfuse로 로컬 에이전트의 지연 구간 찾기
응답 한 번에 걸린 시간을 모델·검색·도구 단계로 나누면 느린 구간을 고르기 쉬워요.
Langfuse는 애플리케이션이 명시적으로 전송한 추적 이벤트를 받아 관찰 화면에 보여 줘요. 로컬 인스턴스와 Python SDK v4를 쓰면 API1 주소를 그 인스턴스로 지정하고 @observe로 함수 호출을 기록할 수 있어요. Langfuse를 설치했다고 임의의 Ollama 요청이 자동으로 기록되지는 않아요. 계측한 입력·출력에 개인정보나 문서 내용이 포함될 수 있으므로 기록할 필드를 직접 고르고 민감한 값을 마스킹해요.
로컬 에이전트가 답하는 동안 모델 호출, 파일 읽기, 도구 실행 중 어디에서 오래 기다리는지 알고 싶을 때 Langfuse를 써요. Python SDK로 각 단계의 추적 이벤트를 보내면 화면에서 시작·종료 시각과 소요 시간을 볼 수 있어요. 아래 예제는 로컬 Ollama 요청과 합성 파일 읽기를 기록하고, 입력·출력 본문은 남기지 않아요.
전체 응답 시간을 처리 단계로 나눠요
에이전트가 느리다고 해서 모델 토큰2 생성이 항상 원인은 아니에요. 검색, 파일 읽기, 도구 대기, 재시도, 응답 출력이 차례로 이어질 수 있어요. Langfuse trace에 각 단계를 기록하면 같은 테스트 입력에서 어느 구간이 길어졌는지 확인할 수 있어요.

로컬 인스턴스를 띄우고 SDK 계측 환경을 준비해요
저장소 루트의 docker-compose.yml에서 # CHANGEME 표시가 붙은 값을 모두 바꿔요. 웹 서비스의 ports는 127.0.0.1:3000:3000으로 제한하고 NEXTAUTH_URL도 http://localhost:3000으로 맞춰요. docker compose up -d와 docker compose ps를 실행해 포트가 127.0.0.1:3000->3000/tcp인지 확인해요.
docker compose logs -f langfuse-web에 Ready가 나타나면 브라우저에서 http://localhost:3000을 열어요. 가입 화면에서 첫 사용자를 만들고, 프로젝트의 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
SDK v4로 모델 호출과 도구 단계를 기록해요
Python 환경에 langfuse와 requests를 설치해요. 프로젝트 API 키와 LANGFUSE_BASE_URL=http://localhost:3000, ollama list에서 확인한 모델 ID를 환경 변수로 지정해요. @observe가 요청의 부모 span을 만들고 get_client()가 Ollama generation과 파일 읽기 tool observation을 그 아래에 기록해요. 입력·출력 본문은 수집하지 않고 상태와 문자 수만 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'환경 변수를 준비한 뒤 아래 코드를 run_trace.py로 저장해요. 예제는 고정된 문장으로 Ollama를 한 번 호출하고 합성 텍스트 파일 하나를 읽어요. 추적 화면에는 두 작업의 소요 시간과 상태만 남겨요.
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.py민감하지 않은 고정 입력으로 trace를 읽어요
Trace 목록에 local-agent-toy가 보이면 열어 parent span 아래의 ollama-chat generation과 read-toy-file tool, 각 지연 시간과 기록한 메타데이터를 확인해요.
첫 오류가 401/403이면 공개·비밀 키가 같은 프로젝트에서 복사됐는지, API 주소가 http://localhost:3000인지 확인해요. 연결 오류면 서버 상태와 docker compose ps의 PORTS 값을 먼저 봐요. Ollama 오류면 curl http://127.0.0.1:11434/api/tags로 로컬 API 응답을 확인해요.
이 요청의 합성 프롬프트3와 파일만 보내며 문서 본문과 모델 응답은 추적에 입력·출력으로 넣지 않아요.

용어 각주
자주 묻는 질문
- 이 글에서 가장 먼저 확인할 것은 무엇인가요?
- Langfuse는 애플리케이션이 명시적으로 전송한 추적 이벤트를 받아 관찰 화면에 보여 줘요. 로컬 인스턴스와 Python SDK v4를 쓰면 API 주소를 그 인스턴스로 지정하고 `@observe`로 함수 호출을 기록할 수 있어요. Langfuse를 설치했다고 임의의 Ollama 요청이 자동으로 기록되지는 않아요. 계측한 입력·출력에 개인정보나 문서 내용이 포함될 수 있으므로 기록할 필드를 직접 고르고 민감한 값을 마스킹해요.
