使用Langgraph创建一个智能任务规划与执行工作流(Plan-and-Execute)

整个工作流分为以下几个核心模块:

  • 工具集成: 利用 TavilySearchResults 提供实时搜索结果。
  • LLM模型: 通过 ChatOpenAI 调用 GLM-4-plus 模型进行语言生成。
  • 工作流管理: 使用 langgraph 创建一个状态图,实现任务的动态规划与执行。
  • 动态任务规划与执行: 根据用户问题生成任务计划,并动态调整未完成的任务。
    在这里插入图片描述

1. 搜索工具

from langchain_community.tools.tavily_search import TavilySearchResults
import os
os.environ["TAVILY_API_KEY"] = "your api key"

tools = [TavilySearchResults(max_results=3)]

2. executor 执行节点

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    temperature=0,
    model="GLM-4-plus",
    openai_api_key="your api key",
    openai_api_base="https://open.bigmodel.cn/api/paas/v4/"
)
from langchain import hub
from langchain_openai import ChatOpenAI

from langgraph.prebuilt import create_react_agent

# Get the prompt to use - you can modify this!
prompt = hub.pull("ih/ih-react-agent-executor")
prompt.pretty_print()

agent_executor = create_react_agent(llm, tools, state_modifier=prompt)
d:\soft\anaconda\envs\langchain\Lib\site-packages\langsmith\client.py:354: LangSmithMissingAPIKeyWarning: API key must be provided when using hosted LangSmith API
  warnings.warn(


================================[1m System Message [0m================================

You are a helpful assistant.

=============================[1m Messages Placeholder [0m=============================

[33;1m[1;3m{messages}[0m
agent_executor.invoke({"messages": [("user", "who is the winnner of the us open")]})
{'messages': [HumanMessage(content='who is the winnner of the us open', additional_kwargs={}, response_metadata={}, id='79a6dac2-034d-4a10-b4a4-cbb9e70f0ba6'),
  AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_-9176234598398291859', 'function': {'arguments': '{"query": "US Open 2023 winner"}', 'name': 'tavily_search_results_json'}, 'type': 'function', 'index': 0}], 'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 19, 'prompt_tokens': 161, 'total_tokens': 180, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'GLM-4-plus', 'system_fingerprint': None, 'finish_reason': 'tool_calls', 'logprobs': None}, id='run-fb86ce02-c1d5-4052-b812-b5a17ed4506f-0', tool_calls=[{'name': 'tavily_search_results_json', 'args': {'query': 'US Open 2023 winner'}, 'id': 'call_-9176234598398291859', 'type': 'tool_call'}], usage_metadata={'input_tokens': 161, 'output_tokens': 19, 'total_tokens': 180, 'input_token_details': {}, 'output_token_details': {}}),
  ToolMessage(content='[{"url": "https://currentaffairs.adda247.com/us-open-2023-winners-complete-list/", "content": "US Open 2023 Winners Complete list Novak Djokovic won his fourth title at the US Open and 24th Grand Slam title by beating Daniil Medvedev 6-3, 7-6(5), 6-3 in the final. Coco Gauff capped off her sensational American summer by winning her maiden Grand Slam title at the US Open by beating Aryna Sabalenka 2-6, 6-3, 6-2 in the final. This tournament is the 143rd edition. Here is the Complete List of US Open 2023 Winners in Different Categories Other champions at US Open 2023 If you are preparing for Government Job Exams, then it is very important for you to read the Daily Current Affairs. All the important updates based on current affairs are included in this Daily Current Affairs 2024 article."}, {"url": "https://www.usopen.org/en_US/news/articles/2023-09-10/novak_djokovic_wins_24th_grand_slam_singles_title_at_2023_us_open.html", "content": "Novak Djokovic wins 24th Grand Slam singles title at 2023 US Open - Official Site of the 2024 US Open Tennis Championships - A USTA Event Novak Djokovic wins 24th Grand Slam singles title at 2023 US Open WHAT HAPPENED:\xa0Novak Djokovic\xa0handled the weight of history to defeat\xa0Daniil Medvedev\xa0on Sunday in the 2023 US Open men\'s singles final. Djokovic is now\xa04-6 across his record-tying 10 US Open men\'s singles finals. MATCH POINT:\xa0Now 10-5 in his head-to-head against Medvedev, Djokovic\xa0earned a measure of US Open revenge two years after Medvedev\xa0denied him\xa0a Grand Slam at the\xa0last hurdle in the 2021 New York final. These cookies may be set through our site by our advertising partners."}, {"url": "https://en.wikipedia.org/wiki/2023_US_Open_–_Men\'s_singles", "content": "Djokovic became the oldest US Open men\'s singles champion in the Open Era, at 36 years and 111 days, as well as the first man to capture the Australian Open, the French Open, and the US Open in a season since Mats Wilander in 1988.[1] Contents\\n2023 US Open – Men\'s singles\\nNovak Djokovic defeated Daniil Medvedev in the final, 6–3, 7–6(7–5), 6–3 to win the men\'s singles tennis title at the 2023 US Open. Alcaraz\'s loss marked the 15th consecutive year where the reigning US Open champion failed to defend the title, with Federer being the last man to do so in 2008.\\n Other entry information[edit]\\nWild cards[edit]\\nProtected ranking[edit]\\nQualifiers[edit]\\nLucky losers[edit]\\nWithdrawals[edit]\\nReferences[edit]\\nExternal links[edit] By reaching a 47th men\'s singles major semifinal, Djokovic surpassed Roger Federer\'s all-time record,[2] and, by reaching the final, he equaled Federer\'s record of reaching all major finals in a season three times.\\n"}]', name='tavily_search_results_json', id='6548718f-0fc6-4298-99c5-1a97e9816310', tool_call_id='call_-9176234598398291859', artifact={'query': 'US Open 2023 winner', 'follow_up_questions': None, 'answer': None, 'images': [], 'results': [{'title': 'US Open 2023 Winners Complete list - adda247', 'url': 'https://currentaffairs.adda247.com/us-open-2023-winners-complete-list/', 'content': 'US Open 2023 Winners Complete list Novak Djokovic won his fourth title at the US Open and 24th Grand Slam title by beating Daniil Medvedev 6-3, 7-6(5), 6-3 in the final. Coco Gauff capped off her sensational American summer by winning her maiden Grand Slam title at the US Open by beating Aryna Sabalenka 2-6, 6-3, 6-2 in the final. This tournament is the 143rd edition. Here is the Complete List of US Open 2023 Winners in Different Categories Other champions at US Open 2023 If you are preparing for Government Job Exams, then it is very important for you to read the Daily Current Affairs. All the important updates based on current affairs are included in this Daily Current Affairs 2024 article.', 'score': 0.99984527, 'raw_content': None}, {'title': 'Novak Djokovic wins 24th Grand Slam singles title at 2023 US Open', 'url': 'https://www.usopen.org/en_US/news/articles/2023-09-10/novak_djokovic_wins_24th_grand_slam_singles_title_at_2023_us_open.html', 'content': "Novak Djokovic wins 24th Grand Slam singles title at 2023 US Open - Official Site of the 2024 US Open Tennis Championships - A USTA Event Novak Djokovic wins 24th Grand Slam singles title at 2023 US Open WHAT HAPPENED:\xa0Novak Djokovic\xa0handled the weight of history to defeat\xa0Daniil Medvedev\xa0on Sunday in the 2023 US Open men's singles final. Djokovic is now\xa04-6 across his record-tying 10 US Open men's singles finals. MATCH POINT:\xa0Now 10-5 in his head-to-head against Medvedev, Djokovic\xa0earned a measure of US Open revenge two years after Medvedev\xa0denied him\xa0a Grand Slam at the\xa0last hurdle in the 2021 New York final. These cookies may be set through our site by our advertising partners.", 'score': 0.99940693, 'raw_content': None}, {'title': "2023 US Open - Men's singles - Wikipedia", 'url': "https://en.wikipedia.org/wiki/2023_US_Open_–_Men's_singles", 'content': "Djokovic became the oldest US Open men's singles champion in the Open Era, at 36 years and 111 days, as well as the first man to capture the Australian Open, the French Open, and the US Open in a season since Mats Wilander in 1988.[1] Contents\n2023 US Open – Men's singles\nNovak Djokovic defeated Daniil Medvedev in the final, 6–3, 7–6(7–5), 6–3 to win the men's singles tennis title at the 2023 US Open. Alcaraz's loss marked the 15th consecutive year where the reigning US Open champion failed to defend the title, with Federer being the last man to do so in 2008.\n Other entry information[edit]\nWild cards[edit]\nProtected ranking[edit]\nQualifiers[edit]\nLucky losers[edit]\nWithdrawals[edit]\nReferences[edit]\nExternal links[edit] By reaching a 47th men's singles major semifinal, Djokovic surpassed Roger Federer's all-time record,[2] and, by reaching the final, he equaled Federer's record of reaching all major finals in a season three times.\n", 'score': 0.9993358, 'raw_content': None}], 'response_time': 1.42}),
  AIMessage(content="The winner of the 2023 US Open in men's singles is Novak Djokovic, who secured his fourth US Open title and 24th Grand Slam title by defeating Daniil Medvedev in the final. In the women's singles, Coco Gauff won her maiden Grand Slam title by overcoming Aryna Sabalenka in the final.", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 73, 'prompt_tokens': 922, 'total_tokens': 995, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'GLM-4-plus', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-ea7dd37c-596e-41a8-8272-4ca47caf463c-0', usage_metadata={'input_tokens': 922, 'output_tokens': 73, 'total_tokens': 995, 'input_token_details': {}, 'output_token_details': {}})]}

3. Plan 计划节点

import operator
from typing import Annotated, List, Tuple
from typing_extensions import TypedDict


class PlanExecute(TypedDict):
    input: str
    plan: List[str]
    past_steps: Annotated[List[Tuple], operator.add]
    response: str
from pydantic import BaseModel, Field


class Plan(BaseModel):
    """Plan to follow in future"""

    steps: List[str] = Field(
        description="different steps to follow, should be in sorted order"
    )
from langchain_core.prompts import ChatPromptTemplate

planner_prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            """For the given objective, come up with a simple step by step plan. \
This plan should involve individual tasks, that if executed correctly will yield the correct answer. Do not add any superfluous steps. \
The result of the final step should be the final answer. Make sure that each step has all the information needed - do not skip steps.""",
        ),
        ("placeholder", "{messages}"),
    ]
)
planner = planner_prompt | ChatOpenAI(
    temperature=0,
    model="GLM-4-plus",
    openai_api_key="your api key",
    openai_api_base="https://open.bigmodel.cn/api/paas/v4/"
).with_structured_output(Plan)
planner.invoke(
    {
        "messages": [
            ("user", "what is the hometown of the current Australia open winner?")
        ]
    }
)
Plan(steps=['Find out who is the current Australia Open winner.', 'Determine the hometown of the current Australia Open winner.'])

4. replan 计划检查节点

from typing import Union


class Response(BaseModel):
    """Response to user."""

    response: str


class Act(BaseModel):
    """Action to perform."""

    action: Union[Response, Plan] = Field(
        description="Action to perform. If you want to respond to user, use Response. "
        "If you need to further use tools to get the answer, use Plan."
    )


replanner_prompt = ChatPromptTemplate.from_template(
    """For the given objective, come up with a simple step by step plan. \
This plan should involve individual tasks, that if executed correctly will yield the correct answer. Do not add any superfluous steps. \
The result of the final step should be the final answer. Make sure that each step has all the information needed - do not skip steps.

Your objective was this:
{input}

Your original plan was this:
{plan}

You have currently done the follow steps:
{past_steps}

Update your plan accordingly. If no more steps are needed and you can return to the user, then respond with that. Otherwise, fill out the plan. Only add steps to the plan that still NEED to be done. Do not return previously done steps as part of the plan."""
)


replanner = replanner_prompt | ChatOpenAI(
    temperature=0,
    model="GLM-4-plus",
    openai_api_key="your api key",
    openai_api_base="https://open.bigmodel.cn/api/paas/v4/"
).with_structured_output(Act)

5. graph 各个节点连接

from typing import Literal
from langgraph.graph import END


async def execute_step(state: PlanExecute):
    plan = state["plan"]
    plan_str = "\n".join(f"{i+1}. {step}" for i, step in enumerate(plan))
    task = plan[0]
    task_formatted = f"""For the following plan:
{plan_str}\n\nYou are tasked with executing step {1}, {task}."""
    agent_response = await agent_executor.ainvoke(
        {"messages": [("user", task_formatted)]}
    )
    return {
        "past_steps": [(task, agent_response["messages"][-1].content)],
    }


async def plan_step(state: PlanExecute):
    plan = await planner.ainvoke({"messages": [("user", state["input"])]})
    return {"plan": plan.steps}


async def replan_step(state: PlanExecute):
    output = await replanner.ainvoke(state)
    if isinstance(output.action, Response):
        return {"response": output.action.response}
    else:
        return {"plan": output.action.steps}


def should_end(state: PlanExecute):
    if "response" in state and state["response"]:
        return END
    else:
        return "agent"
from langgraph.graph import StateGraph, START

workflow = StateGraph(PlanExecute)

# Add the plan node
workflow.add_node("planner", plan_step)

# Add the execution step
workflow.add_node("agent", execute_step)

# Add a replan node
workflow.add_node("replan", replan_step)

workflow.add_edge(START, "planner")

# From plan we go to agent
workflow.add_edge("planner", "agent")

# From agent, we replan
workflow.add_edge("agent", "replan")

workflow.add_conditional_edges(
    "replan",
    # Next, we pass in the function that will determine which node is called next.
    should_end,
    ["agent", END],
)

# Finally, we compile it!
# This compiles it into a LangChain Runnable,
# meaning you can use it as you would any other runnable
app = workflow.compile()

graph 可视化

from IPython.display import Image, display

display(Image(app.get_graph(xray=True).draw_mermaid_png()))

在这里插入图片描述

6. 示例

config = {"recursion_limit": 50}
inputs = {"input": "what is the hometown of the mens 2024 Australia open winner?"}
async for event in app.astream(inputs, config=config):
    for k, v in event.items():
        if k != "__end__":
            print(v)
{'plan': ["Find out who won the men's 2024 Australian Open.", 'Research the hometown of the winner.']}
{'past_steps': [("Find out who won the men's 2024 Australian Open.", "The winner of the men's singles at the 2024 Australian Open was Jannik Sinner. He made an epic comeback to defeat Daniil Medvedev in the final, with a scoreline of 3-6, 3-6, 6-4, 6-4, 6-3. This victory marked Sinner's first ever Grand Slam title, and he became the first Italian man to win the Australian Open since 1976, as well as the youngest player to win at Melbourne Park since Novak Djokovic in 2008.")]}
{'plan': ['Research the hometown of Jannik Sinner.']}
{'past_steps': [('Research the hometown of Jannik Sinner.', "Jannik Sinner's hometown is Sexten, located in northern Italy. This information is confirmed by multiple sources, including ATP Tour and TennisTonic, which mention his return to Sexten and his connection to the region. Additionally, Tennis World USA describes Sexten as being in the county of Trentino Alto Adige, nestled in the Alps. This northern Italian town is where Sinner was born and raised, and it holds a special place in his heart.")]}
{'response': "The hometown of the men's 2024 Australia Open winner, Jannik Sinner, is Sexten, located in northern Italy."}

参考链接: https://langchain-ai.github.io/langgraph/tutorials/plan-and-execute/plan-and-execute/

如果有任何问题,欢迎在评论区提问。

### LangGraph 聊天机器人介绍 LangGraph 是一种基于多智能工作流架构的先进聊天机器人平台,旨在提升机器人的对话质量和用户体验。该平台通过整合 Neo4j 图数据库 LangChain 技术,显著改善了聊天机器人处理复杂查询的能力以及对用户需求的理解精度[^1]。 ### 原理 #### 多智能体协作机制 LangGraph 利用了最新的 LangChain 发布成果——多智能工作流(Multi-Agent Workflows),这允许不同类型的智能体协同合作来完成特定的任务或响应用户的请求。每个智能体负责不同的功能模块,比如自然语言理解(NLU)、意图识别、上下文管理等,它们之间可以通过预定义的消息传递协议进行交互[^2]。 #### 动态计划生成器 特别值得一提的是,Langgraph 配备了一个强大的规划代理(Planning Agent),它能够在接收到用户指令后自动生成详细的行动方案。此特性区别于其他传统框架(如 Rasa 和 Dialogflow),后者可能需要额外编码才能实现类似的多功能操作。相比之下,Langgraph 的内置规划引擎可以根据当前情境自动调整策略并优化任务执行路径[^3]。 ```python from langchain import LangGraph, PlanningAgent def handle_user_input(user_message): graph_db = Neo4jDatabase() # 初始化图数据库连接 chatbot = LangGraph(database=graph_db) planning_agent = PlanningAgent(chatbot) action_plan = planning_agent.generate_action_plan(user_message) response = execute_actions(action_plan) return response ``` ### 应用案例 由于其高度灵活性和智能化水平,LangGraph 已经被应用于多个领域: - **客户服务**:帮助企业构建高效的客户支持系统; - **教育辅导**:提供个性化学习建议和服务; - **医疗咨询**:辅助医生进行病情诊断和治疗推荐;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值