跳至主要内容

LangFuse 教程:用于监控与评测的 LLM 工程平台

构建一个文档问答工具,同时了解 LangFuse 如何在复杂 LLM 应用中简化调试、跟踪成本并组织提示词。
· 15分钟 阅读

使用 AI 探索

构建 LLM 应用很快就会变得一团糟。您开始对成本凭感觉估算;看不到发生了什么时,调试失败会更难;提示词散落在代码库各处。LangFuse 通过一个平台解决这些问题:它跟踪一切、管理提示词并衡量质量。

在本教程中,您将构建一个文档问答工具,并了解 LangFuse 如何组织您的开发流程。您将学会为调试追踪 LLM 调用、用版本控制管理提示词,并探索评估方法。

什么是 LangFuse?

LangFuse 是一个开源平台,帮助团队构建更好的 LLM 应用。您专注于功能开发时,LangFuse 负责监控、测试与调试。

该平台涵盖三个核心领域:

  1. 可观测性:查看 LLM 运行时的实际情况。跟踪成本、定位错误,并了解用户如何与应用交互。不再需要猜测为什么出错,或上个月 OpenAI 向您收了多少钱。
  2. 提示词管理:将提示词集中存储与版本化,而不是散落在代码库里。团队无需改动生产代码即可测试不同版本。
  3. 评估:衡量 LLM 的表现。设置自动化测试,检查回复是否合理、是否不跑题,以及是否符合质量标准。

何时应使用 LangFuse?

当您的 LLM 应用超越简单试验阶段时,您会需要 LangFuse。以下情形下它会特别有价值:

  • 多人协作编辑提示词,您需要版本控制
  • 生产应用需要跟踪成本并监控性能
  • 复杂工作流如 RAG 系统、多智能体设置或对话链路
  • 质量诉求需要系统化测试,而非人工抽查

如果您只是在做一个快速原型或个人项目,暂时可能用不上。但一旦应用需要面向真实用户,或团队不止一人,LangFuse 就会变得有用。

采用与集成

LangFuse 能与您现有的 AI 技术栈配合使用。它可集成 LangChain、LlamaIndex、AutoGen 和 CrewAI 等主流框架。您可以搭配任意模型提供商——OpenAI、Anthropic、Google Gemini、Mistral 或 Hugging Face 模型都可直接使用。

该平台提供 Python 与 JavaScript 的原生 SDK,并支持 OpenTelemetry 以适配自定义方案。无论您使用零代码的智能体构建器,还是复杂的多智能体框架,LangFuse 都能无缝接入而无需更改核心架构。

诸如 Samsara、Twilio 和 Khan Academy 等公司已在生产中使用它,并满足企业级安全标准。该项目在 GitHub 上拥有 16,500 颗星,并获得 Y Combinator 支持。您可以使用其托管版本,或在自有基础设施上运行。

既然您已了解 LangFuse 的作用与适用场景,接下来我们用它来构建点实际的东西。如前所述,我们将创建一个简单的文档问答工具,展示这三大功能如何协同工作。

先决条件

在深入使用 LangFuse 之前,您需要具备一些 Python 和 LLM 经验。

必备:

  • Python 3.8+ 与基础 API 知识
  • OpenAI API 使用经验(我们将使用 GPT-4)
  • LangChain 基础——提示词、链与核心概念

加分项:

  • 了解嵌入与检索模式
  • 具备提示词工程经验

环境设置:

  • OpenAI API 密钥
  • Python 包管理器(uv 或 pip)
  • 我们将一起创建一个免费的 LangFuse 账户

AI 开发新手?请先从我们的 完整 AI 学习指南开始。

想了解 LangFuse 在更大生态中的定位,请查看我们的 LLMOps 工具概览。

现在开始动手。我们将从一个简单的文档问答函数入手,看看 LangFuse 如何在运行时追踪发生的事情。这个基础示例会以可扩展到更复杂项目的方式,展示三大核心功能——可观测性、提示词管理与评估。

使用 LangFuse 构建文档问答工具

您将构建一个简单的文档问答系统,从 PDF 中回答问题。这将为追踪、管理和评估提供一个真实示例。尽管我们保持示例简单,相同模式同样适用于复杂的 RAG 系统与多智能体工作流。

环境搭建

首先,为项目创建一个目录并安装所需包:

mkdir langfuse-qa-demo
cd langfuse-qa-demo
uv add langfuse langchain langchain-openai langchain-community pypdf python-dotenv

在 langfuse.com 注册一个免费的 LangFuse Cloud 账户。登录后,创建一个新组织与项目。您将看到包含 API 密钥的界面:

LangFuse 仪表盘显示新项目的 API 密钥,包括 Public Key 与 Secret Key 字段

复制您的 Public Key 与 Secret Key。您还需要从 platform.openai.com 获取 OpenAI API 密钥。

现在在项目目录中创建一个 .env 文件:

OPENAI_API_KEY=your_openai_key_here
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=https://cloud.langfuse.com

如果您更喜欢在自有基础设施上运行 LangFuse,可以使用 Docker Compose 进行本地测试。请参阅 自托管指南,其中介绍了如何设置 PostgreSQL、ClickHouse 和 LangFuse 服务。生产部署建议使用 Kubernetes 或面向云的 Terraform 模板。

在 LangChain 中构建文档问答链

您将构建一个检索链:加载 PDF,将其切分为片段,存储到向量数据库中,并基于检索到的上下文回答问题。

创建一个名为 qa_chain.py 的文件:

from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_core.vectorstores import InMemoryVectorStore
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
from dotenv import load_dotenv

load_dotenv()

这段代码导入了所有所需内容。load_dotenv() 会从 .env 文件中加载您的 API 密钥。

# Load and split PDF
loader = PyPDFLoader("ai-security-landscape.pdf")
docs = loader.load()

text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)

这里我们加载的是 ai-security-landscape.pdf 文档,这是 Amazon Web Services 撰写的一篇白皮书。要运行该示例,您需要 自行下载该文件,并以正确名称添加到工作目录。

PyPDFLoader 用于读取 PDF,而 RecursiveCharacterTextSplitter 将其按 1000 字符分块,块间有 200 字符重叠。重叠有助于在块边界间维持上下文。

接下来,创建向量存储:

# Create vector store
embeddings = OpenAIEmbeddings()
vectorstore = InMemoryVectorStore.from_documents(documents=splits, embedding=embeddings)

InMemoryVectorStore 将文档嵌入存储在内存中。在生产环境中,您会使用 Pinecone、Weaviate 或其他向量数据库。

现在构建 QA 链:

# Build QA chain
llm = ChatOpenAI(model="gpt-4")
prompt = ChatPromptTemplate.from_messages([
   ("system", "Use the given context to answer the question. If you don't know the answer, say you don't know. Keep the answer concise.\n\n{context}"),
   ("human", "{input}"),
])

question_answer_chain = create_stuff_documents_chain(llm, prompt)
qa_chain = create_retrieval_chain(vectorstore.as_retriever(), question_answer_chain)

create_stuff_documents_chain 会将检索到的文档“塞进”提示词上下文中。create_retrieval_chain 则把检索与回答组合为一条链。

链路准备就绪后,让我们将其接入 LangFuse 以进行追踪。

用 LangFuse 追踪您的首次调用

向脚本添加一个 LangFuse 回调处理器:

from langfuse.langchain import CallbackHandler

langfuse_handler = CallbackHandler()

response = qa_chain.invoke(
   {"input": "What are the main security risks discussed?"},
   config={"callbacks": [langfuse_handler]}
)

print(response["answer"])
The main security risks discussed in relation to generative artificial intelligence (AI) are context window overflow, agent mismanagement, indirect prompt injections and data leaks from overprivileged agents, logging, and caching.

Trace sent to LangFuse! Check your dashboard at https://cloud.langfuse.com

运行后,LangFuse 会捕获完整的执行轨迹。前往 LangFuse 仪表盘,您会看到其中更新了新的详情:

LangFuse 仪表盘显示首次被追踪的问答链执行,含耗时与令牌指标

请注意,尽管我们这里用的是简单示例,LangFuse 同样适用于复杂的 RAG 流水线,例如处理多种文档类型、采用重排序,或并行运行多种检索策略。

随着您的问答系统运行并接入 LangFuse 追踪,您已准备好理解 LangFuse 捕获了什么,以及如何利用这些信息改进应用。

LangFuse 中的可观测性

您刚刚向 LangFuse 发送了一条轨迹。现在,让我们理解这能带来什么价值。

为何 LLM 可观测性重要

传统日志对 LLM 应用并不奏效。您可以记录一个函数被调用,但无法看到模型对用户输入到底做了什么。是否检索到了正确的文档?提示词格式是否正确?是哪一步耗时五秒?

LLM 可观测性会追踪整个执行路径。您能看到每个输入、输出和中间步骤。当用户反馈答案错误时,您可以调出他们的轨迹,准确复现发生了什么。不用猜,心里有数。

随着应用复杂度上升,这更为关键。一个简单的问答链只有 4–5 个步骤。生产级 RAG 系统则包含文档加载、切分策略、多个检索器、重排序和生成步骤。缺乏可观测性,调试几乎不可能;具备可观测性,问题即可精准定位。

理解轨迹与会话

打开 LangFuse 仪表盘,点击左侧边栏的“Tracing(追踪)”。您会在表格中看到第一条轨迹。

表格显示了轨迹的运行时间、名称(retrieval_chain)、以及输入输出。每一行代表一次完整的问答链执行。

点击该轨迹以查看内部发生了什么,您会得到详细拆解。

左侧面板显示执行树。LangFuse 追踪了链中的每一步。根节点 retrieval_chain 总耗时 4.75 秒。其下列出每个运行的操作:文档检索(retrieve_documents)、向量搜索(VectorStoreRetriever)以及答案生成(stuff_documents_chain)。每一步都显示其执行时间。

这个层级结构告诉您链路的耗时分布。如果应用变慢,您能判断是嵌入查找、向量搜索还是 LLM 调用导致。

右侧面板展示轨迹数据。顶部是关键指标:时延(4.75s)、成本(约 $0.016)与令牌使用量(426 输入、55 输出)。下方显示实际的输入与输出。context 区域展示了检索器从向量存储中拉取的四个文档片段。

底部的流程图映射了链路的操作连接关系。在调试具有多分支的复杂链时,这很有帮助。

接下来谈谈会话。轨迹捕获了一次问答循环。但真实应用通常是对话。用户可能会围绕安全风险连问三题。您希望将这些轨迹归组。

这正是会话的作用。它把多条轨迹捆绑为一条对话线索。当用户报告问题时,您可以调出其完整会话,查看其提出的每个问题与获得的每个回答。

我们来看一个示例。首先,创建一个名为 build_chain.py 的辅助文件,将构建链的逻辑封装起来:

from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_core.vectorstores import InMemoryVectorStore
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate
from dotenv import load_dotenv

load_dotenv()

def build_qa_chain():
   # Load and split PDF
   loader = PyPDFLoader("ai-security-landscape.pdf")
   docs = loader.load()

   text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
   splits = text_splitter.split_documents(docs)

   # Create vector store
   embeddings = OpenAIEmbeddings()
   vectorstore = InMemoryVectorStore.from_documents(documents=splits, embedding=embeddings)

   # Build QA chain
   llm = ChatOpenAI(model="gpt-4")
   prompt = ChatPromptTemplate.from_messages([
       ("system", "Use the given context to answer the question. If you don't know the answer, say you don't know. Keep the answer concise.\n\n{context}"),
       ("human", "{input}"),
   ])

   question_answer_chain = create_stuff_documents_chain(llm, prompt)
   qa_chain = create_retrieval_chain(vectorstore.as_retriever(), question_answer_chain)

   return qa_chain

这会将一切封装在一个可导入的函数中。现在创建 sessions_demo.py:

from build_chain import build_qa_chain
from langfuse.langchain import CallbackHandler

# Build the Q&A chain
qa_chain = build_qa_chain()

# Set up LangFuse handler
langfuse_handler = CallbackHandler()
This imports your chain and sets up the LangFuse handler. Now add session tracking for the first conversation:
# Session 1: User asking about security risks
response1 = qa_chain.invoke(
   {"input": "What are the main security risks discussed?"},
   config={
       "callbacks": [langfuse_handler],
       "metadata": {"langfuse_session_id": "conversation-001"}
   }
)
print(f"Q1: {response1['answer']}\n")

metadata 字段中的 langfuse_session_id 会用会话 ID 标记此轨迹。运行后您会看到:

Q1: The main security risks discussed are context window overflow, agent mismanagement, and indirect prompt injections.

现在用同一会话 ID 添加一个追问:

response2 = qa_chain.invoke(
   {"input": "How can these risks be mitigated?"},
   config={
       "callbacks": [langfuse_handler],
       "metadata": {"langfuse_session_id": "conversation-001"}
   }
)
print(f"Q2: {response2['answer']}\n")

第二个问题属于同一对话,因此仍使用 conversation-001。您将看到更长的回答:

Q2: Risks can be mitigated through several strategies including:
1. Input Management: Limit and sanitize inputs going into the model.
2. Real-time Monitoring: Use systems that alert when the context window is nearing capacity.
3. Principle of Least Privilege: Implement this for all agents and external integrations.
....

现在模拟第二位用户提出不同问题。将以下内容添加到脚本:

# Session 2: Different user asking about AI applications
response3 = qa_chain.invoke(
   {"input": "What AI applications are mentioned in the document?"},
   config={
       "callbacks": [langfuse_handler],
       "metadata": {"langfuse_session_id": "conversation-002"}
   }
)
print(f"Q3: {response3['answer']}\n")

response4 = qa_chain.invoke(
   {"input": "What are the benefits of these applications?"},
   config={
       "callbacks": [langfuse_handler],
       "metadata": {"langfuse_session_id": "conversation-002"}
   }
)
print(f"Q4: {response4['answer']}\n")

这两个问题使用 conversation-002。运行完整脚本:

uv run python sessions_demo.py

最后两条输出将是:

Q3: The document does not specifically mention any AI applications. However, it discusses the concept of generative AI and its security considerations.

Q4: The context does not provide specific benefits of these applications.

前往 LangFuse 仪表盘,点击左侧边栏的“Sessions(会话)”。您将看到两条对话:

出现两个会话:conversation-002(约 4 秒)与 conversation-001(约 14 秒)。LangFuse 会按会话 ID 对轨迹进行分组。

点击 conversation-001 可查看完整对话:

LangFuse 会话详情页显示两个相关轨迹,问题涉及安全风险与缓解策略

您会按顺序看到两条轨迹:问题 1 关于安全风险,问题 2 关于缓解措施。会话显示总成本(两条轨迹合计 $0.05121)与总时长(14 秒)。每条轨迹都包含输入、输出与检索到的上下文。

该会话视图精确呈现用户在交互中的体验。如果他们报告问题,您无需在单条轨迹中反复查找,只需打开其会话即可看到完整对话流程。

用户追踪

到目前为止,您已追踪了会话,但个体用户呢?真实的 LLM 应用需要知道是谁发起了哪个请求。有人注册时,您会为其生成一个唯一 ID,并将该 ID 附着在其每次 LLM 调用上。

LangFuse 支持在会话分组之上按用户 ID 对轨迹分组。这为组织可观测性数据提供了另一种视角。

以下是添加用户追踪的方法。创建 user_tracking.py:

from build_chain import build_qa_chain
from langfuse.langchain import CallbackHandler

# Build the Q&A chain
qa_chain = build_qa_chain()

# Set up LangFuse handler
langfuse_handler = CallbackHandler()

# Simulate a new user asking a question
user_response = qa_chain.invoke(
   {"input": "What security controls are recommended for AI systems?"},
   config={
       "callbacks": [langfuse_handler],
       "metadata": {
           "langfuse_session_id": "conversation-003",
           "langfuse_user_id": "user-12345"
       }
   }
)
print(f"Response: {user_response['answer']}")

langfuse_user_id 字段用用户 ID 标记该轨迹。运行脚本:

uv run python user_tracking.py

您将看到:

Response: The recommended security controls for AI systems include:

1. Adaptive defenses: Incorporate machine learning-powered filters that continuously learn and adapt to new adversarial techniques.
2. Defense-in-depth: Introduce layered security mechanisms, such as refusal classifiers and real-time input monitoring, to fortify AI system integrity.
3. Data classification: Properly classify your data according to sensitivity.
......

现在前往 LangFuse 仪表盘。点击左侧边栏的“Users(用户)”,您会看到 user-12345。点击该用户即可查看其跨会话的所有轨迹。

该用户视图可帮助您回答诸如“某用户本月花费了我们多少钱?”或“某用户反复在问哪些问题?”之类的问题。您可以追踪个体用户行为并调试特定用户的问题。

LangFuse 中的提示词管理

您的问答系统有个问题:提示词被埋在代码里。若想更改系统回复方式,您需要修改 qa_chain.py、本地测试并重新部署。如果队友想尝试不同做法,他们需要理解您的代码结构并创建新分支。您无法并排比较不同提示词版本,或不翻阅 Git 历史就回滚到上周的版本。

提示词管理通过将提示词从代码中剥离来解决这一问题。您可在 UI 中编辑、自动版本化,并在运行时提取。代码保持不变,提示词不断改进。

协作式提示词之痛

看看您问答链中的提示词:

prompt = ChatPromptTemplate.from_messages([
   ("system", "Use the given context to answer the question. If you don't know the answer, say you don't know. Keep the answer concise.\n\n{context}"),
   ("human", "{input}"),
])

这对个人项目来说够用。但在团队协作或生产环境中,硬编码提示词会带来问题:

  • 部署摩擦:每次修改提示词都要部署代码。您无法在不改动应用代码的情况下做提示词 A/B 测试。若想把 “Be brief and factual” 改成 “Keep the answer concise”,就得提交、推送并重新部署。
  • 缺乏版本控制:Git 跟踪代码变更,但无法告诉您哪个提示词版本在生产中的表现更好。您看不到“prompt v1” 与 “prompt v2” 的指标对比,也无法在不部署代码的情况下快速回滚到上一版本。
  • 团队瓶颈:非技术成员无法迭代提示词。产品经理也许有更好的措辞建议,但需要工程师修改。这会拖慢试验节奏。
  • 测试困难:对比提示词变体意味着要运行多份代码。若想并排测试简洁与详细回复,就得手工处理。

LangFuse 的提示词管理通过将提示词视为数据而非代码,来解决这些问题。

创建与版本化提示词

LangFuse 将提示词集中存储并自动版本化。您可以通过 UI 或 SDK 创建提示词。

在 UI 中创建提示词

前往 LangFuse 仪表盘,点击左侧边栏的“Prompts(提示词)”。点击“New Prompt(新建提示词)”开始创建。

您将看到一个表单,可以:

  • 为提示词命名(使用 document-qa-prompt)
  • 选择类型(text 或 chat)
  • 使用 {{variable}} 语法编写带变量的提示词模板
  • 设置模型与温度等配置
  • 添加标签标记版本(如 production 或 staging)

对于我们的问答系统,创建一个包含两条消息的对话提示词:

系统消息:

Use the given context to answer the question. If you don't know the answer, say you don't know. Keep the answer concise.

{{context}}

用户消息:

{{input}}

LangFuse 将自动识别 {{context}} 与 {{input}} 变量。

然后将配置设置为:

{
 "model": "gpt-4",
 "temperature": 0.0
}

添加 production 标签,将其标记为生产版本。

保存后,LangFuse 会创建该提示词的版本 1。每次编辑并保存,都会创建一个新版本;旧版本将保留可用。

通过 SDK 创建提示词

您也可以使用 Python SDK 创建提示词:

from langfuse import Langfuse

langfuse = Langfuse()

langfuse.create_prompt(
   name="document-qa-prompt",
   type="chat",
   prompt=[
       {"role": "system", "content": "Use the given context to answer the question. If you don't know the answer, say you don't know. Keep the answer concise.\n\n{{context}}"},
       {"role": "user", "content": "{{input}}"}
   ],
   labels=["production"]
)

这将以编程方式创建相同的提示词。如果使用相同名称再次调用 create_prompt(),LangFuse 会添加新版本而不是覆盖。

用标签进行版本控制

LangFuse 会用版本号(v1、v2、v3)跟踪每次提示词变更。您还可以给版本分配标签。标签有助于管理部署:

  • production - 生产应用使用的版本
  • staging - 预发布环境使用的版本
  • latest - 自动指向最新版本

当您改进提示词时,会创建一个新版本。先在预发布环境测试,为其添加 staging 标签。确认效果良好后,将 production 标签切换到新版本。生产应用会在下次拉取提示词时自动生效。

在 playground 中测试变体

LangFuse 的 UI 包含一个 playground,您可以在正式使用前测试提示词。您可以:

  • 尝试不同的变量取值
  • 并排比较多个版本
  • 观察更改对输出的影响
  • 与团队分享测试结果

这使非技术成员无需动代码就能探索措辞。

在代码中集成托管提示词

以下展示如何在应用中使用 LangFuse 托管的提示词。此流程让代码保持稳定,同时提示词可持续演进。

步骤 1:拉取提示词

在应用代码中,从 LangFuse 拉取提示词而非硬编码:

from langfuse import Langfuse

langfuse = Langfuse()

# Get the production version
prompt = langfuse.get_prompt("document-qa-prompt", type="chat")

这会拉取带有 production 标签的版本。LangFuse 在客户端缓存提示词,因此不会给 LLM 调用带来时延影响。

您也可以按特定版本或标签拉取:

# Get version 2 specifically
prompt = langfuse.get_prompt("document-qa-prompt", version=2, type="chat")

# Get staging version
prompt = langfuse.get_prompt("document-qa-prompt", label="staging", type="chat")

# Get latest version (automatically maintained by LangFuse)
prompt = langfuse.get_prompt("document-qa-prompt", label="latest", type="chat")

步骤 2:用变量编译提示词

拉取到的提示词是带有 {{variables}} 的模板。通过替换变量为实际值来编译:

compiled_messages = prompt.compile(
   context="Retrieved document context goes here",
   input="What are the main security risks?"
)

这会返回一组可直接发送给 LLM 的对话消息:

[
   {
       "role": "system",
       "content": "Use the given context to answer the question. If you don't know the answer, say you don't know. Keep the answer concise.\n\nRetrieved document context goes here"
   },
   {
       "role": "user",
       "content": "What are the main security risks?"
   }
]

步骤 3:将编译后的提示词用于 LLM

将编译后的消息传给您的 LLM 调用。具体代码取决于您使用 LangChain、OpenAI SDK 还是其他框架。

步骤 4:将提示词与轨迹关联

当您用 LangFuse 托管的提示词进行 LLM 调用时,请将其与轨迹关联。这能让您看到每次 LLM 调用使用的是哪个提示词版本,并按版本跟踪指标:

from langfuse.langchain import CallbackHandler

langfuse_handler = CallbackHandler()

response = qa_chain.invoke(
   {"input": "What are the main security risks?"},
   config={"callbacks": [langfuse_handler]}
)

在 LangFuse 仪表盘中,您会看到按提示词名称与版本分组的轨迹。这可以展示哪些版本成本更高、运行更慢或产出更好。

步骤 5:无需改代码即可迭代

这正是提示词管理的价值所在。要改进提示词:

  1. 打开 LangFuse UI
  2. 编辑提示词(会自动创建新版本)
  3. 在 playground 中测试
  4. 赋予 staging 标签以在预发布环境中测试
  5. 切换 production 标签以部署

您的代码无需变更。下次调用 get_prompt() 时就会拉取到新版本。

步骤 6:需要时回滚

如果新提示词表现更差,只需将 production 标签切回上一个版本。无需部署代码。

该工作流将提示词工程与软件工程解耦。团队可以快速迭代提示词,而应用代码保持稳定。

延伸阅读: LangFuse 还支持提示词版本的 A/B 测试(自动分流)、提示词变更的 Webhooks 通知,以及评论与审批等团队协作功能。这些高级能力帮助大型团队在规模化场景管理提示词。详见 提示词管理文档。

LangFuse 中的评估

您已构建了问答系统,添加了可观测性并设置了提示词管理。但如何判断答案是否“好”?目前您可能在手动测试:提问、阅读回答并判断是否合理。少量示例还能应付,但这无法扩展。

当您更改提示词时,会发生什么?您需要重测全部用例。边界情况怎么办?您不可能记住测试过的每个问题。而在生产部署后,您也无法衡量提示词 v2 是否优于 v1。

评估通过系统化的方式衡量 LLM 表现来解决问题。LangFuse 提供工具自动为回复打分、用真实指标对比提示词版本,并在用户感知之前捕捉质量问题。

系统化的 LLM 评估方法

人工测试能告诉您某个具体回答是否不错;系统化评估能告诉您整个系统在数百或上千个样例上是否可靠。

在 LangFuse 中,系统化评估的流程如下:

  1. 构建测试数据集:收集 20–50 个能代表真实使用的提问,包括答案不在文档中的边界情况。
  2. 选择评分方法:决定对问答系统重要的质量维度(下一节将介绍)。
  3. 用数据集运行系统:处理每个问题,并将结果作为轨迹记录到 LangFuse。
  4. 为回复打分:自动对每个回复应用评分方法。
  5. 分析结果:LangFuse 会聚合测试集上的分数,并展示失败样例。
  6. 迭代与对比:调整提示词,重新跑测试集,并用指标比较是否有所提升。

该流程用“新提示词相关性得分 0.85,旧版为 0.72”替代了“我觉得这个更好”。

欲了解完整评估方法与在 LangFuse 中的实现,请参阅 评估概览文档。

理解“以 LLM 为裁判”的评估

您需要为数百条回复打分,手工进行耗时巨大。“以 LLM 为裁判”通过另一模型来给主模型输出打分,从而实现自动化。

其工作原理

您向裁判 LLM 提供三样东西:原始问题、问答系统的回答、以及评分标准。裁判阅读回答并给出分数。

对于问答系统,您会关注不同的质量维度。以下是三种可能的裁判:

正确性裁判:“评估该答案是否正确反映了所给上下文中的信息。完全正确得 1,部分正确得 0.5,不正确或幻觉内容得 0。”

它能捕捉与文档相矛盾或凭空捏造的回答。

相关性裁判:“评估该答案是否直接回应了所提问题。高度相关得 1,部分相关得 0.5,跑题得 0。”

这可确保系统不跑题,而不是给出准确却无关的内容。

扎根性(依据性)裁判:“评估该答案是否仅基于所给上下文。完全基于上下文得 1,部分基于得 0.5,包含上下文外信息得 0。”

这可防止 LLM 在文档之外添加事实(幻觉)。

每个裁判都关注某一质量维度。您对每条回复同时运行三位裁判,从而获得完整的质量画像。您还可以为风格(是否简洁)、语气(是否专业)或拒答处理(是否在需要时说“不知道”)添加更多裁判。

在 LangFuse 中设置裁判

LangFuse 支持通过 UI 或 API 配置 LLM 裁判。设置流程如下:

  1. 定义裁判提示词:为每个分值区间编写清晰的评分说明与具体标准。
  2. 选择裁判模型:使用 GPT-4、Claude 或其他 LLM。更强的模型评分更准,但成本更高。
  3. 在 LangFuse 中配置裁判:创建一个评分模板,LangFuse 将自动应用于轨迹。
  4. 测试裁判:在已知正确分数的少量样例上运行。若裁判过严或过松,调整提示词。
  5. 应用于数据集:当裁判稳定可靠后,LangFuse 会自动为您的全部轨迹打分。

裁判会异步运行,因此不会拖慢主应用。测试结束后,您可在 LangFuse 仪表盘查看分数。

裁判的擅长之处

LLM 裁判更适合那些难以用代码衡量的主观标准,如语气、相关性与风格。对于客观事实,它们的可靠性较低。如果您需要验证“2+2=4”,应编写确定性检查而非使用裁判。

对于我们的问答系统,裁判非常适合评估相关性与扎根性,但您也可以将其与“答案长度不超过 100 词”之类的确定性检查结合起来。

需要注意的限制

LLM 裁判并不完美。它们可能彼此不一致、对某些答案风格有偏好,并会犯把听起来自信但错误的答案打高分的错误。

应对方法包括:在已知分数的样例上测试裁判、使用多个裁判并对分数取平均、以及抽查结果以捕捉裁判错误。

实现说明:完整的评估工作流包括设置数据集、配置裁判、运行批量评估并分析结果。这比我们在本教程中保持实用性的篇幅所能涵盖的要多。请参阅 LLM-as-a-judge 文档以获取完整实现细节(包含代码示例与最佳实践)。如需超越 LLM 裁判的自定义评分方法,请参阅 自定义评分指南。

上述工作流展示了评估思维方式。一旦您在 LangFuse 中管理了轨迹与提示词,添加系统化评估就顺理成章。您可以逐步构建测试集,从简单裁判起步,并在实践中不断优化对应用而言重要的指标。

延伸阅读: LangFuse 还支持用于组织测试用例的数据集管理、用于确定性检查的自定义评分函数,以及在生产流量上自动运行的持续评估。这些功能可帮助您在系统扩展时保持质量。详见 评估概览获取完整信息。

结语

您已构建了一个文档问答系统,并了解了 LangFuse 的三大支柱如何协同工作。可观测性帮助您看清 LLM 运行时发生的事情——每条轨迹、每笔成本、每个令牌。提示词管理将提示词从代码中抽离,放入可版本控制的系统,让您无需部署即可迭代。评估为您提供系统化的质量衡量方法,告别拍脑袋。这些功能互相关联:轨迹可沉淀为评估数据集,提示词版本与性能指标相链接,整体体系帮助您判断更改到底是改进还是退步。

从小处开始应用到您的项目上。先选一个功能:也许先加上追踪,看看应用的钱花在哪里;或把某个硬编码提示词迁移到 LangFuse 的管理系统。本教程中的简单问答示例所体现的模式,能够扩展到复杂的 RAG 流水线、多智能体系统,以及面向成千上万用户的生产应用。查阅 LangFuse 文档以深入了解具体功能,或尝试 示例笔记本,了解真实世界的实现。下次您用 LLM 构建应用时,将拥有看清发生了什么、控制变更内容并衡量关键指标的工具。

Bexruz (Bex) Tuychiev

作者

Bexruz (Bex) Tuychiev

我是一名数据科学内容创作者,拥有超过 2 年的经验,并在 Medium 上拥有较大的读者群。我喜欢用略带讽刺的笔调撰写有关 AI 和机器学习的深度文章——毕竟总得想点办法让这些内容不那么枯燥。我已发表 130 多篇文章,并制作了一门 DataCamp 课程,另有一门正在筹备中。我的内容已被超过 500 万人次阅读,其中有 2 万人在 Medium 和 LinkedIn 上成为关注者。 

主题