学习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模式去做。但是,为了正确性,一般顶层任务还是明确执行步骤为上。

目录
相关文章
|
3天前
|
人工智能 机器人 Shell
【开源】龙虾人工智能 —— 完全本地化的机器人大脑!不联网、不付 API 费、能看能说能理解!
龙虾本地化AI(Lobster AI)是一款完全离线、零成本、零隐私泄露的开源机器人系统,支持文本推理(Gemma4)、多模态视觉理解(桌面/摄像头)、语音识别与合成(Sherpa-ONNX),纯本地运行,不依赖任何云服务。
243 2
【开源】龙虾人工智能 —— 完全本地化的机器人大脑!不联网、不付 API 费、能看能说能理解!
|
3天前
|
人工智能 定位技术 Go
从零搭建 Harness Engineering 框架 :Rule、Skill、Sub-Agent等工程落完整路径
Harness Engineering 是一套让AI在真实项目中稳定、可靠交付的工程系统,涵盖SPEC规范、Rule约束、Skill流程、Sub-Agent分工、Workflow编排、Script校验与MCP集成。它不追求模型更聪明,而是通过结构化机制消除随意性,实现可验证、可维护、可持续的AI协作开发。
367 1
从零搭建 Harness Engineering 框架 :Rule、Skill、Sub-Agent等工程落完整路径
|
3天前
|
机器学习/深度学习 人工智能 监控
人体姿态检测数据集分享(适用于YOLO系列深度学习检测任务)
本数据集含6000张高质量标注图像,覆盖站着、摔倒、坐、深蹲、跑5类人体姿态,按5:1划分训练集与验证集,采用YOLO格式标注,结构清晰,开箱即用,适用于YOLOv8等目标检测模型训练,助力跌倒监测、智能健身、安防监控等应用。
211 3
|
3天前
|
人工智能 开发工具 开发者
学习AI Agent编程-第一天-MCP基础
本文精炼解析MCP(Model Context Protocol):它不是新模型,而是让AI Agent运行时动态增删工具的协议。通过MCP Server(工具实现)、Client(SDK封装)与Host(Agent应用)三组件协作,解决传统`bind_tools`静态绑定的局限。附完整可运行示例,助你快速掌握80%核心用法。(239字)
210 1
|
3天前
|
人工智能 运维 安全
Java领域AI Agent开发首选框架:Harness Agent特性、实战用法全面解读
在智能化技术全面渗透软件开发领域的当下,AI Agent智能体已经成为应用开发、业务流程自动化、系统运维、智能交互场景中的核心技术形态。Java作为企业级开发领域应用最广泛、生态最成熟的编程语言,长期占据后端服务、大型分布式系统、政企项目、金融业务系统等核心赛道。但在AI Agent技术落地过程中,传统Java开发模式却暴露出明显短板,原生语言体系缺少针对智能体调度、工具调用、多轮会话、任务编排的标准化组件,开发者想要从零搭建AI Agent应用,需要整合大量第三方组件、自主设计通信逻辑、封装模型调用接口,开发周期长、代码冗余度高、后期维护难度大。
223 0
|
3天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
8132 36
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
|
3天前
|
人工智能 资源调度 调度
AI时代,大学生应该提前准备什么?
AI时代,大学生面临就业重塑与能力升级的双重挑战。本文聚焦认知重构、三大核心能力(统筹力、技术力、实战力)及行动路径,倡导从“工具使用者”进阶为“AI决策者”,以T型+AI复合素养应对变革,在人机协同中抢占未来先机。
|
3天前
|
人工智能 自然语言处理 监控
阿里云百炼千问Qwen3.7-Max全面解析:核心能力、技术特性与订阅使用全指南
在智能应用与AI智能体飞速发展的2026年,大模型的推理能力、长文本处理、多模态理解以及工具调用能力,已经成为企业开发、科研创作、自动化办公的核心刚需。阿里云百炼正式推出**Qwen3.7-Max**旗舰大模型,作为通义千问系列综合实力最强的版本,直接对标国际主流高端闭源大模型,专为复杂逻辑推理、长周期自主任务、多模态分析、企业级业务场景打造。
992 3
|
3天前
|
人工智能 开发工具 git
Claude Code新手零基础入门教程:安装配置、国产模型接入与常用命令全集
在AI编程工具快速迭代的当下,传统代码补全插件已经无法满足复杂开发需求,而**Claude Code**凭借终端原生、任务驱动、轻量高效、多模型兼容的独特优势,成为开发者首选的智能编程助手。它不需要依赖笨重的IDE插件,全程在终端运行,能够自主理解项目需求、拆解开发任务、生成代码、修改文件、执行终端命令、管理Git版本仓库,覆盖从项目初始化、代码编写、Bug修复到项目重构的全流程开发工作。
513 3
|
3天前
|
人工智能 Oracle 机器人
推理 → 行动 → 观察:用 LangChain + Python 实现一个智能体循环
智能体循环(Agentic Loop)突破单次问答局限,通过“推理→行动→观察”迭代闭环,让AI能自主分解任务、调用工具、持续优化直至目标完成,是构建真正自动化智能体的核心架构。
194 9
推理 → 行动 → 观察:用 LangChain + Python 实现一个智能体循环

热门文章

最新文章