avatar

Neo·元

算法的尽头,认知的倒影

  • 首页
  • 三千问道
  • 万法归宗
  • 诗酒田园
  • 关于Neo·元
主页 浅谈Langfuse 生产级全链路观测与排坑指南
文章

浅谈Langfuse 生产级全链路观测与排坑指南

发表于 最近 更新于 最近
作者 Neo
12~15 分钟 阅读

前言

Langfuse 作为目前开源界最出色的 LLM 可观测工具,支持全链路 Trace 追踪、Prompt 管理和成本分析。

我今天在本地 Docker 私有化部署了Langfuse及结合到之前的 LangChain/LangGraph项目 ,下面记录总结一些重要的节点和注意事项。

一、 私有化部署:Docker 环境搭建

Langfuse 官方提供了非常完善的 Docker Compose 部署方案,内部集成了以下核心组件:

  • Web 服务 (langfuse-web):提供前端 UI 及 API 服务。

  • Worker (langfuse-worker):处理后台异步任务与数据上报。

  • Postgres:存储用户、项目配置与关系元数据。

  • ClickHouse:高性能列式数据库,专门存储海量 Trace 日志。

  • Redis:充当后台任务队列与缓存。

1. 启动 Docker 服务

在 docker-compose.yml 目录下执行:

Bash

docker compose up -d

启动后,可以通过 http://localhost:3000 访问 Langfuse 控制台并注册管理员账号。

二、 工程接入:LangChain / LangGraph 整合

在 LangChain 及 LangGraph (v2) 中接入 Langfuse 非常简洁,核心在于利用其提供的 CallbackHandler 机制。

1. 环境变量配置 (.env)

代码段

LANGFUSE_PUBLIC_KEY="pk-lf-***"
LANGFUSE_SECRET_KEY="sk-lf-***"
#这里最好不要用localhost,就用127.0.0.1
LANGFUSE_HOST="http://127.0.0.1:3000"

2. LangGraph 状态图绑定示例

在异步流式输出或图执行时,将 CallbackHandler 传入 config 中:

Python

from langfuse.langchain import CallbackHandler
from langfuse import Langfuse

async def get_stream_response(self, question: str, session_id: str):
    # 1. 实例化CallbackHandler(自动读取 .env 环境变量)
    langfuse_handler = CallbackHandler()

    config = {
        "recursion_limit": 100,
        "callbacks": [langfuse_handler],
        "metadata": {
            # 绑定 session_id 实现会话级别的 Trace 归类
            "langfuse_session_id": session_id 
        }
    }

    try:
        # 执行 LangGraph 图链
        async for event in self.graph.astream_events(initial_state, config=config, version="v2"):
            # 处理流式事件
            pass
    finally:
        # 手动刷新
        try:
            Langfuse().flush()
        except Exception as e:
            logger.warning(f"Langfuse flush 提醒: {e}")

三、 实战避坑指南

在实际部署与调试过程中,笔者遇到过几个非常具有代表性的工程问题,特此总结记录:

1. 报错 HTTPConnectionPool Read timed out

  • 现象:测试脚本运行结束,控制台抛出 Failed to export span batch ... Read timed out,Langfuse 后台找不到任何 Trace。

  • 排查与原因:

    1. IPv6 解析延迟:Windows/WSL2 环境下,localhost 会优先尝试 IPv6 地址 (::1),导致通信卡死超时。将 LANGFUSE_HOST 改为 [http://127.0.0.1:3000](http://127.0.0.1:3000) 可解决此问题。

    2. 组件依赖缺失:因误将 Docker 容器中的 Redis 停止并卸载,导致 langfuse-web 内部报 Error: getaddrinfo ENOTFOUND redis 异常。

这里简单说一下,langfuse集群内部使用的Redis和我本地跑的Redis是两码事,我本地之前在做LangChain\LangGraph流式输出的时候,有用到过,就是在agent_service里调用过这句(redis://localhost:6379/0),在docker安装好Langfuse的时候,在本地运行redis会报错,端口占用,这个时候如果去把docker里的redis暂停或删除,就可以了。然后启动本地Redis后,因为langfuse工作是离不开redis的时候,这个时候切记要去在docker里把他的redis给跑起来,要不就会卡在推送不到Tracing。

2. LLM 未能正确触发 Tool Calling

  • 现象:前台询问“青岛天气”,模型回复“请提供您所在的城市名称”,且 Langfuse 中显示未调用 get_weather 工具。

  • 原因分析:

    • Tool Docstring 不够直接:小模型(如 Qwen2.5 3B/Llama3)无法精准从“青岛天气”中提取 city="青岛" 参数。

    • System Prompt 约束模糊:提示词中写有“非汽车问题可以不调用工具”,导致模型倾向于直接回答而非触发 Tool Call。

    • Redis 历史会话污染:先前回答过的“请提供城市”被记录在 RedisChatMessageHistory 中,引发模型上下文模仿。

  • 解决方法:

    1. 优化 Tool Docstring,明确告知提取规则(如:“当用户输入中包含城市时,直接提取城市名并调用”)。

    2. 强化 SYSTEM_PROMPT 中关于工具调用的硬性规则。

    3. 清理 Redis 旧 Session 历史或更换新的 session_id 进行测试

这里也简单说明一下,跟LangFuse关系不是很大,纯粹顺手升级了一下 原先的weather_tool类。

四、 运维与数据占用分析

本地存储占用空间不大,Langfuse 的 Trace 主要是文本,存放在 ClickHouse 列式数据库中,压缩比通常可达 10:1 以上。数千条 Trace 数据实际占用的磁盘空间仅数十兆。如果希望清理测试环境的脏数据,只需进入 Docker 目录执行:

docker compose down -v && docker compose up -d

许可协议:  CC BY 4.0
分享

相关文章

下一篇

浅谈治理RAG 混合检索+重排序 (续)

上一篇

最近更新

  • 浅谈Langfuse 生产级全链路观测与排坑指南
  • 浅谈治理RAG 混合检索+重排序 (续)
  • 浅谈治理RAG 升级RAG 混合检索+重排序
  • 浅谈LangChain升级LangGraph
  • 浅谈LangChain的用法

热门标签

AI

©2026 All Rights Reserved Neo 鲁ICP备2026037083号