Agent开发应知应会(Langfuse):Langfuse Session概念详解和实战应用

最近在做一个 Text-to-SQL 的 Agent 项目 EasySQL,这篇文章就把我langfuse的session使用整理一下,代码都是从项目里直接搬的,欢迎大佬们高抬贵手点点star,共建、交流。

Langfuse官方文档的原文定义

Many interactions with LLM applications span multiple traces and observations. Sessions in Langfuse are a special way to group these observations across traces together and see a simple session replay of the entire interaction. Optionally, traces can be grouped into sessions. Sessions are used to group traces that are part of the same user interaction. A common example is a thread in a chat interface.

翻译一下:一次用户与 LLM 应用的交互往往不只一个请求。比如用户在聊天界面中连续问了 3 个问题,每个问题是一个独立的 Trace(一次完整的 LLM调用链路),但它们属于同一次会话。Session 就是把这些相关的 Trace 归到一组。

Session
session_id 格式 任意 US-ASCII 字符串,小于 200 字符
归组逻辑 所有携带相同 session_id 的 Trace 自动归入同一个 Session
创建时机 无需显式创建 Session 对象,第一个携带该 session_id 的 Trace 出现时自动创建
Trace 的关系 一个 Session 包含多个 Trace,一个 Trace 只属于一个 Session

项目举例

没有Session时:这两个Trace(一个会话中的两个问答) 在Langfuse Dashboard中是散落的,你不知道它们之间有关联。有Session时:点进某个Session,能看到完整的多次对话回放------用户从第1个问题到第3个问题的完整链路。

无session的情况下,所有的trace都集中展示无法筛选

有session的情况,可以根据session展示,我这里就可以通过同个session来观察第二个问题有没有取得第一个问题的历史对话上下文,由此来判断代码中的处理是否合理

也可以在Dashboards中筛选

代码实现

核心代码在 query_service.py。也就是创建一个会话session id的地方,由于项目中已经设置了session id来区分不同的会话,所以这里可以直接复用,保证langfuse中的session id和数据库中的会话session id一致。这样做的好处是:当在 Langfuse Dashboard 中看到某个Session 有问题时,可以直接用这个 ID 去业务数据库中查对应的会话记录,两边的 ID 是一致的。(这也是我认为最重要的一点)

python 复制代码
  def _make_config(self, session_id: str, thread_id: str | None = None) -> RunnableConfig:
      effective_thread_id = thread_id or session_id
      config: RunnableConfig = {"configurable": {"thread_id": effective_thread_id}}
      if self.callbacks:
          config["callbacks"] = self.callbacks
          config["metadata"] = {                          # ← 关键
              "langfuse_session_id": session_id,          # ← Session 隔离
              "langfuse_tags": ["text2sql"],              # ← 标签
          }
          logger.debug(f"LangFuse callbacks attached: {len(self.callbacks)} handler(s)")
      return config
python 复制代码
    async for chunk in self.graph.astream(
        input_state,
        self._make_config(session.session_id, effective_thread_id),
        stream_mode=["updates", "custom"],
    ):

工作原理

这里用的是 Langfuse 官方推荐的 metadata 传参方式。官方文档原文:

With the Python SDK, you can set trace attributes dynamically via metadata fields in chain invocation by passing a config dictionary.This is the simplest approach for adding trace context to your LangChain executions without additional setup.

官方示例:

python 复制代码
 response = chain.invoke(
      {"topic": "cats"},
      config={
          "callbacks": [langfuse_handler],
          "metadata": {
              "langfuse_user_id": "random-user",
              "langfuse_session_id": "random-session",     
              "langfuse_tags": ["random-tag-1", "random-tag-2"] 
          }
      }
  )

Session带来的监控意义

Session 级别的聚合分析
每个 Session 的 Trace 数量 用户平均问几轮才完成任务 ** 轮次多 = 可能需要优化追问体验**
每个 Session 的 总 Token 一次完整交互的总消耗 评估单次用户交互的成本
每个 Session 的 总延迟 用户完成任务的总等待时间 评估端到端的用户体验
每个 Session 的 失败 Trace 比例 多轮中有几轮出错 定位哪些类型的追问容易失败
对比没有session
场景 没有 Session 有 Session
查看某用户的完整交互 需要自己按时间排序、手动关联 直接点进 Session 看回放
统计"用户平均几轮完成任务" 无法统计 Dashboard 直接提供
分析"追问时 SQL 质量是否下降" 需要导出数据写脚本 按 Session 内的 Trace 顺序直接对比
定位"用户反馈体验差"的问题 只能逐条 Trace 查看 拿到 session_id 直接看全过程

总结

session是一个很小的知识点,但是使用的好对我们整个agent开发带来的增益是巨大。

以上所有代码示例均来自我的开源项目 EasySQL ------ 一个 Text-to-SQL 智能体分析应用,项目地址:github.com/zaizaizhao/...。项目主要技术栈包括:

  • LangGraph:构建多步骤 Agent 状态机,支持条件路由、Human-in-the-Loop 澄清、SQL 生成→验证→修复的迭代循环
  • LangChain:LLM 调用抽象与 RunnableConfig 配置传递
  • Langfuse:Callback + 手动 Span 双模式可观测性,实现全链路追踪与业务汇总
  • PostgreSQL + AsyncPostgresSaver:LangGraph Checkpointer 状态持久化,支持多轮对话上下文
  • FastAPI + Uvicorn:异步 API 服务层,提供流式 SSE 响应
  • Milvus:向量数据库,用于 Schema 语义检索
  • Neo4j: 图数据库,用于知识图谱构建
  • Pydantic Settings:类型安全的配置管理,支持环境变量覆盖

项目示例

欢迎 Star ⭐ 和交流、共建!

相关推荐
王_teacher5 小时前
RNN 循环神经网络 计算过程(通俗+公式版+运行实例)
人工智能·rnn·nlp
玩转单片机与嵌入式5 小时前
一个成熟的嵌入式AI系统,是长什么样子的?
人工智能·单片机·嵌入式硬件·嵌入式ai
u0109147607 小时前
CSS组件库如何快速扩展_通过Sass @extend继承基础布局
jvm·数据库·python
baidu_340998827 小时前
Golang怎么用go-noescape优化性能_Golang如何使用编译器指令控制逃逸分析行为【进阶】
jvm·数据库·python
m0_678485457 小时前
如何利用虚拟 DOM 实现无痕刷新?基于 VNode 对比的状态保持技巧
jvm·数据库·python
qq_342295827 小时前
CSS如何实现透明背景效果_通过RGBA色彩模式控制透明度
jvm·数据库·python
TechWayfarer7 小时前
知乎/微博的IP属地显示为什么偶尔错误?用IP归属地查询平台自检工具3步验证
网络·python·网络协议·tcp/ip·网络安全
Greyson17 小时前
CSS如何处理超长文本换行问题_结合word-wrap属性
jvm·数据库·python
曦樂~8 小时前
【机器学习】概述
人工智能·机器学习
justjinji8 小时前
如何批量更新SQL数据表_使用UPDATE JOIN语法提升效率
jvm·数据库·python