当前位置: 首页 > news >正文

维护测试监控LLM应用

维护一个生产级的 LLM 应用,我们需要做什么?

  1. 各种指标监控与统计:访问记录、响应时长、Token 用量、计费等等
  2. 调试 Prompt
  3. 测试/验证系统的相关评估指标
  4. 数据集管理(便于回归测试)
  5. Prompt 版本管理(便于升级/回滚)

针对以上需求,我们介绍两个生产级 LLM App 维护平台

  1. LangFuse: 开源 + SaaS(免费/付费),LangSmith 平替,可集成 LangChain 也可直接对接 OpenAI API;
  2. LangSmith: LangChain 的官方平台,SaaS 服务(免费/付费),非开源,企业版支持私有部署;

1、LangFuse

开源,支持 LangChain 集成或原生 OpenAI API 集成

官方网站:https://langfuse.com/

项目地址:https://github.com/langfuse

文档地址:https://langfuse.com/docs

API文档:https://api.reference.langfuse.com/

  • Python SDK: https://python.reference.langfuse.com/

  • JS SDK: https://js.reference.langfuse.com/

  1. 通过官方云服务使用:
    • 注册: cloud.langfuse.com
    • 创建 API Key
LANGFUSE_SECRET_KEY="sk-lf-..."
LANGFUSE_PUBLIC_KEY="pk-lf-..."
LANGFUSE_HOST="https://cloud.langfuse.com" # EU 服务器
# LANGFUSE_HOST="https://us.cloud.langfuse.com" # US 服务器
  1. 通过 Docker 本地部署
# Clone repository
git clone https://github.com/langfuse/langfuse.git
cd langfuse# Run server and db
docker compose up -d
# 在自己部署的系统中生成上述两个 KEY
# 并在环境变量中指定服务地址LANGFUSE_SECRET_KEY="sk-lf-..."
LANGFUSE_PUBLIC_KEY="pk-lf-.."
LANGFUSE_HOST="http://localhost:3000"
# !pip install langfuse==2.43.2

1.1、通过装饰器记录

from langfuse.decorators import observe, langfuse_context
from langfuse.openai import openai  # OpenAI integration
from dotenv import load_dotenv, find_dotenv_ = load_dotenv(find_dotenv())@observe()
def run():return openai.chat.completions.create(model="gpt-3.5-turbo",messages=[{"role": "user", "content": "对我说Hello, World!"}],).choices[0].message.contentprint(run())
langfuse_context.flush()
Hello, World! How are you today?

1.1.1、几个基本概念

  • Trace 一般表示用户与系统的一次交互,其中记录输入、输出,也包括自定义的 metadata 比如用户名、session id 等;
  • 一个 trace 内部可以包含多个子过程,这里叫 observarions;
  • Observation 可以是多个类型:
    • Event 是最基本的单元,用于记录一个 trace 中的每个事件;
    • Span 表一个 trace 中的一个"耗时"的过程;
    • Generation 是用于记录与 AI 模型交互的 span,例如:调用 embedding 模型、调用 LLM。
  • Observation 可以嵌套使用。
    在这里插入图片描述

1.1.2、observe() 装饰器的参数

def observe(self,*,name: Optional[str] = None, # Trace 或 Span 的名称,默认为函数名as_type: Optional[Literal['generation']] = None, # 将记录定义为 Observation (LLM 调用)capture_input: bool = True, # 记录输入capture_output: bool = True, # 记录输出transform_to_string: Optional[Callable[[Iterable], str]] = None # 将输出转为 string
) -> Callable[[~F], ~F]:
from langfuse.decorators import observe, langfuse_context
from langfuse.openai import openai
from dotenv import load_dotenv, find_dotenv_ = load_dotenv(find_dotenv())@observe(name="HelloWorld")
def run():return openai.chat.completions.create(model="gpt-3.5-turbo",messages=[{"role": "user", "content": "对我说Hello, World!"}],).choices[0].message.contentprint(run())
langfuse_context.flush()
Hello, World! How can I assist you today?

1.1.3、通过 langfuse_context 记录 User ID、Metadata 等

from langfuse.decorators import observe, langfuse_context
from langfuse.openai import openai
from dotenv import load_dotenv, find_dotenv_ = load_dotenv(find_dotenv())@observe()
def run():langfuse_context.update_current_trace(name="HelloWorld",user_id="rivers",tags=["test", "demo"])return openai.chat.completions.create(model="gpt-3.5-turbo",messages=[{"role": "user", "content": "对我说Hello, World!"}],).choices[0].message.contentprint(run())
langfuse_context.flush()
Hello, World! Nice to meet you.

1.2、通过 LangChain 的回调集成

from dotenv import load_dotenv, find_dotenv_ = load_dotenv(find_dotenv())from langchain.prompts import (ChatPromptTemplate,HumanMessagePromptTemplate,
)
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
from langchain_core.runnables import RunnablePassthroughmodel = ChatOpenAI(model="gpt-3.5-turbo")prompt = ChatPromptTemplate.from_messages([HumanMessagePromptTemplate.from_template("Say hello to {input}!")
])# 定义输出解析器
parser = StrOutputParser()chain = ({"input": RunnablePassthrough()}| prompt| model| parser
)from langfuse.decorators import langfuse_context, observe@observe()
def run():langfuse_context.update_current_trace(name="LangChainDemo",user_id="rivers",)# 获取当前 LangChain 回调处理器langfuse_handler = langfuse_context.get_current_langchain_handler()return chain.invoke(input="rivers", config={"callbacks": [langfuse_handler]})print(run())
langfuse_context.flush()  # Langfuse 回传记录是异步的,可以通过 flush 强制更新
Hello rivers! You flow so gracefully, shaping landscapes and sustaining life. Thank you for your beauty and power.

1.3、构建一个实际应用

AGI 课堂跟课助手,根据课程内容,判断学生问题是否需要老师解答

  1. 判断该问题是否需要老师解答,回复’Y’或’N’
  2. 判断该问题是否已有同学问过

1.3.1、用 Trace 记录一个多次调用 LLM 的过程

TRACE (id: trace_id)
|
|-- SPAN: LLMCain (id: generated by Langfuse)
|   |
|   |-- GENERATION: OpenAI (id: generated by Langfuse)
|
|-- SPAN: LLMCain (id: generated by 'next_span_id')
|   |
|   |-- GENERATION: OpenAI (id: generated by Langfuse)
from dotenv import load_dotenv, find_dotenv
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI_ = load_dotenv(find_dotenv())# 构建 PromptTemplate
from langchain.prompts import PromptTemplateneed_answer = PromptTemplate.from_template("""
*********
你是AIGC课程的助教,你的工作是从学员的课堂交流中选择出需要老师回答的问题,加以整理以交给老师回答。课程内容:
{outlines}
*********
学员输入:
{user_input}
*********
如果这是一个需要老师答疑的问题,回复Y,否则回复N。
只回复Y或N,不要回复其他内容。""")check_duplicated = PromptTemplate.from_template("""
*********
已有提问列表:
[
{question_list}
]
*********
新提问:
{user_input}
*********
已有提问列表是否有和新提问类似的问题? 回复Y或N, Y表示有,N表示没有。
只回复Y或N,不要回复其他内容。""")outlines = """
LangChain
模型 I/O 封装
模型的封装
模型的输入输出
PromptTemplate
OutputParser
数据连接封装
文档加载器:Document Loaders
文档处理器
内置RAG:RetrievalQA
记忆封装:Memory
链架构:Chain/LCEL
大模型时代的软件架构:Agent
ReAct
SelfAskWithSearch
LangServe
LangChain.js
"""question_list = ["LangChain可以商用吗","LangChain开源吗",
]# 创建 chain
model = ChatOpenAI
http://www.xdnf.cn/news/644275.html

相关文章:

  • 从厨房到储物间:Grocy 家庭的智能物资管理助手
  • CA自签名证书创建--证书链生成脚本
  • dify-plugin-daemon的.env配置文件
  • 大模型和AI工具汇总(一)
  • CMake学习笔记(六)可以在CMake的function中修改function函数体之外的变量值吗?
  • 【FastAPI】--进阶教程1
  • VS2022 安装CodeGeeX AI插件实现高效编程体验
  • 贪心算法应用:贝尔曼-福特松弛问题详解
  • 差分数组知识笔记
  • 嵌入式学习笔记——day26
  • C++ gtest单元测试
  • STM32八股【10】-----stm32启动流程
  • 如何利用好cursor
  • 【第四十六周】文献阅读:从 RAG 到记忆:大型语言模型的非参数持续学习
  • c++ overwrite
  • 华为OD机试真题——仿LISP运算(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
  • Linux应用程序 栈溢出 内存踩踏 问题 排查学习
  • 第九课 影像文章插图及图表制作完全指南:从原理到应用
  • 市场需求文档撰写
  • C++11(2):
  • 《算法导论(第4版)》阅读笔记:p1178-p1212
  • 吴恩达机器学习笔记:逻辑回归3
  • Python元类(Metaclass)深度解析
  • Volatile的相关内容
  • Lombok与Jackson实现高效JSON序列化与反序列化
  • Python类与对象:面向对象编程的基础
  • Kubernetes 核心原理详解
  • Python实现基于线性回归的空气质量预测系统并达到目标指标
  • 内存管理 : 02 内存分区与分页
  • Python实例题:Python打造漏洞扫描器