深入解析如何在子链间进行路由:实用指南

84 阅读3分钟

引言

在构建复杂的AI模型交互时,路由能够为非确定性链提供结构和一致性。通过定义状态并使用相关信息作为模型调用的上下文,我们可以实现更智能的AI问答系统。本篇文章将详细介绍如何在子链间进行路由,包括条件路由和通过嵌入进行路由的实现方法。

主要内容

方法一:使用 RunnableLambda 进行条件路由

这种方法推荐使用自定义函数来选择合适的子链。首先,我们需要创建一个分类链来判断问题属于LangChain、Anthropic还是其他类别,并据此选择对应的处理链。

示例代码

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

# 分类链
classification_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()
)

# 创建子链
langchain_chain = PromptTemplate.from_template("...") | ChatAnthropic(model_name="claude-3-haiku-20240307")
anthropic_chain = PromptTemplate.from_template("...") | ChatAnthropic(model_name="claude-3-haiku-20240307")
general_chain = PromptTemplate.from_template("...") | ChatAnthropic(model_name="claude-3-haiku-20240307")

# 自定义路由函数
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

# 完整链路
full_chain = {"topic": classification_chain, "question": lambda x: x["question"]} | RunnableLambda(route)

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

方法二:使用 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": classification_chain, "question": lambda x: x["question"]} | branch
full_chain.invoke({"question": "how do I use Anthropic?"})

方法三:通过语义相似性进行路由

利用嵌入技术,我们可以根据查询的语义相似性选择合适的模板。

示例代码

from langchain_community.utils.math import cosine_similarity
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
from langchain_openai import OpenAIEmbeddings

# 定义模板
physics_template = """You are a very smart physics professor..."""
math_template = """You are a very good mathematician..."""

# 嵌入计算
embeddings = OpenAIEmbeddings()
prompt_templates = [physics_template, math_template]
prompt_embeddings = embeddings.embed_documents(prompt_templates)

# 路由函数
def prompt_router(input):
    query_embedding = embeddings.embed_query(input["query"])
    similarity = cosine_similarity([query_embedding], prompt_embeddings)[0]
    most_similar = prompt_templates[similarity.argmax()]
    return PromptTemplate.from_template(most_similar)

chain = (
    {"query": RunnablePassthrough()}
    | RunnableLambda(prompt_router)
    | ChatAnthropic(model="claude-3-haiku-20240307")
    | StrOutputParser()
)

# 使用API代理服务提高访问稳定性
print(chain.invoke("What's a black hole"))

常见问题和解决方案

  • 网络访问问题:由于某些地区的网络限制,建议使用API代理服务以提高访问稳定性。
  • 条件重复匹配:确保条件是互斥的,以避免不确定的分支选择。

总结和进一步学习资源

以上介绍了在子链间进行路由的几种方法。接下来,可以参考以下资源进一步学习:

参考资料

  1. LangChain Expression Language (LCEL) Documentation
  2. AI Models and Their Applications
  3. OpenAI API 使用指南

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

---END---