| name | langfuse-observability |
| description | Self-host Langfuse v3.x on EKS (Web, API, Worker) with PostgreSQL, ClickHouse, Redis, and S3 backends. Wire an OpenTelemetry Collector pipeline that receives traces from vLLM, Bifrost/LiteLLM, and LangChain agents so token cost, latency, and quality scores are tracked end-to-end. |
| argument-hint | [expected trace volume, multi-tenant requirement] |
| user-invocable | true |
| model | claude-sonnet-4-6 |
| allowed-tools | Read,Write,Edit,Bash,Grep,Glob,mcp__eks,mcp__aws-documentation,mcp__cloudwatch,mcp__prometheus |
Optional. This is one observability backend within the ai-infra platform plugin. OMA's core (ontology + harness DSL) needs no observability backend โ the default profile mode is none. Use this skill only if you have opted into Langfuse (observability.mode: langfuse-self-hosted); opentelemetry-only or any OTLP-compatible store are equally valid alternatives.
When to Use
- Agent / LLM ํธ์ถ์ ๋ํ end-to-end trace, token cost, quality ์ ์๋ฅผ ํ๊ณณ์์ ๋ณด๊ณ ์ถ์ ๋
- LangSmith SaaS ๋์ self-hosted ๊ด์ธก์ฑ์ด ํ์ํ ๊ท์ ํ๊ฒฝ
- ํ๋กฌํํธ ๋ฒ์ ๋, ํ๊ฐ(Ragas), ๋ฐ์ดํฐ์
๊ธฐ๋ฐ ํ๊ท ํ
์คํธ๊ฐ ํ์ํ ๋
- vLLMยทBifrostยทLangChainยทLangGraph ๋ชจ๋๋ฅผ ํ๋์ trace tree ๋ก ์ฐ๊ฒฐํด์ผ ํ ๋
When NOT to Use
- Cloud SaaS ๋ก ์ถฉ๋ถ โ Langfuse Cloud ์ฌ์ฉ
- ๋ฉํธ๋ฆญ๋ง ํ์ (trace ๋ถํ์) โ Prometheus + Grafana ๋จ๋
- OTel ํ์ค๊ณผ ํธํ๋์ง ์๋ legacy agent โ OTel ๋ง์ด๊ทธ๋ ์ด์
์ ํ ํ์
Preconditions
- EKS 1.32+, IRSA ๊ตฌ์ฑ, S3 ๋ฒํท ์์ฑ
- PostgreSQL, ClickHouse, Redis ๋ฅผ in-cluster ๋๋ managed ๋ก ๋ฐฐํฌํ ์ง ๊ฒฐ์ (RDS, Aurora, ElastiCache ๊ฐ๋ฅ)
- OTel Collector ๋ฅผ
observability namespace ์ ๋ฐฐํฌ ์์
Procedure
Step 1. S3 ๋ฒํท + IRSA ์์ฑ
AmazonS3FullAccess ๊ฐ์ account-wide s3:* managed policy ๋ ์ ๋ attach ํ์ง ์์ต๋๋ค. Langfuse ๋ฒํท ํ ๊ฐ๋ก scope ํ ์ต์๊ถํ customer-managed policy ๋ง ์ฌ์ฉํฉ๋๋ค.
export BUCKET=my-langfuse-blobs
export REGION=ap-northeast-2
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
aws s3api create-bucket \
--bucket "$BUCKET" \
--region "$REGION" \
--create-bucket-configuration LocationConstraint="$REGION"
cat > /tmp/langfuse-s3-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LangfuseBucketListAndMeta",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::${BUCKET}"
},
{
"Sid": "LangfuseBucketObjectRW",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload"
],
"Resource": "arn:aws:s3:::${BUCKET}/*"
}
]
}
EOF
aws iam create-policy \
--policy-name LangfuseBlobStoreRW \
--policy-document file:///tmp/langfuse-s3-policy.json
eksctl create iamserviceaccount \
--cluster agentic-prod \
--namespace langfuse \
--name langfuse \
--attach-policy-arn "arn:aws:iam::${ACCOUNT_ID}:policy/LangfuseBlobStoreRW" \
--approve
๊ธ์ง: arn:aws:iam::aws:policy/AmazonS3FullAccess ๋ s3:* ๋ฅผ account-wide ๋ก ํ์ฉํ๋ฏ๋ก ๋ค๋ฅธ ๋ฒํท์ blob ๋ ์ด๋ยท์ญ์ ๊ฐ๋ฅํฉ๋๋ค. IRSA ๊ฐ ํ์ทจ๋๋ฉด ๋ฐ์ดํฐ ์ ์ฒด๊ฐ ๋
ธ์ถ๋๋ ๋ฒกํฐ์ด๋ฏ๋ก ์ฌ์ฉํ์ง ์์ต๋๋ค.
Step 2. Langfuse v3 Helm ๋ฐฐํฌ
helm repo add langfuse https://langfuse.github.io/langfuse-k8s
helm upgrade --install langfuse langfuse/langfuse \
--namespace langfuse --create-namespace \
--version 1.3.0 \
-f langfuse-values.yaml
langfuse-values.yaml:
langfuse:
image:
tag: "3.162.0"
web:
replicas: 2
worker:
replicas: 2
postgresql:
deploy: true
auth:
database: langfuse
clickhouse:
deploy: true
shards: 1
replicas: 2
redis:
deploy: true
architecture: replication
s3:
bucket: my-langfuse-blobs
region: ap-northeast-2
useIamRole: true
Step 3. OTel Collector ํ์ดํ๋ผ์ธ
receivers:
otlp:
protocols:
grpc: { endpoint: 0.0.0.0:4317 }
http: { endpoint: 0.0.0.0:4318 }
processors:
batch: {}
attributes:
actions:
- key: service.namespace
value: agentic
action: insert
exporters:
otlphttp/langfuse:
endpoint: http://langfuse-web.langfuse.svc:3000/api/public/otel
headers:
Authorization: Basic ${env:LANGFUSE_API_BASIC}
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch, attributes]
exporters: [otlphttp/langfuse]
Step 4. vLLM / Bifrost ์ฐ๊ฒฐ
kubectl -n inference set env deployment/vllm-llama3 \
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector.observability.svc:4317 \
OTEL_SERVICE_NAME=vllm-llama3
kubectl -n inference set env deployment/bifrost \
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector.observability.svc:4317 \
OTEL_SERVICE_NAME=bifrost
Step 5. ๊ฒ์ฆ
kubectl -n langfuse get pods
kubectl -n langfuse port-forward svc/langfuse-web 3000:3000
- ์ํ ์์ฒญ ํ Langfuse Traces ํญ์์ span tree ํ์ธ
Step 6. ์๋ฆผยท๋์๋ณด๋
- Prometheus alert:
langfuse_worker_queue_depth > 10000
- Langfuse Dashboards: token/day, error rate, p95 latency, cost by model
- Ragas ํ๊ฐ ๊ฒฐ๊ณผ๋ฅผ Langfuse Scores ๋ก ์
๋ก๋
Good Examples
- ํ๋ก๋์
: PostgreSQL RDS Multi-AZ + ClickHouse 2-replica + Redis ElastiCache + S3
- PoC: in-cluster PG + ClickHouse single + Redis single (replicas=1)
- OTel attribute
gen_ai.usage.input_tokens, gen_ai.usage.output_tokens ์ฃผ์
์ผ๋ก ์ ํ cost
Bad Examples (๊ธ์ง)
- ClickHouse ๋นํ์ฑ + 1M events/day ์ด๊ณผ โ ๋์๋ณด๋ ๋ก๋ฉ ํ์์์
- OTel Collector ์์ด SDK โ Langfuse ์งํต (retriesยทsampling ๋ฏธ์ง์)
disable-model-invocation ๋ชจ๋์์ ํ๋กฌํํธ sanitize ๋๋ฝ โ PII ์ ์ถ ์ํ
- Langfuse v2.x ๊ตฌ๋ฒ์ โ Prompt Experiments, ClickHouse ๋ฏธ์ง์
References