01. configurable_fields 方法使用技巧

在某些场合下除了在构建链的时候配置对应的调用参数,也可能让链在执行调用的时候才去配置对应的运行时链内部(运行时修改链相应参数),包括运行时动态调整温度、停止词、传递自定义参数、甚至是运行时动态替换模型为另外一个。

针对这类需求,在 LangChain 也提供了相应的解决方案:

  1. configurable_fields():和 bind() 方法接近,但是并不是在构建时传递对应的参数,而是在链运行时为链中的给定步骤指定参数,比 bind() 更灵活。
  2. configurable_alternatives():使用这个方法可以在链运行时,将链中的某一个部分替换成其他替换方案,例如:运行中更换提示模板、更换大语言模型等。

configurable_fields() 方法使用分成两个流程:

  1. 为 Runnable 定义哪些字段可以在链运行时动态配置;
  2. 在调用 invoke() 函数时,传递对应的配置信息 configurable 完成动态配置;

例如,在链的调用过程中,将 temperature 温度设置为 0,使用代码如下

import dotenv

from langchain_core.output_parsers import StrOutputParser

from langchain_core.prompts import ChatPromptTemplate

from langchain_core.runnables import ConfigurableField

from langchain_openai import ChatOpenAI

dotenv.load_dotenv()

# 1.创建提示模板

prompt = ChatPromptTemplate.from_template("请生成一个小于{x}的随机整数")

# 2.创建LLM大语言模型,并配置temperature参数为可在运行时配置,配置键位llm_temperature

llm = ChatOpenAI(model="gpt-3.5-turbo-16k").configurable_fields(

    temperature=ConfigurableField(

        id="llm_temperature",

        name="大语言模型温度",

        description="用于调整大语言模型生成内容的随机性"

    ),

)

# 3.构建链应用

chain = prompt | llm | StrOutputParser()

# 4.正常调用内容

content = chain.invoke({"x": 1000})

print(content)

# 5.将temperature修改为0调用内容

content = chain.invoke(

    {"x": 1000},

    config={"configurable": {"llm_temperature": 0}}

)

print(content)

02. configurable_fields 运行流程与解析

configurable_fields() 和 bind() 非常接近,但是可配置范围更广,只要 Runnable 组件下有的所有属性,都可以通过 configurable_fields() 进行配置,而 bind() 只能配置调用参数(一般调用参数都和组件参数有关系)。

可以通过以下函数来查看 configurable_fields() 支持配置哪些字段(父类属性也可以配置,但是在这里不显示)

Runnable.__fields__.keys()

例如 PromptTemplate 组件下存在 template 字段,这个字段是提示模板的模板本体,同样也可以快速实现动态配置。

代码如下

from langchain_core.prompts import PromptTemplate

from langchain_core.runnables import ConfigurableField

# 1.创建提示模板并配置支持动态配置的字段

prompt = PromptTemplate.from_template("请写一篇关于{subject}主题的冷笑话").configurable_fields(

    template=ConfigurableField(

        id="prompt_template",

        name="提示模板",

        description="提示模板字符串本身",

    )

)

# 2.传递配置更改prompt_template并调用生成内容

content = prompt.invoke(

    {"subject": "程序员"},

    config={"configurable": {"prompt_template": "请写一篇关于{subject}主题的藏头诗"}}

).to_string()

print(content)

输出结果

请写一篇关于程序员主题的藏头诗

configurable_fields() 的运行原理及流程其实也非常简单,在调用 invoke() 函数调用链的时候,会调用 _prepare() 预处理函数,在预处理函数这里,会重新依据原有参数+配置的参数创建对应的组件进行覆盖,从而实现配置运行时链内部

核心代码

# langchain_core/runnables/configurable.py --> RunnableConfigurableFields

def _prepare(

    self, config: Optional[RunnableConfig] = None

) -> Tuple[Runnable[Input, Output], RunnableConfig]:

    config = ensure_config(config)

    specs_by_id = {spec.id: (key, spec) for key, spec in self.fields.items()}

    configurable_fields = ...

    configurable_single_options = ...

    configurable_multi_options = ...

    configurable = {

        **configurable_fields,

        **configurable_single_options,

        **configurable_multi_options,

    }

    if configurable:

        init_params = {

            k: v

            for k, v in self.default.__dict__.items()

            if k in self.default.__fields__

        }

        return (

            self.default.__class__(**{**init_params, **configurable}),

            config,

        )

    else:

        return (self.default, config)

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐