学习AI Agent编程-第二天-LangGraph ReAct模式实现

简介: 本文介绍了LangChain中ReAct(推理-行动)模式的实践应用:通过“会议室申请”流程,演示LLM如何循环执行“决策→调用工具→评估结果→调整策略”,实现多步任务自动化。代码涵盖流程定义、工具函数与多轮会话测试,验证了其在空闲检查、报备审批、异常处理等场景的可靠性。(239字)

和DeepSeek聊了一天的技术,不断发散思维,收获不错。
但是剩下的时间已经不够学习更多的东西,所以只好草草学习了下LangGraph的基础 - ReAct模式

一、什么是ReAct模式

ReAct模式就是“决策、执行、评估结果、执行下一步”,即reasoning-action,简称ReAct。一个任务发给llm,llm先进行决策,然后决策执行第一步,执行完后再评估执行结果,然后再决定是否继续下一步,还是修复上一步的错误。
如下图所示:

c0ffb0596fa0254f3393db2bd8dba9d5.jpeg

二、ReAct在LangGraph中的实现

严格来说,是在LangChain中的实现,原本在LangGraph中的实现因版本原因被移进了LangChain包。

我们这一次让llm熟悉一个“会议室申请”的流程:

# 申请会议室流程
1. 查看指定时间会议室是否空闲
   * 如果空闲,执行下一步
   * 如果不空闲,则另找空闲时间
2. 向后勤经理和人事经理报备,获得报备号码
3. 提供以下信息,申请会议
    * 会议名称
    * 会议用途
    * 会议时间
    * 后勤经理和人事经理给的报备号码
4. 申请成功会反回申请号码,请妥善保存号码。

这里个流程涉及三个步骤,其中第一步和第三步的结果是一个逻辑分叉,这是一个很典型的适用于ReAct模式,即思考、执行、观察结果循环。

1. 基本代码和资源文件

我们要准备一些资源文件和基础代码,以供调用。
首先是流程规则文件,这个文件用于定义申请会议室的流程规则,用于prompt中,让llm去遵循。

# 申请会议室流程
1. 查看指定时间会议室是否空闲
   * 如果空闲,执行下一步
   * 如果不空闲,则另找空闲时间
2. 向后勤经理和人事经理报备,获得报备号码
3. 提供以下信息,申请会议
    * 会议名称
    * 会议用途
    * 会议时间
    * 后勤经理和人事经理给的报备号码
4. 申请成功会反回申请号码,请妥善保存号码。

然后就是两个功能函数:

def get_work_flow():
    """
    获得流程规则

    :return: 流程规则
    """
    with open('./work_flow.md', 'r') as f:
        return f.read()

def get_model():
    """
    获得模型客户端

    :return: 模型客户端
    """
    return ChatOpenAI(
        model=os.environ['OPENAI_MODEL_NAME'],
        temperature=0,
        extra_body={
   
            "enable_thinking": False,
            "thinking": {
   
                "type": "disabled"
            }
        }
    )

2. 添加工具函数,用于被llm调用

llm需要调用tool来获取他想要的额外信息或者进行相应的操作。所以我们需要实现这些tool。

这个开发过程一般都是慢慢调的,不同的llm的思维方式不同,有些要求很细,有些则要求很粗,所以尽可能跑多几个不同的模型来补上缺失的tool。

@tool
def check_meeting_room_free(date: datetime.datetime):
    """
    检查会议室是否空闲

    :param date: 会议时间
    :return: 空闲返回true,否则为false
    """
    print(f'checking meeting room free date: {date}')
    if str(date) == '2089-05-25 15:00:00':
        return False
    else:
        return True

@tool
def get_approver_name(position:str):
    """
    获取岗位负责人名字

    :param position: 岗位
    :return: 名字
    """
    if position == '后勤经理':
        return '刘四逼'
    elif position == '人事经理':
        return '脏三疯'
    else:
        return '路人ABC'

@tool
def request_approve(approver: str, date: datetime.datetime, reason: str):
    """
    向上级报备使用会议室

    :param approver: 批准人
    :param date: 会议时间
    :param reason: 使用原因
    :return: 报备号
    """
    print(f'{approver}: handle meeting request for date: {date} - {reason}')
    return str(uuid.uuid4())


@tool
def make_meeting_appointment(name, reason, date: datetime.datetime, codes: list[str]) -> tuple:
    """
    申请会议

    :param name: 名称
    :param reason: 用途
    :param date: 时间
    :param codes: 报备号
    :return: 结果,第一个值是"是否成功",如果成功,第二个值是"申请号码",否则则是“失败原因”
    """
    print(f'handling meeting request: {name} - {date} - {reason} - {codes}')
    if str(date.date()) == '2089-05-26':
        return False, '会议室灯光安排在当日维修,无法使用。'
    else:
        return True, str(uuid.uuid4())

3. 测试代码:

if __name__ == '__main__':
    load_dotenv()
    agent = create_agent(
        # 模型
        model=get_model(),
        # 工具
        tools=[check_meeting_room_free, request_approve, make_meeting_appointment, get_approver_name],
        # 流程规则 - prompt
        system_prompt=get_work_flow(),
        # 实现多轮会话
        checkpointer=MemorySaver(),
    )
    # 实现多轮会话
    config = RunnableConfig(configurable={
   "thread_id": "user_thread_1"})

    # 第一轮会话
    state = {
   
        "messages": [
            ("user", "我要申请下周三(2089年5月25日)下午3点整的会议室,名称是“批头会”,用途“批头大叫”")
        ]
    }
    response = agent.invoke(state, config=config)
    print(response['messages'][-1].content)

    # 第二轮会话
    state = {
   
        "messages": [
            ("user", "那就下周四上午9点。")
        ]
    }
    response = agent.invoke(state, config=config)
    print(response['messages'][-1].content)

    # 第三轮会话
    state = {
   
        "messages": [
            ("user", "那就下周二下午4点?")
        ]
    }
    response = agent.invoke(state, config=config)
    print(response['messages'][-1].content)

    # 第四轮会话
    state = {
   
        "messages": [
            ("user", "谢谢")
        ]
    }
    response = agent.invoke(state, config=config)
    print(response['messages'][-1].content)

这个测试代码共进行了四轮会话:

  1. 第一轮测试无空闲会议室的情况
  2. 第二轮测试有空闲会议室但是却申请不成功的情况
  3. 第三轮是正常通过的情况
  4. 第四轮是与流程无关的消息llm能不能正确处理。

输出日志分析:

# 第一轮,可以看到llm能正确调用tool,并且能正确评估tool结果
checking meeting room free date: 2089-05-25 15:00:00
下周三(2089525日)下午3点整的会议室不空闲,请您另选一个时间再申请。

# 第二轮:可以看到llm能正确调用tool获得岗位主管的名字,并且正确被处理申请和返回申报号,而且最后能识别申请失败的原因,并以自然语言的方式回复。最重要的是,日期正确。
checking meeting room free date: 2089-05-26 09:00:00
刘四逼: handle meeting request for date: 2089-05-26 09:00:00 - 批头大叫
脏三疯: handle meeting request for date: 2089-05-26 09:00:00 - 批头大叫
handling meeting request: 批头会 - 2089-05-26 09:00:00 - 批头大叫 - ['d3558796-d523-4e01-acaa-5023dc85023d', 'e25791d2-a22d-46f9-9862-f4414e0075cc']
很抱歉,虽然下周四上午9点会议室时间空闲且已获得后勤经理和人事经理的报备号,但由于当日会议室灯光安排维修,无法使用。请您另选其他时间再申请。

# 第三轮:正常申请成功的流程。
checking meeting room free date: 2089-05-23 16:00:00
刘四逼: handle meeting request for date: 2089-05-23 16:00:00 - 批头大叫
脏三疯: handle meeting request for date: 2089-05-23 16:00:00 - 批头大叫
handling meeting request: 批头会 - 2089-05-23 16:00:00 - 批头大叫 - ['480fb94e-e142-4b0d-acfd-463c0fc843f5', '9e441bb8-e586-420b-9f44-2b11e1fa3a18']
会议室申请成功!您的申请号码为:2f03df27-2e34-4ad8-a99b-1b7dc3a606e3,请妥善保存。会议时间为下周二(2089523日)下午4点整,名称“批头会”,用途“批头大叫”。

# 第四轮:llm能够正确区分非业务消息并正确客套回复。
不客气!祝您会议顺利,如有其他需要随时联系我。

三、总结

由测试结果可以得出,现在的llm能正确处理三步左右的问题,所以可以将子步骤交由ReAct模式去做。但是,为了正确性,一般顶层任务还是明确执行步骤为上。

目录
相关文章
|
10天前
|
人工智能 开发工具 iOS开发
Claude Code 新手完全上手指南:安装、国产模型配置与常用命令全解
Claude Code 是一款运行在终端环境中的 AI 编程助手,能够直接在命令行中完成代码生成、项目分析、文件修改、命令执行、Git 管理等开发全流程工作。它最大的特点是**任务驱动、终端原生、轻量高效、多模型兼容**,无需图形界面、不依赖 IDE 插件,能够深度融入开发者日常工作流。
3191 9
|
12天前
|
Shell API 开发工具
Claude Code 快速上手指南(新手友好版)
AI编程工具卷疯啦!Claude Code凭借任务驱动+终端原生的特性,成了开发者的效率搭子。本文从安装、登录、切换国产模型到常用命令,手把手带新手快速上手,全程避坑,30分钟独立用起来。
3233 22
|
2天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队版、Coding Plan或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
|
6天前
|
人工智能 Linux BI
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
JeecgBoot AI专题研究 一键脚本:Claude Code + JeecgBoot Skills + DeepSeek 全平台接入 一行命令装好 Claude Code + JeecgBoot Skills + DeepSeek 接入,无需翻墙使用 Claude Code,支持 Wind
2207 4
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
|
25天前
|
人工智能 JSON 供应链
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
LucianaiB分享零成本畅用JVS Claw教程(学生认证享7个月使用权),并开源GeoMind项目——将JVS改造为科研与产业地理情报可视化AI助手,支持飞书文档解析、地理编码与腾讯地图可视化,助力产业关系图谱构建。
23594 15
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
|
12天前
|
人工智能 JSON BI
DeepSeek V4-Pro 接入 Claude Code 完全实战:体验、测试与关键避坑指南
Claude Code 作为当前主流的 AI 编程辅助工具,凭借强大的代码理解、工程执行与自动化能力深受开发者喜爱,但原生模型的使用成本相对较高。为了在保持能力的同时进一步降低开销,不少开发者开始寻找兼容度高、价格更友好的替代模型。DeepSeek V4 系列的发布带来了新的选择,该系列包含 V4-Pro 与 V4-Flash 两款模型,并提供了与 Anthropic 完全兼容的 API 接口,理论上只需简单修改配置,即可让 Claude Code 无缝切换为 DeepSeek 引擎。
2702 3
|
4天前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全+三种模式+记忆体系+实战工作流完整手册
Claude Code 是当前最流行的终端级 AI 编程助手,能够直接在命令行中完成代码生成、项目理解、文件修改、命令执行、错误修复等全流程开发工作。它不依赖图形界面、不占用额外资源,却能深度理解项目结构,自动生成规范代码,大幅提升研发效率。
807 2
|
11天前
|
人工智能 安全 开发工具
Claude Code 官方工作原理与使用指南
Claude Code 不是传统代码补全工具,而是 Anthropic 推出的终端 AI 代理,具备代理循环、双驱动架构(模型+工具)、全局项目感知、6 种权限模式等核心能力,本文基于官方文档系统解析其工作原理与高效使用技巧。
1475 0

热门文章

最新文章