自定义函数加入链
RunnnamebeLambda
chain = first_prompt | model | json_parser | second_prompt | model | str_parser
前文我们根据JsonOutputParser完成了多模型执行链条的构建。
- 除了
JsonOutputParser这类固定功能的解析器之外 - 我们也可以自己编写Lambda匿名函数来完成自定义逻辑的数据转换,想怎么转换就怎么转换,更自由。
想要完成这个功能,可以基于RunnableLambda类实现。
RunnableLambda类是LangChain内置的,将普通函数等转换为Runnable接口实例,方便自定义函数加入chain。
语法:
RunnableLambda(函数对象或lambda匿名函数)
补充
Lambda 函数基础语法:
lambda 参数列表: 表达式
代码示例
import os
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_community.chat_models.tongyi import ChatTongyi
# from langchain_core.runnables import RunnableLambda
from dotenv import load_dotenv
load_dotenv()
LLM_API_KEY = os.getenv("LLM_API_KEY")
model = ChatTongyi(model="qwen3-max",api_key=LLM_API_KEY)
str_parser = StrOutputParser()
first_prompt = PromptTemplate.from_template(
"我邻居姓:{lastname},刚生了{gender},请帮忙起名字,仅告知我一个名字,不要额外信息。"
)
second_prompt = PromptTemplate.from_template(
"姓名:{name},请帮我解析含义。"
)
# 函数的入参: AIMessage -> dict ({"name": "xxx"})
# my_func = RunnableLambda(lambda ai_msg: {"name": ai_msg.content})
chain = first_prompt | model | (lambda ai_msg: {"name": ai_msg.content}) | second_prompt | model | str_parser
for chunk in chain.stream({"lastname": "张", "gender": "女孩"}):
print(chunk, end="", flush=True)
直接使用函数
chain = first_prompt | model | (lambda ai_msg: {"name": ai_msg.content}) | second_prompt | model | str_parser
跳过RunnableLambda类,直接让函数加入链也是可以的。
因为Runnable接口类在实现__or__的时候,支持Callable接口的实例。
- 函数就是
Callable接口的实例
def __or__(
self,
other: Runnable[Any, Other]
| Callable[[Iterator[Any]], Iterator[Other]]
| Callable[[AsyncIterator[Any]], AsyncIterator[Other]]
| Callable[[Any], Other]
| Mapping[str, Runnable[Any, Other] | Callable[[Any], Other] | Any],
) -> RunnableSerializable[Input, Other]:
如上代码示例,|符号(底层是调用__or__)组链,是支持函数加入的。
总结
如果像要在链中加入自定义函数,可以选择:
- 将函数封装入
RunnableLambda类对象,其是Runnable接口实例,可以直接入链 - 直接将函数入链,函数会自动转换为
RunnableLambda对象