当前位置: 首页 > news >正文

Runnable组件动态添加默认调用参数

01. bind 函数用途与使用技巧

在使用 LangChain 开发时,某些场景我们希望在一个 Runnable 队列中调用另一个 Runnable 并传递常量参数,这些参数既非前序 Runnable 的输出,也不是用户输入,而是组件自身的部分参数。此时可以使用 Runnable.bind() 传递默认参数。

典型应用场景

  1. 创建 ChatOpenAI 大语言模型构建两条链:
    • 第 1 条链设置 temperature=0.7(确定性输出)
    • 第 2 条链设置 temperature=1.2(创意性输出)
  2. 通过 LLM.bind(temperature=0.7)LLM.bind(temperature=1.2) 设置不同参数

bind() 用于修改 Runnable 底层的默认调用参数,调用时自动传递无需手动输入。适合在构建链时已知参数值的场景。


1.1 动态添加默认调用参数

通过绑定运行时参数实现 LLM 的多场景复用:

import dotenv
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

dotenv.load_dotenv()

prompt = ChatPromptTemplate.from_messages([
    (
        "system",
        "你正在执行一项测试,请重复用户传递的内容,除了重复其他均不要操作"
    ),
    ("human", "{query}")
])
llm = ChatOpenAI(model="gpt-4o")

chain = prompt | llm.bind(stop="world") | StrOutputParser()

content = chain.invoke({"query": "Hello world"})

print(content)

输出:

Hello

资料推荐

  • 🔗 官方文档参考
  • 💡大模型中转API推荐
  • ✨中转使用教程

1.2 解决 RunnableLambda 多参传递问题

在 LangChain 中,如果要将一个函数变成 Runnable 组件,可以通过 RunnableLambda 函数进行包装。但是封装后,所有的 Runnable 组件的 invoke 函数,调用时,只能传递一个参数(类型不限制),如果原本的函数支持多个参数,并且是必填参数,就会出现报错。
例如:

import random

from langchain_core.runnables import RunnableLambda


def get_weather(location: str, unit: str) -> str:
    """根据传入的位置+温度单位获取对应的天气信息"""
    print("location:", location)
    print("unit:", unit)
    return f"{location}天气为{random.randint(24, 40)}{unit}"


get_weather_runnable = RunnableLambda(get_weather)

resp = get_weather_runnable.invoke({"location": "北京", "unit": "摄氏度"})

print(resp)

上述代码在执行 invoke 时虽然传递了字典,并且包含了 location 和 unit 两个参数,但是这个参数只会作为唯一的一个值,传递给 get_weather 函数的 location 参数,所以实际上 get_weather 函数接收的参数如下:

{
    "location": {"location": "北京", "unit": "摄氏度"},
    "unit": None
}

而使用 bind() 函数绑定添加其他默认调用参数,从而巧妙实现 RunnableLambda 组件实现接收多个参数,修改示例:

import random

from langchain_core.runnables import RunnableLambda


def get_weather(location: str, unit: str) -> str:
    """根据传入的位置+温度单位获取对应的天气信息"""
    print("location:", location)
    print("unit:", unit)
    return f"{location}天气为{random.randint(24, 40)}{unit}"


get_weather_runnable = RunnableLambda(get_weather).bind(unit="摄氏度")

resp = get_weather_runnable.invoke("北京")

print(resp)

输出内容:

location: {'location': '北京', 'unit': '摄氏度'}
unit: 摄氏度
{'location': '北京', 'unit': '摄氏度'}天气为31摄氏度

资料推荐

  • 🔗 官方文档参考
  • 💡大模型中转API推荐
  • ✨中转使用教程

02 bind 函数运行流程解析

通过上述的案例,可以知道 .bind() 函数是在构建应用的时候添加上对应的默认调用参数,而在 Runnable.bind() 函数的底层,本质上是往 Runnable 的 kwargs 属性添加对应的字段,并生成一个新的 Runnable,当 Runnable 组件执行调用时(invoke、ainvoke、stream、astream、batch、abatch等),会自动将 kwargs 字段里的所有参数合并并覆盖默认调用参数。

从而完成动态添加默认调用参数的效果,Runnable.bind() 的实现原理:

  1. 在构建时向 Runnable 的 kwargs 属性添加字段
  2. 调用时自动合并覆盖默认参数
  3. 生成携带新参数的新 Runnable 实例

运行流程为:在这里插入图片描述

注意事项
虽然 .bind() 是所有 Runnable 共有的方法,但是并不是所有的 Runnable 组件都支持绑定默认调用参数,部分组件底层并没有默认调用参数的概念,例如 PromptTemplate 底层的 invoke 方法,并没有使用到 .bind() 的逻辑。

# langchain_core/prompts/base.py -> BasePromptTemplate
def invoke(
    self, input: Dict, config: Optional[RunnableConfig] = None
) -> PromptValue:
    config = ensure_config(config)
    if self.metadata:
        config["metadata"] = {**config["metadata"], **self.metadata}
    if self.tags:
        config["tags"] = config["tags"] + self.tags
    return self._call_with_config(
        self._format_prompt_with_error_handling,
        input,
        config,
        run_type="prompt",
    )

"

http://www.dtcms.com/a/111380.html

相关文章:

  • 基于SpringBoot框架发生验证码
  • 【Docker项目实战】使用Docker部署MediaCMS内容管理系统
  • 脑影像分析软件推荐 | BCT(Brain Connectivity Toolbox)
  • c语言修炼秘籍 - - 禁(进)忌(阶)秘(技)术(巧)【第四式】自定义类型详解(结构体、枚举、联合)
  • Windows 11 听的见人声,但是听不见背景音乐或者听不见轻音乐等,可以这样设置
  • 【橘子大模型】Runnable和Chain以及串行和并行
  • STM32 HAL库 CANFD配置工具
  • 小程序API —— 58 自定义组件 - 创建 - 注册 - 使用组件
  • CExercise_04_1运算符_6 (扩展) 找出数组中只出现一次的唯二元素
  • 社会视频汇聚:构筑城市安全防线的智慧之眼
  • VirtualBox 配置双网卡(NAT + 桥接)详细步骤
  • 《微服务概念进阶》精简版
  • 新浪财经股票每天10点自动爬取
  • 免费送源码:Java+SSM+Android Studio 基于Android Studio游戏搜索app的设计与实现 计算机毕业设计原创定制
  • Springboot + Vue + WebSocket + Notification实现消息推送功能
  • 接口自动化学习四:全量字段校验
  • L1-100 四项全能(测试点1)
  • 计算机网络知识点汇总与复习——(三)数据链路层
  • 在VMware下Hadoop分布式集群环境的配置--基于Yarn模式的一个Master节点、两个Slaver(Worker)节点的配置
  • Leetcode 33 -- 二分查找 | 归约思想
  • 【YOLO系列(V5-V12)通用数据集-交通红黄绿灯检测数据集】
  • SpringBoot集成swagger和jwt
  • Flask学习笔记 - 模板渲染
  • 深入探究 Hive 中的 MAP 类型:特点、创建与应用
  • 【Linux系统编程】进程概念,进程状态
  • 第三期:深入理解 Spring Web MVC [特殊字符](数据传参+ 特殊字符处理 + 编码问题解析)
  • 游戏编程模式学习(编程质量提升之路)
  • 25.4.4错题分析
  • Linux: network: 两台直连的主机业务不通
  • 【移动编程技术】作业1 中国现代信息科技发展史、Android 系统概述与程序结构 作业解析