langchain:在应用、链和代理以及工具中监控 LLM#

本指南解释了如何使用 ArgillaCallbackHandler 将 Argilla 与 LangChain 应用程序集成。通过此集成,Argilla 可用于评估和微调 LLM。它的工作原理是收集与 LLM 的交互,并将它们推送到 FeedbackDataset 中,以进行持续监控和人工反馈。您只需要在 Argilla 中创建一个与 Langchain 兼容的 FeedbackDataset,然后实例化 ArgillaCallbackHandler,以提供给 LangChain LLM、链和/或代理。

警告

从 Argilla 1.14.0 开始,FeedbackDataset 已被重构以改进其用法,因此如果您使用的是 Argilla 1.14.0 或更高版本,您将无法使用 ArgillaCallbackHandler,因为它尚未在 LangChain 中更新。

LangChain 兼容的 FeedbackDataset#

由于 LangChain 回调和 FeedbackDataset 的工作方式,我们需要在 Argilla 中创建一个具有特定字段结构的 FeedbackDataset,而问题和指南保持开放,可以由用户定义。

FeedbackDataset 需要具有以下字段:promptresponseprompt 字段将用于为 LLM 提供输入,而 response 字段将用于收集 LLM 的输出。

然后,关于问题和指南,用户可以自由定义它们,因为 ArgillaCallbackHandler 不会使用它们来收集 LLM 生成的数据,但它们将用于注释 FeedbackDataset

以下是如何在 Argilla 中创建一个可以与 ArgillaCallbackHandler 一起使用的 FeedbackDataset 的示例

import argilla as rg

rg.init(
    api_url="...",
    api_key="..."
)

dataset = rg.FeedbackDataset(
    fields=[
        rg.TextField(name="prompt", required=True),
        rg.TextField(name="response", required=True)
    ],
    questions=[
        rg.RatingQuestion(
            name="response-rating",
            description="How would you rate the quality of the response?",
            values=[1, 2, 3, 4, 5],
            required=True,
        ),
        rg.TextQuestion(
            name="response-correction",
            description="If you think the response is not accurate, please, correct it.",
            required=False,
        ),
    ],
    guidelines="Please, read the questions carefully and try to answer it as accurately as possible.",
)

然后,您需要将该 FeedbackDataset 推送到 Argilla,如下所示,否则 ArgillaCallbackHandler 将无法工作。

dataset.push_to_argilla("langchain-dataset")

有关如何创建 FeedbackDataset 的更多信息,请参阅 创建反馈数据集 指南。

监控#

所有 LangChain 回调都被实例化并提供给 LangChain LLM、链和/或代理,然后无需再担心它们,因为它们会自动跟踪 LangChain 管道中发生的一切。在这种情况下,我们正在跟踪 LLM、链和/或代理提供的输入和最终响应。

from langchain.callbacks import ArgillaCallbackHandler

argilla_callback = ArgillaCallbackHandler(
    dataset_name="langchain-dataset",
    api_url="...",
    api_key="...",
)

LLM#

首先,让我们只运行一个 LLM 几次,并在 Argilla 中捕获结果的 prompt-response 对。

from langchain.callbacks import ArgillaCallbackHandler, StdOutCallbackHandler
from langchain.llms import OpenAI

argilla_callback = ArgillaCallbackHandler(
    dataset_name="langchain-dataset",
    api_url="...",
    api_key="...",
)

llm = OpenAI(temperature=0.9, callbacks=[argilla_callback])
llm.generate(["Tell me a joke", "Tell me a poem"] * 3)

Argilla UI with LangChain LLM input-response

链中的 LLM#

然后,我们可以使用提示模板创建一个链,然后在 Argilla 中跟踪初始提示和最终响应。

from langchain.callbacks import ArgillaCallbackHandler, StdOutCallbackHandler
from langchain.llms import OpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate

argilla_callback = ArgillaCallbackHandler(
    dataset_name="langchain-dataset",
    api_url="...",
    api_key="...",
)

llm = OpenAI(temperature=0.9, callbacks=[argilla_callback])

template = """You are a playwright. Given the title of play, it is your job to write a synopsis for that title.
Title: {title}
Playwright: This is a synopsis for the above play:"""
prompt_template = PromptTemplate(input_variables=["title"], template=template)
synopsis_chain = LLMChain(llm=llm, prompt=prompt_template, callbacks=[argilla_callback])

test_prompts = [{"title": "Documentary about Bigfoot in Paris"}]
synopsis_chain.apply(test_prompts)

Argilla UI with LangChain Chain input-response

带有工具的代理#

最后,作为更高级的工作流程,您可以创建一个使用某些工具的代理。这样 ArgillaCallbackHandler 将跟踪输入和输出,但不跟踪中间步骤/想法,以便在给定提示的情况下,我们记录原始提示和对该给定提示的最终响应。

请注意,对于此场景,我们将使用 Google Search API (Serp API),因此您需要同时安装 google-search-results,如 pip install google-search-results,并将 Serp API 密钥设置为 os.environ["SERPAPI_API_KEY"] = "..."(您可以在 https://serpapi.com/dashboard 找到它),否则以下示例将无法工作。

from langchain.agents import AgentType, initialize_agent, load_tools
from langchain.callbacks import ArgillaCallbackHandler, StdOutCallbackHandler
from langchain.llms import OpenAI

argilla_callback = ArgillaCallbackHandler(
    dataset_name="langchain-dataset",
    api_url="...",
    api_key="...",
)

llm = OpenAI(temperature=0.9, callbacks=[argilla_callback])
tools = load_tools(["serpapi"], llm=llm, callbacks=[argilla_callback])
agent = initialize_agent(
    tools,
    llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    callbacks=[argilla_callback],
)
agent.run("Who was the first president of the United States of America?")

Argilla UI with LangChain Agent input-response

合成数据#

如果您想使用 LangChain 创建合成数据,您可以使用 ArgillaCallbackHandler 来跟踪 LLM、链和/或代理的输入和输出,然后将该数据存储在 Argilla 中。这意味着您将以与上述类似的场景中监控数据,但不是提供直接的功能提示来定制数据生成,以便设置您的 LLM 来为 `TextField` 生成一些合成数据。如果您想要更定制的数据生成和计算反馈方法,您可以查看 此与 LangChain 的集成关于 SetFit 建议的本教程

警告

请记住,LLM 具有许可,并非每个 LLM 都可以在每个操作环境中使用来创建合成数据。在使用 LLM 创建合成数据之前,请检查您使用的 LLM 的许可。

import random

from langchain.callbacks import ArgillaCallbackHandler, StdOutCallbackHandler
from langchain.llms import OpenAI

argilla_callback = ArgillaCallbackHandler(
    dataset_name="langchain-dataset",
    api_url="...",
    api_key="...",
)

topics = ["opening a new account", "applying for a loan", "applying for a credit card"]
sentiment = ["positive", "neutral", "negative"]

def get_prompt():
    prompt = (
        "Write a customer review for a bank. "
        f"Do that for topic of {random.choice(topics)}. "
        f"Do that with one a {random.choice(sentiment)} sentiment."
    )
    return template

llm = OpenAI(temperature=0.9, callbacks=[argilla_callback])
llm.generate([get_prompt() for _ in range(3)])