如何使用 LangChain Callbacks 将模型调用和答案记录到变量中

Ont*_*nio 8 python nlp openai-api langchain

我正在使用LangChain构建 NL 应用程序。我希望将与 LLM 的交互记录在一个变量中,我可以将其用于日志记录和调试目的。我创建了一个非常简单的链:

from typing import Any, Dict

from langchain import PromptTemplate
from langchain.callbacks.base import BaseCallbackHandler
from langchain.chains import LLMChain
from langchain.llms import OpenAI

llm = OpenAI()
prompt = PromptTemplate.from_template("1 + {number} = ")
handler = MyCustomHandler()

chain = LLMChain(llm=llm, prompt=prompt, callbacks=[handler])
chain.run(number=2)
Run Code Online (Sandbox Code Playgroud)

为了记录发生的情况,我创建了一个自定义CallbackHandler

class MyCustomHandler(BaseCallbackHandler):
    def on_text(self, text: str, **kwargs: Any) -> Any:
        print(f"Text: {text}")
        self.log = text
  
    def on_chain_start(
        self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any
    ) -> Any:
        """Run when chain starts running."""
        print("Chain started running")
Run Code Online (Sandbox Code Playgroud)

这或多或少符合预期,但它有一些副作用,我无法弄清楚它们来自哪里。输出是:

在此输入图像描述

并且该handler.log变量包含:

'Prompt after formatting:\n\x1b[32;1m\x1b[1;3m1 + 2 = \x1b[0m'

“格式化后提示”和将文本设置为绿色的ANSI代码来自哪里?我可以摆脱它们吗?

总的来说,我是否缺少使用回调系统来记录应用程序的更好方法?这似乎没有很好的记录。

Rhu*_*arb 1

我不知道你是否能摆脱它们,但我可以告诉你它们从哪里来,今天我自己也遇到过。像这样的区块在LangChain的llm.py类中多次出现:

            prompt = self.prompt.format_prompt(**selected_inputs)
            _colored_text = get_colored_text(prompt.to_string(), "green")
            _text = "Prompt after formatting:\n" + _colored_text
            if run_manager:
                run_manager.on_text(_text, end="\n", verbose=self.verbose)
            if "stop" in inputs and inputs["stop"] != stop:
                raise ValueError(
                    "If `stop` is present in any inputs, should be present in all."
                )
            prompts.append(prompt)
Run Code Online (Sandbox Code Playgroud)

这是一个非常精选的片段,但表明 colored_text发送到 run_manager 上的回调。因此,您的处理程序可以看到它,但获取列表的实际 LLMprompts却看不到。

我也没有办法禁用它 - 因为get_colored_text()总是返回额外的 ANSI 代码:

def get_colored_text(text: str, color: str) -> str:
    """Get colored text."""
    color_str = _TEXT_COLOR_MAPPING[color]
    return f"\u001b[{color_str}m\033[1;3m{text}\u001b[0m"
Run Code Online (Sandbox Code Playgroud)

我认为希望可以使用原始值调用您的回调是合理的,因此我会记录一个问题。