掌握LangChain中自定义函数的运行秘诀

96 阅读3分钟

掌握LangChain中自定义函数的运行秘诀

在现代软件开发中,处理自然语言任务时,扩展和自定义现有框架是非常重要的。在这篇文章中,我们将探索如何在LangChain框架中运行自定义函数。这不仅能为你提供更多的自由度,还可以帮助你实现特定的业务需求。

引言

LangChain是一个强大的工具,用于将多个AI模型和自然语言处理组件结合起来,形成复杂的交互链。然而,有时我们需要功能不在LangChain默认组件列表中的自定义逻辑。这篇文章的目标是介绍如何在LangChain中创建和运行自定义函数,以及应对可能遇到的挑战。

主要内容

创建RunnableLambda

要在LangChain中运行自定义函数,我们可以使用RunnableLambda构造器将函数包装为可运行的实体。以下示例展示了如何显式地将自定义函数封装为RunnableLambda

from langchain_core.runnables import RunnableLambda

def length_function(text):
    return len(text)

runnable = RunnableLambda(length_function)

使用@chain装饰器

除了使用RunnableLambda构造器,我们还可以通过@chain装饰器将任意函数转换为链:

from langchain_core.runnables import chain

@chain
def custom_chain(text):
    return text[::-1]  # 返回字符串的反转

自动强制转换

LangChain中一个有趣的特性是自动强制转换。当你使用管道符号|构建链时,不需要显式地将函数包装为RunnableLambda,而是让LangChain自动识别:

prompt = ChatPromptTemplate.from_template("tell me a story about {topic}")
model = ChatOpenAI()

chain_with_coerced_function = prompt | model | (lambda x: x.content[:5])  # 自动转换

使用运行元数据

有时,我们需要在运行过程中传递额外的元数据。这可以通过在自定义函数中接受RunnableConfig参数来实现:

from langchain_core.runnables import RunnableConfig

def parse_with_metadata(text: str, config: RunnableConfig):
    # 使用配置做一些事情
    pass

实现流式处理

LangChain允许你创建支持流式处理的自定义函数。通过返回生成器,我们可以在链中操作输入输出的块:

from typing import Iterator, List

def split_into_list(input: Iterator[str]) -> Iterator[List[str]]:
    buffer = ""
    for chunk in input:
        buffer += chunk
        while "," in buffer:
            comma_index = buffer.index(",")
            yield [buffer[:comma_index].strip()]
            buffer = buffer[comma_index + 1 :]
    yield [buffer.strip()]

代码示例

下面是一个完整的代码示例,演示如何创建并使用自定义的RunnableLambda

from langchain_core.runnables import RunnableLambda
from operator import itemgetter
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

def length_function(text):
    return len(text)

def multiple_length_function(_dict):
    return len(_dict["text1"]) * len(_dict["text2"])

model = ChatOpenAI()
prompt = ChatPromptTemplate.from_template("what is {a} + {b}")

chain = (
    {
        "a": itemgetter("foo") | RunnableLambda(length_function),  # 使用API代理服务提高访问稳定性
        "b": {"text1": itemgetter("foo"), "text2": itemgetter("bar")}
        | RunnableLambda(multiple_length_function),
    }
    | prompt
    | model
)

result = chain.invoke({"foo": "bar", "bar": "gah"})
print(result)

常见问题和解决方案

  • 多参数函数:如果你的函数需要多个参数,请创建一个包装函数只接受一个字典参数,然后解包该字典。
  • 性能问题:在高负载下运行流式处理代码时,确保生成器有效地处理和缓冲数据。

总结和进一步学习资源

通过掌握如何在LangChain中使用自定义函数,可以大大拓展你在自然语言处理项目中的能力。要深入了解LangChain的更多功能,建议查阅以下资源:

参考资料

  1. LangChain Documentation: langchain.com/docs/
  2. Python Generators: docs.python.org/3/library/s…

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---