使用 🤗 Gradio 构建 LLM 聊天 UI,并用 🪢 Litefuse 进行追踪

这是一个简洁的端到端示例 notebook,展示了如何将 Gradio 应用与 Litefuse 集成,实现 LLM 的可观测性与评估。

说明: 建议在 Google Colab 中运行本 notebook(见上方链接)。本 notebook 也以 Hugging Face Space 模板的形式提供,地址在这里

感谢 @tkmamidi 对本 notebook 的原始实现与贡献。

简介

什么是 Gradio?

Gradio 是一个开源 Python 库,可以为机器学习模型、API 与 Python 函数快速构建 Web 界面。它允许开发者用交互式 UI 包装任意 Python 函数,方便共享或嵌入,非常适合做 demo、原型和 ML 模型部署。详见文档

什么是 Litefuse?

Litefuse 是一个开源的 AI Agent 可观测性与评估平台,通过 LLM 应用可观测性、评估、实验和 prompt 管理,帮助你构建可靠的 LLM 应用。详见文档

视频讲解

我们录制了下面这段实现讲解。你可以跟着视频或 notebook 一起操作。

内容大纲

本 notebook 会演示如何:

  1. 用 Python 构建一个简单的聊天界面,并使用 Gradio Chatbot 在 notebook 中渲染
  2. 为聊天机器人添加 Litefuse 追踪
  3. 实现聊天应用常用的额外 Litefuse 追踪特性:聊天会话用户反馈

准备

安装依赖。本示例使用 OpenAI,也可以换成任意模型。

注意: 本指南使用的是我们的 Python SDK v2。我们已经基于 OpenTelemetry 发布了更新更强的 SDK,可参考 SDK v3,体验更强大、更简单的使用方式。

# 固定 httpx 版本,因为创建本 notebook 时最新版本与 OpenAI SDK 不兼容
%pip install gradio "langfuse<3.0.0" openai httpx==0.27.2

设置凭证并初始化 Langfuse SDK 客户端,稍后会用它来添加用户反馈。

你可以创建一个免费的 Litefuse Cloud 账号,也可以在几分钟内自托管 Litefuse

import os
 
# 从项目设置页面获取你项目的 Key
# https://litefuse.cloud
os.environ["LANGFUSE_PUBLIC_KEY"] = ""
os.environ["LANGFUSE_SECRET_KEY"] = ""
os.environ["LANGFUSE_BASE_URL"] = "https://litefuse.cloud"
 
# 你的 openai key
# 本 demo 使用 OpenAI,可轻松替换为其他模型
os.environ["OPENAI_API_KEY"] = ""
import gradio as gr
import json
import uuid
from langfuse import Langfuse
 
langfuse = Langfuse()

聊天功能的实现

会话/Thread

Gradio Chatbot 中的每条消息都属于一个 thread,可以通过 clear 重置(参考)。

我们实现下面这个方法来创建一个全局的 session_id,并通过 set_new_session_id 方法重置。该 session_id 会用于 Litefuse 会话

session_id = None
def set_new_session_id():
    global session_id
    session_id = str(uuid.uuid4())
 
# 初始化
set_new_session_id()

响应处理函数

实现 respond 方法时,我们使用 Litefuse 的 @observe() 装饰器 自动将每次响应写入 Litefuse 追踪

此外,我们使用 openai 集成 简化 LLM 调用的 instrumentation,自动捕获模型参数、token 数等元数据。你也可以使用 LangChainLlamaIndex其他框架 的集成,或直接通过装饰器自行 instrument 调用(示例)。

# Langfuse 装饰器
from langfuse.decorators import observe
# 可选:通过 OpenAI SDK 集成实现自动 instrumentation
# 关于其他实现方式见上方说明
from langfuse.openai import openai
from langfuse import propagate_attributes
 
# 全局保存当前 trace_id,用于稍后添加用户反馈
current_trace_id = None
 
# 在此添加装饰器以捕获整体耗时、输入输出,并通过 `langfuse` 操作 trace 元数据
@observe()
async def create_response(
    prompt: str,
    history,
):
    # 把 trace id 保存到全局变量,便于后续添加反馈
    global current_trace_id
    current_trace_id = langfuse.get_current_trace_id()
 
    # 将 session_id 加到 Litefuse Trace 上以启用会话跟踪
    global session_id
    with propagate_attributes(
        trace_name="gradio_demo_chat",
        session_id=session_id,
    ):
 
        # 设置 trace 输入
        langfuse.set_current_trace_io(
            input=prompt,
        )
 
        # 把 prompt 加到历史里
        if not history:
            history = [{"role": "system", "content": "You are a friendly chatbot"}]
        history.append({"role": "user", "content": prompt})
        yield history
 
        # 通过 OpenAI SDK 获取补全
        # 通过 import 自动被 Litefuse instrument,其他方式见上方说明
        response = {"role": "assistant", "content": ""}
        oai_response = openai.chat.completions.create(
            messages=history,
            model="gpt-4o-mini",
        )
        response["content"] = oai_response.choices[0].message.content or ""
 
        # 自定义 trace 输出,便于在 Litefuse 会话中阅读
        langfuse.set_current_trace_io(
            output=response["content"],
        )
 
        yield history + [response]
 
async def respond(prompt: str, history):
    async for message in create_response(prompt, history):
        yield message

用户反馈处理函数

我们通过 Gradio chatbot 的 like 事件实现 Litefuse 中的用户反馈跟踪参考)。此方法复用了本应用全局状态中的当前 trace id。

def handle_like(data: gr.LikeData):
    global current_trace_id
    if data.liked:
        langfuse.score(value=1, name="user-feedback", trace_id=current_trace_id)
    else:
        langfuse.score(value=0, name="user-feedback", trace_id=current_trace_id)

重试

通过 Gradio Chatbot 的 retry 事件支持重新生成补全(文档)。这部分与 Litefuse 集成无关。

async def handle_retry(history, retry_data: gr.RetryData):
    new_history = history[: retry_data.index]
    previous_prompt = history[retry_data.index]["content"]
    async for message in respond(previous_prompt, new_history):
        yield message

运行 Gradio 聊天机器人

实现完上述所有方法后,我们就可以把 Gradio Chatbot 组装起来并启动。如果在 Colab 中运行,你应该会看到一个嵌入的 chatbot 界面。

with gr.Blocks() as demo:
    gr.Markdown("# Chatbot using 🤗 Gradio + Litefuse")
    chatbot = gr.Chatbot(
        label="Chat",
        type="messages",
        show_copy_button=True,
        avatar_images=(
            None,
            "https://static.langfuse.com/cookbooks/gradio/hf-logo.png",
        ),
    )
    prompt = gr.Textbox(max_lines=1, label="Chat Message")
    prompt.submit(respond, [prompt, chatbot], [chatbot])
    chatbot.retry(handle_retry, chatbot, [chatbot])
    chatbot.like(handle_like, None, None)
    chatbot.clear(set_new_session_id)
 
 
if __name__ == "__main__":
    demo.launch(share=True, debug=True)

在 Litefuse 中探索数据

与 chatbot 交互时,你会在 Litefuse 项目中看到 trace、会话以及反馈分数。详见上方视频讲解。

Litefuse 中的 trace、会话和用户反馈示例(公开链接):

Litefuse 中的 Gradio Trace、会话和用户反馈

如果你有任何问题或反馈,欢迎加入 Litefuse Discord 或在 GitHub Discussions 上发起新讨论。

这个页面对你有帮助吗?