Langfuse 自托管本地安装指南(Docker Compose)

mystu 项目采用 自托管 Langfuse 接收 Agent 链路追踪数据(见 docs/langfuse-tracing-explained.md)。本文从零讲解:需要装什么、怎么装、装完如何拿到 API Key 并接到 mystu 的 .env推荐路径是 Docker Compose ,适合本地开发、内网测试与中小规模部署;生产高可用请另看 Langfuse Kubernetes / Terraform 部署


1. 安装前你需要知道的事

1.1 自托管会拉起哪些组件

Langfuse 不是单个容器,而是一套可观测性栈 。官方 docker-compose.yml 会同时启动:
#mermaid-svg-7CM88LuNSQJtHSof{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-7CM88LuNSQJtHSof .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-7CM88LuNSQJtHSof .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-7CM88LuNSQJtHSof .error-icon{fill:#552222;}#mermaid-svg-7CM88LuNSQJtHSof .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7CM88LuNSQJtHSof .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-7CM88LuNSQJtHSof .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7CM88LuNSQJtHSof .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7CM88LuNSQJtHSof .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-7CM88LuNSQJtHSof .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7CM88LuNSQJtHSof .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7CM88LuNSQJtHSof .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7CM88LuNSQJtHSof .marker.cross{stroke:#333333;}#mermaid-svg-7CM88LuNSQJtHSof svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7CM88LuNSQJtHSof p{margin:0;}#mermaid-svg-7CM88LuNSQJtHSof .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-7CM88LuNSQJtHSof .cluster-label text{fill:#333;}#mermaid-svg-7CM88LuNSQJtHSof .cluster-label span{color:#333;}#mermaid-svg-7CM88LuNSQJtHSof .cluster-label span p{background-color:transparent;}#mermaid-svg-7CM88LuNSQJtHSof .label text,#mermaid-svg-7CM88LuNSQJtHSof span{fill:#333;color:#333;}#mermaid-svg-7CM88LuNSQJtHSof .node rect,#mermaid-svg-7CM88LuNSQJtHSof .node circle,#mermaid-svg-7CM88LuNSQJtHSof .node ellipse,#mermaid-svg-7CM88LuNSQJtHSof .node polygon,#mermaid-svg-7CM88LuNSQJtHSof .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-7CM88LuNSQJtHSof .rough-node .label text,#mermaid-svg-7CM88LuNSQJtHSof .node .label text,#mermaid-svg-7CM88LuNSQJtHSof .image-shape .label,#mermaid-svg-7CM88LuNSQJtHSof .icon-shape .label{text-anchor:middle;}#mermaid-svg-7CM88LuNSQJtHSof .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-7CM88LuNSQJtHSof .rough-node .label,#mermaid-svg-7CM88LuNSQJtHSof .node .label,#mermaid-svg-7CM88LuNSQJtHSof .image-shape .label,#mermaid-svg-7CM88LuNSQJtHSof .icon-shape .label{text-align:center;}#mermaid-svg-7CM88LuNSQJtHSof .node.clickable{cursor:pointer;}#mermaid-svg-7CM88LuNSQJtHSof .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-7CM88LuNSQJtHSof .arrowheadPath{fill:#333333;}#mermaid-svg-7CM88LuNSQJtHSof .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-7CM88LuNSQJtHSof .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-7CM88LuNSQJtHSof .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7CM88LuNSQJtHSof .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-7CM88LuNSQJtHSof .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7CM88LuNSQJtHSof .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-7CM88LuNSQJtHSof .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-7CM88LuNSQJtHSof .cluster text{fill:#333;}#mermaid-svg-7CM88LuNSQJtHSof .cluster span{color:#333;}#mermaid-svg-7CM88LuNSQJtHSof div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-7CM88LuNSQJtHSof .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-7CM88LuNSQJtHSof rect.text{fill:none;stroke-width:0;}#mermaid-svg-7CM88LuNSQJtHSof .icon-shape,#mermaid-svg-7CM88LuNSQJtHSof .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7CM88LuNSQJtHSof .icon-shape p,#mermaid-svg-7CM88LuNSQJtHSof .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-7CM88LuNSQJtHSof .icon-shape .label rect,#mermaid-svg-7CM88LuNSQJtHSof .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7CM88LuNSQJtHSof .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-7CM88LuNSQJtHSof .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-7CM88LuNSQJtHSof :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 仅本机 127.0.0.1
对外访问
langfuse-web :3000

UI + Ingest API
MinIO :9090

部分场景需外网访问
langfuse-worker

异步 ingestion
PostgreSQL :5432

事务元数据
ClickHouse :8123/9000

Trace 分析存储
Redis :6379

队列与缓存
MinIO 内部 :9000

原始事件 Blob

组件 作用
langfuse-web Web UI、Public API、SDK 上报入口
langfuse-worker 从队列/S3 异步写入 ClickHouse
PostgreSQL 用户、项目、API Key、配置等 OLTP 数据
ClickHouse Trace / Observation 等分析型数据
Redis 队列、API Key 缓存、Prompt 缓存等
MinIO S3 兼容对象存储,持久化原始 ingestion 事件

1.2 硬件与系统建议

场景 CPU 内存 磁盘 说明
本地试用 2 核+ 8 GiB+ 20 GiB+ 能跑起来,trace 量大时 ClickHouse 会涨盘
团队内网 4 核+ 16 GiB+ 100 GiB+ 官方 VM 推荐起点
时区 --- --- --- Postgres 与 ClickHouse 必须 UTCTZ=UTC),否则查询可能为空

1.3 软件依赖

工具 版本建议 用途
Git 任意较新版本 克隆官方仓库
Docker Engine 24+ 运行容器
Docker Compose V2 插件内置 docker compose up
  • Windows / macOS :安装 Docker Desktop,并启用 WSL2(Windows)。
  • Linux :安装 docker-ce + docker-compose-plugin(见下文 Ubuntu 示例)。

2. 整体安装工作流(一图看懂)

#mermaid-svg-Ftf4NlfTyurGexRn{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Ftf4NlfTyurGexRn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Ftf4NlfTyurGexRn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Ftf4NlfTyurGexRn .error-icon{fill:#552222;}#mermaid-svg-Ftf4NlfTyurGexRn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ftf4NlfTyurGexRn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Ftf4NlfTyurGexRn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ftf4NlfTyurGexRn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ftf4NlfTyurGexRn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Ftf4NlfTyurGexRn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ftf4NlfTyurGexRn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ftf4NlfTyurGexRn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ftf4NlfTyurGexRn .marker.cross{stroke:#333333;}#mermaid-svg-Ftf4NlfTyurGexRn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ftf4NlfTyurGexRn p{margin:0;}#mermaid-svg-Ftf4NlfTyurGexRn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Ftf4NlfTyurGexRn .cluster-label text{fill:#333;}#mermaid-svg-Ftf4NlfTyurGexRn .cluster-label span{color:#333;}#mermaid-svg-Ftf4NlfTyurGexRn .cluster-label span p{background-color:transparent;}#mermaid-svg-Ftf4NlfTyurGexRn .label text,#mermaid-svg-Ftf4NlfTyurGexRn span{fill:#333;color:#333;}#mermaid-svg-Ftf4NlfTyurGexRn .node rect,#mermaid-svg-Ftf4NlfTyurGexRn .node circle,#mermaid-svg-Ftf4NlfTyurGexRn .node ellipse,#mermaid-svg-Ftf4NlfTyurGexRn .node polygon,#mermaid-svg-Ftf4NlfTyurGexRn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ftf4NlfTyurGexRn .rough-node .label text,#mermaid-svg-Ftf4NlfTyurGexRn .node .label text,#mermaid-svg-Ftf4NlfTyurGexRn .image-shape .label,#mermaid-svg-Ftf4NlfTyurGexRn .icon-shape .label{text-anchor:middle;}#mermaid-svg-Ftf4NlfTyurGexRn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Ftf4NlfTyurGexRn .rough-node .label,#mermaid-svg-Ftf4NlfTyurGexRn .node .label,#mermaid-svg-Ftf4NlfTyurGexRn .image-shape .label,#mermaid-svg-Ftf4NlfTyurGexRn .icon-shape .label{text-align:center;}#mermaid-svg-Ftf4NlfTyurGexRn .node.clickable{cursor:pointer;}#mermaid-svg-Ftf4NlfTyurGexRn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Ftf4NlfTyurGexRn .arrowheadPath{fill:#333333;}#mermaid-svg-Ftf4NlfTyurGexRn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Ftf4NlfTyurGexRn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Ftf4NlfTyurGexRn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ftf4NlfTyurGexRn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Ftf4NlfTyurGexRn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ftf4NlfTyurGexRn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Ftf4NlfTyurGexRn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Ftf4NlfTyurGexRn .cluster text{fill:#333;}#mermaid-svg-Ftf4NlfTyurGexRn .cluster span{color:#333;}#mermaid-svg-Ftf4NlfTyurGexRn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Ftf4NlfTyurGexRn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Ftf4NlfTyurGexRn rect.text{fill:none;stroke-width:0;}#mermaid-svg-Ftf4NlfTyurGexRn .icon-shape,#mermaid-svg-Ftf4NlfTyurGexRn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ftf4NlfTyurGexRn .icon-shape p,#mermaid-svg-Ftf4NlfTyurGexRn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Ftf4NlfTyurGexRn .icon-shape .label rect,#mermaid-svg-Ftf4NlfTyurGexRn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ftf4NlfTyurGexRn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Ftf4NlfTyurGexRn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Ftf4NlfTyurGexRn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 安装 Docker
克隆 langfuse 仓库
修改密钥 CHANGEME
docker compose up -d
等待 web 日志 Ready
浏览器打开 :3000
注册 / 创建 Project
复制 Public Key + Secret Key
配置 mystu .env
发一条 /chat 验证 Trace


3. Windows 本地安装(逐步操作)

以下步骤在 Windows 10/11 上验证思路与官方文档一致;路径示例可按你的习惯调整。

3.1 安装 Docker Desktop

  1. 下载并安装 Docker Desktop for Windows
  2. 安装时勾选 Use WSL 2 instead of Hyper-V(推荐)。
  3. 打开 Docker Desktop,等待左下角状态为 Engine running
  4. 在 PowerShell 中验证:
powershell 复制代码
docker --version
docker compose version
docker run hello-world

hello-world 成功,说明 Docker 引擎可用。

3.2 克隆 Langfuse 官方仓库

选一个不含中文路径的目录(避免 Docker 挂载异常),例如:

powershell 复制代码
cd C:\dev
git clone https://github.com/langfuse/langfuse.git
cd langfuse

不要直接把 Langfuse 克隆进 mystu 仓库内------它是独立的基础设施栈,与业务代码分开维护更清晰。

3.3 修改密钥(必做,不要跳过)

官方 docker-compose.yml 里所有 # CHANGEME 标记的默认值仅适合本地试玩 ,正式使用前必须改成足够长的随机字符串

必须修改的项(至少改这些):

环境变量 / 配置 位置 生成方式示例
POSTGRES_PASSWORD postgres 服务 随机 32+ 字符
CLICKHOUSE_PASSWORD clickhouse / worker / web 随机强密码
REDIS_AUTH redis command + worker env 随机强密码
MINIO_ROOT_PASSWORD minio + S3 相关 SECRET 随机强密码
SALT worker / web 随机字符串
ENCRYPTION_KEY worker / web openssl rand -hex 32(64 位十六进制)
NEXTAUTH_SECRET langfuse-web 随机 32+ 字符

Windows 生成随机 hex(PowerShell):

powershell 复制代码
# 64 字符 hex,用作 ENCRYPTION_KEY
-join ((1..32) | ForEach-Object { '{0:x2}' -f (Get-Random -Maximum 256) })

推荐做法:使用 .env 文件覆盖默认值

langfuse 仓库根目录创建 .env(不要提交 Git),例如:

env 复制代码
# Langfuse docker compose 环境变量(示例,请自行替换为随机值)
POSTGRES_PASSWORD=your-strong-postgres-password
CLICKHOUSE_PASSWORD=your-strong-clickhouse-password
REDIS_AUTH=your-strong-redis-password
MINIO_ROOT_PASSWORD=your-strong-minio-password
LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY=your-strong-minio-password
LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY=your-strong-minio-password
LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY=your-strong-minio-password

SALT=your-random-salt-string
ENCRYPTION_KEY=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
NEXTAUTH_SECRET=your-random-nextauth-secret

NEXTAUTH_URL=http://localhost:3000

docker compose 会自动读取同目录下的 .env 并替换 ${VAR:-default} 占位符。

可选:Headless 初始化(免手动注册)

若希望首次启动就创建管理员与项目,可在 .env 中追加(密钥也可预生成):

env 复制代码
LANGFUSE_INIT_ORG_NAME=mystu-dev
LANGFUSE_INIT_PROJECT_NAME=mystu-agent
LANGFUSE_INIT_USER_EMAIL=admin@example.com
LANGFUSE_INIT_USER_NAME=Admin
LANGFUSE_INIT_USER_PASSWORD=ChangeMeOnFirstLogin!
# 可选:固定 project API keys(否则启动后在 UI 创建)
# LANGFUSE_INIT_PROJECT_PUBLIC_KEY=pk-lf-...
# LANGFUSE_INIT_PROJECT_SECRET_KEY=sk-lf-...

详见 Headless Initialization

3.4 启动 Langfuse

langfuse 目录执行:

powershell 复制代码
# 前台启动(首次建议,方便看日志)
docker compose up

# 或后台启动
docker compose up -d

首次启动大约需要 2--5 分钟,需等待依赖健康检查通过:
langfuse-web MinIO Redis ClickHouse PostgreSQL docker compose 你 langfuse-web MinIO Redis ClickHouse PostgreSQL docker compose 你 #mermaid-svg-r8mwSwFlVo6QID8m{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-r8mwSwFlVo6QID8m .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-r8mwSwFlVo6QID8m .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-r8mwSwFlVo6QID8m .error-icon{fill:#552222;}#mermaid-svg-r8mwSwFlVo6QID8m .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-r8mwSwFlVo6QID8m .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-r8mwSwFlVo6QID8m .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-r8mwSwFlVo6QID8m .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-r8mwSwFlVo6QID8m .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-r8mwSwFlVo6QID8m .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-r8mwSwFlVo6QID8m .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-r8mwSwFlVo6QID8m .marker{fill:#333333;stroke:#333333;}#mermaid-svg-r8mwSwFlVo6QID8m .marker.cross{stroke:#333333;}#mermaid-svg-r8mwSwFlVo6QID8m svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-r8mwSwFlVo6QID8m p{margin:0;}#mermaid-svg-r8mwSwFlVo6QID8m .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-r8mwSwFlVo6QID8m text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-r8mwSwFlVo6QID8m .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-r8mwSwFlVo6QID8m .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-r8mwSwFlVo6QID8m .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-r8mwSwFlVo6QID8m .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-r8mwSwFlVo6QID8m #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-r8mwSwFlVo6QID8m .sequenceNumber{fill:white;}#mermaid-svg-r8mwSwFlVo6QID8m #sequencenumber{fill:#333;}#mermaid-svg-r8mwSwFlVo6QID8m #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-r8mwSwFlVo6QID8m .messageText{fill:#333;stroke:none;}#mermaid-svg-r8mwSwFlVo6QID8m .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-r8mwSwFlVo6QID8m .labelText,#mermaid-svg-r8mwSwFlVo6QID8m .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-r8mwSwFlVo6QID8m .loopText,#mermaid-svg-r8mwSwFlVo6QID8m .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-r8mwSwFlVo6QID8m .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-r8mwSwFlVo6QID8m .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-r8mwSwFlVo6QID8m .noteText,#mermaid-svg-r8mwSwFlVo6QID8m .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-r8mwSwFlVo6QID8m .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-r8mwSwFlVo6QID8m .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-r8mwSwFlVo6QID8m .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-r8mwSwFlVo6QID8m .actorPopupMenu{position:absolute;}#mermaid-svg-r8mwSwFlVo6QID8m .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-r8mwSwFlVo6QID8m .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-r8mwSwFlVo6QID8m .actor-man circle,#mermaid-svg-r8mwSwFlVo6QID8m line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-r8mwSwFlVo6QID8m :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} docker compose up healthcheck pg_isready healthcheck /ping healthcheck redis-cli ping healthcheck mc ready healthy healthy healthy healthy 启动 web + worker 日志出现 Ready

如何判断成功:

powershell 复制代码
docker compose ps
docker compose logs langfuse-web --tail 50

langfuse-web 日志中出现 Ready(或类似就绪提示),即可访问 UI。

3.5 打开 Web UI 并完成初始化

  1. 浏览器访问:http://localhost:3000
  2. 若未使用 Headless 初始化:点击 Sign up 注册第一个账号(首个用户通常为管理员)。
  3. 登录后创建 OrganizationProject(若向导未自动创建)。
  4. 进入 Project → SettingsAPI Keys
    • 创建一对 Public Keypk-lf-...)和 Secret Keysk-lf-...
    • Secret Key 只显示一次,请立即保存到密码管理器。

#mermaid-svg-JfLPllQru5pPFIdu{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-JfLPllQru5pPFIdu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-JfLPllQru5pPFIdu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-JfLPllQru5pPFIdu .error-icon{fill:#552222;}#mermaid-svg-JfLPllQru5pPFIdu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-JfLPllQru5pPFIdu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-JfLPllQru5pPFIdu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-JfLPllQru5pPFIdu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-JfLPllQru5pPFIdu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-JfLPllQru5pPFIdu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-JfLPllQru5pPFIdu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-JfLPllQru5pPFIdu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-JfLPllQru5pPFIdu .marker.cross{stroke:#333333;}#mermaid-svg-JfLPllQru5pPFIdu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-JfLPllQru5pPFIdu p{margin:0;}#mermaid-svg-JfLPllQru5pPFIdu .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-JfLPllQru5pPFIdu .cluster-label text{fill:#333;}#mermaid-svg-JfLPllQru5pPFIdu .cluster-label span{color:#333;}#mermaid-svg-JfLPllQru5pPFIdu .cluster-label span p{background-color:transparent;}#mermaid-svg-JfLPllQru5pPFIdu .label text,#mermaid-svg-JfLPllQru5pPFIdu span{fill:#333;color:#333;}#mermaid-svg-JfLPllQru5pPFIdu .node rect,#mermaid-svg-JfLPllQru5pPFIdu .node circle,#mermaid-svg-JfLPllQru5pPFIdu .node ellipse,#mermaid-svg-JfLPllQru5pPFIdu .node polygon,#mermaid-svg-JfLPllQru5pPFIdu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-JfLPllQru5pPFIdu .rough-node .label text,#mermaid-svg-JfLPllQru5pPFIdu .node .label text,#mermaid-svg-JfLPllQru5pPFIdu .image-shape .label,#mermaid-svg-JfLPllQru5pPFIdu .icon-shape .label{text-anchor:middle;}#mermaid-svg-JfLPllQru5pPFIdu .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-JfLPllQru5pPFIdu .rough-node .label,#mermaid-svg-JfLPllQru5pPFIdu .node .label,#mermaid-svg-JfLPllQru5pPFIdu .image-shape .label,#mermaid-svg-JfLPllQru5pPFIdu .icon-shape .label{text-align:center;}#mermaid-svg-JfLPllQru5pPFIdu .node.clickable{cursor:pointer;}#mermaid-svg-JfLPllQru5pPFIdu .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-JfLPllQru5pPFIdu .arrowheadPath{fill:#333333;}#mermaid-svg-JfLPllQru5pPFIdu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-JfLPllQru5pPFIdu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-JfLPllQru5pPFIdu .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-JfLPllQru5pPFIdu .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-JfLPllQru5pPFIdu .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-JfLPllQru5pPFIdu .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-JfLPllQru5pPFIdu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-JfLPllQru5pPFIdu .cluster text{fill:#333;}#mermaid-svg-JfLPllQru5pPFIdu .cluster span{color:#333;}#mermaid-svg-JfLPllQru5pPFIdu div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-JfLPllQru5pPFIdu .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-JfLPllQru5pPFIdu rect.text{fill:none;stroke-width:0;}#mermaid-svg-JfLPllQru5pPFIdu .icon-shape,#mermaid-svg-JfLPllQru5pPFIdu .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-JfLPllQru5pPFIdu .icon-shape p,#mermaid-svg-JfLPllQru5pPFIdu .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-JfLPllQru5pPFIdu .icon-shape .label rect,#mermaid-svg-JfLPllQru5pPFIdu .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-JfLPllQru5pPFIdu .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-JfLPllQru5pPFIdu .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-JfLPllQru5pPFIdu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 登录 Langfuse UI
创建 Project
Settings → API Keys
Create new API key
保存 pk-lf / sk-lf
写入 mystu .env

3.6 验证 Langfuse 自身是否正常

UI 健康:

  • 能打开 Dashboard,无 502/500。

容器健康:

powershell 复制代码
docker compose ps
# 期望 langfuse-web、langfuse-worker、postgres、clickhouse、redis、minio 均为 running / healthy

可选:Public API 探测

Langfuse 提供健康检查端点(版本可能略有差异,以官方文档为准):

powershell 复制代码
curl http://localhost:3000/api/public/health

返回 200 即表示 Web 进程可用。


4. Linux / macOS 本地安装

与 Windows 逻辑相同,仅 Docker 安装方式不同。

4.1 macOS

  1. 安装 Docker Desktop for Mac
  2. 分配足够资源:Settings → Resources,建议 Memory ≥ 8 GiB。
  3. 后续步骤同 §3.2--3.6。

4.2 Ubuntu 服务器 / WSL2 内 Linux

安装 Docker(官方源):

bash 复制代码
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run hello-world

克隆并启动:

bash 复制代码
git clone https://github.com/langfuse/langfuse.git
cd langfuse
# 编辑 .env 修改 CHANGEME 密钥(同 §3.3)
docker compose up -d
docker compose logs -f langfuse-web

远程 VM 访问 UI 时,在安全组/防火墙中仅开放 3000(及按需 9090),不要把 Postgres/Redis/ClickHouse 暴露到公网。


5. 与 mystu 项目对接

Langfuse 装好后,还需让 mystu Agent 把 trace 发到你的实例。

5.1 mystu 侧环境变量

在 mystu 项目根目录 .env 中增加(与 AGENTS.md 一致):

env 复制代码
# Langfuse 自托管 tracing
LANGFUSE_ENABLED=true
LANGFUSE_PUBLIC_KEY=pk-lf-xxxxxxxx
LANGFUSE_SECRET_KEY=sk-lf-xxxxxxxx
LANGFUSE_HOST=http://localhost:3000
LANGFUSE_SAMPLE_RATE=1.0
变量 说明
LANGFUSE_ENABLED 必须显式 true 才启用
LANGFUSE_PUBLIC_KEY / LANGFUSE_SECRET_KEY 来自 Langfuse Project → API Keys
LANGFUSE_HOST 自托管 Web 地址;mystu 与 Langfuse 同机时用 http://localhost:3000
LANGFUSE_SAMPLE_RATE 1.0 全量;生产可改 0.1

mystu 运行在 Docker 容器内、Langfuse 在宿主机时,不能用 localhost,应改为 http://host.docker.internal:3000(Docker Desktop)或宿主机局域网 IP。

5.2 网络连通性检查

mystu(Python 进程)必须能访问 Langfuse Ingest API:

powershell 复制代码
# 在 mystu 同一环境执行
curl http://localhost:3000/api/public/health

若 mystu 在 WSL、Langfuse 在 Windows Docker Desktop,一般 localhost:3000 可通;若不通,改用 Docker 网桥 IP 或 host.docker.internal

5.3 端到端验证工作流

Langfuse :3000 mystu :5000 浏览器 Langfuse :3000 mystu :5000 浏览器 #mermaid-svg-uWiGdkxaQLmSN3ts{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-uWiGdkxaQLmSN3ts .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-uWiGdkxaQLmSN3ts .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-uWiGdkxaQLmSN3ts .error-icon{fill:#552222;}#mermaid-svg-uWiGdkxaQLmSN3ts .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-uWiGdkxaQLmSN3ts .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-uWiGdkxaQLmSN3ts .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-uWiGdkxaQLmSN3ts .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-uWiGdkxaQLmSN3ts .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-uWiGdkxaQLmSN3ts .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-uWiGdkxaQLmSN3ts .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-uWiGdkxaQLmSN3ts .marker{fill:#333333;stroke:#333333;}#mermaid-svg-uWiGdkxaQLmSN3ts .marker.cross{stroke:#333333;}#mermaid-svg-uWiGdkxaQLmSN3ts svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-uWiGdkxaQLmSN3ts p{margin:0;}#mermaid-svg-uWiGdkxaQLmSN3ts .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-uWiGdkxaQLmSN3ts text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-uWiGdkxaQLmSN3ts .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-uWiGdkxaQLmSN3ts .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-uWiGdkxaQLmSN3ts .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-uWiGdkxaQLmSN3ts .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-uWiGdkxaQLmSN3ts #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-uWiGdkxaQLmSN3ts .sequenceNumber{fill:white;}#mermaid-svg-uWiGdkxaQLmSN3ts #sequencenumber{fill:#333;}#mermaid-svg-uWiGdkxaQLmSN3ts #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-uWiGdkxaQLmSN3ts .messageText{fill:#333;stroke:none;}#mermaid-svg-uWiGdkxaQLmSN3ts .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-uWiGdkxaQLmSN3ts .labelText,#mermaid-svg-uWiGdkxaQLmSN3ts .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-uWiGdkxaQLmSN3ts .loopText,#mermaid-svg-uWiGdkxaQLmSN3ts .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-uWiGdkxaQLmSN3ts .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-uWiGdkxaQLmSN3ts .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-uWiGdkxaQLmSN3ts .noteText,#mermaid-svg-uWiGdkxaQLmSN3ts .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-uWiGdkxaQLmSN3ts .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-uWiGdkxaQLmSN3ts .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-uWiGdkxaQLmSN3ts .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-uWiGdkxaQLmSN3ts .actorPopupMenu{position:absolute;}#mermaid-svg-uWiGdkxaQLmSN3ts .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-uWiGdkxaQLmSN3ts .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-uWiGdkxaQLmSN3ts .actor-man circle,#mermaid-svg-uWiGdkxaQLmSN3ts line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-uWiGdkxaQLmSN3ts :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 按 thread_id 搜索 Session 登录并发一条 /agent/api/chat SDK 上报 trace(LANGFUSE_HOST) 打开 UI → Traces / Sessions

操作步骤:

  1. 启动 Langfuse:docker compose up -d(在 langfuse 目录)。
  2. 启动 mystu:python main.py(在 mystu 根目录,且 .env 已配置 LLM + MySQL + Redis + Langfuse)。
  3. 浏览器登录 mystu,发送一条会触发模型回复的消息。
  4. 打开 Langfuse UI → Tracing → 按时间或 Session 查看是否出现新 Trace。
  5. Session ID 应与 mystu 的 thread_id 一致(见 docs/langfuse-tracing-explained.md)。

若无 Trace:

  • 确认 LANGFUSE_ENABLED=true 且密钥正确。
  • 查看 mystu 日志是否有 Langfuse callback 注入失败 / flush 失败 的 warning。
  • 查看 docker compose logs langfuse-web langfuse-worker

6. 端口与防火墙一览

官方 compose 默认端口(便于排查冲突):

服务 宿主机端口 绑定 是否需对外
langfuse-web 3000 0.0.0.0 (UI + API)
MinIO S3 API 9090 0.0.0.0 视多模态上传需求
MinIO Console 9091 127.0.0.1
PostgreSQL 5432 127.0.0.1
ClickHouse HTTP 8123 127.0.0.1
ClickHouse Native 9000 127.0.0.1
Redis 6379 127.0.0.1
langfuse-worker 3030 127.0.0.1

若本机 3000 已被占用 (例如其他前端项目),可在 docker-compose.yml 中把 3000:3000 改为 3001:3000,并同步修改 NEXTAUTH_URL 与 mystu 的 LANGFUSE_HOST


7. 日常运维命令

7.1 启动 / 停止 / 重启

powershell 复制代码
cd C:\dev\langfuse

# 后台启动
docker compose up -d

# 停止(保留数据卷)
docker compose down

# 停止并删除所有数据(⚠️ 清空 trace,慎用)
docker compose down -v

# 拉取新镜像并重启(升级)
docker compose pull
docker compose up -d

7.2 查看日志

powershell 复制代码
docker compose logs -f langfuse-web
docker compose logs -f langfuse-worker
docker compose logs -f clickhouse

7.3 磁盘占用

Trace 与原始事件会持续增长,主要占用:

  • Docker volume langfuse_clickhouse_data
  • Docker volume langfuse_minio_data
  • Docker volume langfuse_postgres_data
powershell 复制代码
docker system df -v

磁盘不足时优先清理旧 trace(Langfuse UI / 保留策略)或扩容 volume。


8. 常见问题排查

8.1 长时间无法 Ready

可能原因 处理
内存不足 Docker Desktop 调高 Memory;关闭其它占内存容器
端口冲突 `netstat -ano
ClickHouse 启动慢 docker compose logs clickhouse,等待 healthcheck 通过
密码含特殊字符未转义 .env 中用引号包裹或换简单强密码测试

8.2 UI 能开,但 mystu 无 Trace

检查项 处理
LANGFUSE_ENABLED 未设 true .env 并重启 mystu
Host 地址错误 容器内勿用错 localhost
Secret Key 错误 在 UI 重新创建 Key
采样率为 0 LANGFUSE_SAMPLE_RATE=1.0
防火墙拦截 放行 mystu → Langfuse 3000

8.3 查询结果为空 / 时间不对

官方要求 Postgres 与 ClickHouse 时区为 UTC 。官方 compose 已为 Postgres 设置 TZ=UTC / PGTZ=UTC;若你自建库,需手动保证 UTC。

8.4 多模态 Trace 上传失败

Docker Compose 默认 MinIO 的 media upload 外部 endpointhttp://localhost:9090。SDK 从浏览器或外部进程直传时,需保证该地址可达,或按 Blob Storage 配置指南 调整。

mystu 当前以 文本 LLM + 工具 span 为主,一般不受影响。

8.5 Windows 路径 / 权限问题

  • 仓库路径避免中文与空格。
  • Docker Desktop 确保 WSL2 集成已启用。
  • 公司环境若禁止 Docker,只能改用 Linux VM 或 Langfuse Cloud。

9. 安全与合规建议(自托管必读)

mystu 当前 tracing 策略为全量记录用户消息与工具参数(见需求文档)。自托管时请注意:

建议
密钥 所有 # CHANGEME 必须替换;.env 不提交 Git
网络 仅内网访问 3000;公网暴露务必加 HTTPS + 认证
RBAC Langfuse 项目级权限;生产限制 UI 访问人员
Retention 在 Langfuse 或库层面规划 trace 保留周期
备份 Docker Compose 无内置 HA/备份;重要环境请备份 volume 或上 K8s

10. 与 Docker Compose 之外的部署方式

方式 适用 文档
Docker Compose 本地 / 单机 VM 本文
Kubernetes (Helm) 生产 HA Langfuse K8s
AWS / Azure / GCP Terraform 云上单区域生产 Langfuse 官网 Self-hosting
Langfuse Cloud 免运维 cloud.langfuse.com

mystu 的 SDK 配置方式相同,仅 LANGFUSE_HOST 改为你的生产域名,例如 https://langfuse.internal.example.com


11. 安装完成检查清单

复制以下清单逐项打勾:

  • Docker / Docker Compose 可用(docker compose version
  • 已克隆 github.com/langfuse/langfuse
  • 已修改所有 CHANGEME 密钥(或 .env 覆盖)
  • docker compose up -dlangfuse-web 日志 Ready
  • 浏览器可打开 http://localhost:3000 并登录
  • 已创建 Project 并取得 pk-lf / sk-lf
  • mystu .env 已配置 LANGFUSE_*LANGFUSE_ENABLED=true
  • mystu 发一条 chat 后 Langfuse UI 可见 Trace
  • Session 与 mystu thread_id 可对应(可选:走一遍 HITL resume)