七、LLM维护平台LangFuse实战

本文详细介绍了如何使用LangFuse进行LLM维护,包括监控指标、版本管理、部署步骤、HelloWorld示例、回调集成、Prompt模板创建和应用示例,以及数据集管理和测试过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 对LLM进行维护

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

2 LangFuse

2.1 下载

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

创建自己的项目获得API Key
在这里插入图片描述

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

git clone https://github.com/langfuse/langfuse.git
cd langfuse

2.2 部署安装

通过docker compose up -d安装

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

# 安装 langfuse SDK
!pip install --upgrade langfuse

2.3 hello world例子

'''
将相应的KEY写到.env文件中,然后加载
LANGFUSE_SECRET_KEY="sk-lf-"
LANGFUSE_PUBLIC_KEY="pk-lf-"
LANGFUSE_HOST="https://us.cloud.langfuse.com"
'''
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
from langfuse.openai import openai
from langfuse import Langfuse 

trace = Langfuse().trace(
    name = "hello-world",
    user_id = "naive frank",
    release = "v0.0.1"
)

completion = openai.chat.completions.create(
  name="hello-world",
  model="gpt-3.5-turbo",
  messages=[
      {"role": "user", "content": "你能为我做什么?"}
  ],
  temperature=0,
  trace_id=trace.id,
)

print(completion.choices[0].message.content)

在这里插入图片描述

2.4 通过LangChain的回调集成

from langfuse.callback import CallbackHandler

handler = CallbackHandler(
    trace_name="SayHello",
    user_id="naive frank",
)
from langchain_openai import ChatOpenAI
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough

from langchain.prompts.chat import HumanMessagePromptTemplate
from langchain.prompts import ChatPromptTemplate

model = ChatOpenAI(model="gpt-3.5-turbo-0613")

prompt = ChatPromptTemplate.from_messages([
    HumanMessagePromptTemplate.from_template("Say hello to {input}!") 
])

# 定义输出解析器
parser = StrOutputParser()

chain = (
    {"input":RunnablePassthrough()} 
    | prompt
    | model
    | parser
)

chain.invoke(input="Naive Frank", config={"callbacks":[handler]})

在这里插入图片描述

2.5 构建一个实际应用

构建 PromptTemplate

from langchain.prompts import PromptTemplate

need_answer=PromptTemplate.from_template("""
*********
你是人工智能机器学习算法的大咖,你的工作是回答有关机器学习算法的问题。
 
机器学习算法:
{outlines}
*********
用户输入:
{user_input}
*********
如果这是一个需要老师答疑的问题,回复Y,否则回复N。
只回复Y或N,不要回复其他内容。""")

check_duplicated=PromptTemplate.from_template("""
*********
已有问题列表:
[
{question_list}
]
*********
新问题:
{user_input}
*********
已有提问列表是否有和新提问类似的问题? 回复Y或N, Y表示有,N表示没有。
只回复Y或N,不要回复其他内容。""")

初始化大纲和问题列表

outlines="""
线性回归
逻辑回归
决策树
随机森林
支持向量机
神经网络
"""

question_list=[
    "谢谢老师",
    "什么是线性回归",
]

创建 chain


model = ChatOpenAI(temperature=0,model_kwargs={"seed":50})
parser = StrOutputParser()

chain1 = (
    need_answer
    | model
    | parser
)

chain2 = (
    check_duplicated
    | model
    | parser
)
import uuid
from langfuse.client import Langfuse

# 创建一个新trace
def create_trace(user_id):
    langfuse = Langfuse()
    trace_id = str(uuid.uuid4())
    trace = langfuse.trace(
        name="assistant",
        id=trace_id,
        user_id=user_id
    )
    return trace

# 主流程
def verify_question(
    question: str,
    outlines: str,
    question_list: list,
    user_id: str,
) -> bool:
	# 创建trace
    trace = create_trace(user_id)
    # 获取一个语言链(language chain)处理器(handler)
    handler = trace.get_langchain_handler()
    # 判断是否需要回答
    if chain1.invoke(
        {"user_input":question,"outlines": outlines},
        config={"callbacks":[handler]}
    ) == 'Y':
        # 判断是否为重复问题
        if chain2.invoke(
            {"user_input":question,"question_list": "\n".join(question_list)},
            config={"callbacks":[handler]}
        ) == 'N':
            question_list.append(question)
            return True
    return False

实际调用,判断是否为新问题,需要回答

ret = verify_question(
    "什么是随机森林",
    outlines,
    question_list,
    user_id="naive frank",
)
print(ret)

在这里插入图片描述
在这里插入图片描述
Trace
在这里插入图片描述

2.6 用session记录多轮对话

import uuid
from langchain_openai import ChatOpenAI
from langchain.schema import (
    AIMessage, #等价于OpenAI接口中的assistant role
    HumanMessage, #等价于OpenAI接口中的user role
    SystemMessage #等价于OpenAI接口中的system role
)


llm = ChatOpenAI()

messages = [
    SystemMessage(content="你是人工智能机器学习算法的大咖。"), 
]

handler = CallbackHandler(
    user_id="naive frank",
    trace_name="naive_chat",
    session_id=str(uuid.uuid4())
)

while True:
    user_input=input("User: ")
    if user_input.strip() == "":
        break
    messages.append(HumanMessage(content=user_input))
    response = llm.invoke(messages,config={"callbacks":[handler]})
    print("AI: "+response.content)
    messages.append(response)

在这里插入图片描述

2.7 数据集与测试

创建数据集
在这里插入图片描述
数据标注

在这里插入图片描述

标注结果:

在这里插入图片描述

2.8 上传数据集

解析JSON数据

import json

data = []
with open('my_annotations.jsonl','r',encoding='utf-8') as fp:
    for line in fp:
        example = json.loads(line.strip())
        item = {
            "input": {
                "outlines": example["outlines"],
                "user_input": example["user_input"]
            },
            "expected_output": example["label"]
        }
        data.append(item)

将解析数据上传至创建的数据集my_dataset

from langfuse import Langfuse
from langfuse.model import CreateDatasetRequest, CreateDatasetItemRequest
from tqdm import tqdm

# init
langfuse = Langfuse()

# 考虑演示运行速度,只上传前50条数据
for item in tqdm(data[:50]):
    langfuse.create_dataset_item(
        dataset_name="my_dataset",
        input=item["input"],
        expected_output=item["expected_output"]
    )

在这里插入图片描述
在这里插入图片描述

2.9 运行测试

def simple_evaluation(output, expected_output):
  return output == expected_output
# 构建 PromptTemplate
from langchain.prompts import PromptTemplate

need_answer=PromptTemplate.from_template("""
*********
你是人工智能机器学习算法的大咖,你的工作是回答有关机器学习算法的问题。
 
机器学习算法:
{outlines}
*********
用户输入:
{user_input}
*********
如果这是一个需要老师答疑的问题,回复Y,否则回复N。
只回复Y或N,不要回复其他内容。""")

model = ChatOpenAI(temperature=0,model_kwargs={"seed":50})
parser = StrOutputParser()

chain_v1 = (
    need_answer
    | model
    | parser
)
from concurrent.futures import ThreadPoolExecutor
from functools import partial
from langfuse import Langfuse

langfuse = Langfuse()

def run_evaluation(chain, dataset_name, run_name):
    dataset = langfuse.get_dataset(dataset_name)

    def process_item(item):
        handler = item.get_langchain_handler(run_name=run_name)
        
        # Assuming chain.invoke is a synchronous function
        output = chain.invoke(item.input, config={"callbacks": [handler]})
        
        # Assuming handler.root_span.score is a synchronous function
        handler.root_span.score(
            name="accuracy",
            value=simple_evaluation(output, item.expected_output)
        )
        print('.', end='',flush=True)

    # Using ThreadPoolExecutor with a maximum of 10 workers
    with ThreadPoolExecutor(max_workers=4) as executor:
        # Map the process_item function to each item in the dataset
        executor.map(process_item, dataset.items)
run_evaluation(chain_v1, "my_dataset", "v1-"+str(uuid.uuid4())[:8])

在这里插入图片描述

2.10 Prompt调优与回归测试

from langchain.prompts import PromptTemplate

need_answer=PromptTemplate.from_template("""
*********
你是人工智能机器学习算法的大咖,你的工作是回答有关机器学习算法的问题。。

你的选择需要遵循以下原则:
1 需要老师回答的问题是指与课程内容或AI/LLM相关的技术问题;
2 评论性的观点、闲聊、表达模糊不清的句子,不需要老师回答;
3 学生输入不构成疑问句的,不需要老师回答;
4 学生问题中如果用“这”、“那”等代词指代,不算表达模糊不清,请根据问题内容判断是否需要老师回答。
 
课程内容:
{outlines}
*********
学员输入:
{user_input}
*********
Analyse the student's input according to the lecture's contents and your criteria.
Output your analysis process step by step.
Finally, output a single letter Y or N in a separate line.
Y means that the input needs to be answered by the teacher.
N means that the input does not needs to be answered by the teacher.""")
from langchain_core.output_parsers import BaseOutputParser
import re

class MyOutputParser(BaseOutputParser):
    """自定义parser,从思维链中取出最后的Y/N"""
    def parse(self, text: str)->str:
        matches = re.findall(r'[YN]', text)
        return matches[-1] if matches else 'N'
chain_v2 = (
    need_answer
    | model
    | MyOutputParser()
)
run_evaluation(chain_v2, "my_dataset", "cot-"+str(uuid.uuid4())[:8])

在这里插入图片描述

2.11 Prompt 版本管理

添加Prompt
在这里插入图片描述
加载prompt测试

# 按名称加载
prompt = langfuse.get_prompt("my_prompt")
 
# 按名称和版本号加载
prompt = langfuse.get_prompt("my_prompt", version=3)
 
# 对模板中的变量赋值
compiled_prompt = prompt.compile(user_input="你好",outlines="SVM是什么?")

print(compiled_prompt)

在这里插入图片描述

3 管理LLM全生命周期工具

  1. 调试Prompt的后台
  2. 测试/验证系统的相关指标
  3. 数据集管理
  4. 各种指标监控与统计:访问量、响应时长、Token计费等
### 大型语言模型与推荐系统的结合 大型语言模型(LLMs)在推荐系统中的应用正在成为研究热点。通过融合自然语言处理能力,这些模型能够理解用户的偏好并提供更加个性化的推荐。 #### 使用LLM增强推荐算法的理解力 为了提高推荐效果,可以采用预训练的语言模型来解析用户评论、产品描述等内容。这有助于捕捉更深层次的情感倾向和语义特征[^1]。例如,在电影推荐场景下,不仅考虑评分历史,还深入分析观众对于特定类型的反馈文字。 ```python from transformers import pipeline nlp = pipeline('sentiment-analysis') result = nlp("I absolutely loved this movie!") print(result) ``` 此代码片段展示了如何利用Hugging Face Transformers库快速设置情感分析工具,从而辅助判断用户态度。 #### 构建基于对话的交互式推荐服务 借助于强大的生成能力和上下文感知功能,LLMs能支持创建聊天机器人形式的个性化导购平台。这类应用程序允许顾客以自然交流的方式表达需求,并实时获得精准匹配的商品列表或资讯链接。 ```json { "conversation": [ {"role": "user", "content": "Find me books similar to Harry Potter."}, {"role": "assistant", "content": "Sure! Here are some recommendations:\n\n1. The Name of the Wind by Patrick Rothfuss.\n2. Mistborn by Brandon Sanderson."} ] } ``` 上述JSON结构模拟了一次简单的问答过程,其中AI助手根据给定提示提供了两本可能感兴趣的书籍作为回应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值