大模型ReAct框架—打造AI Agent的代码实现—基于LLM + Function Call构建Agent

【LLM】ReAct 工具本质上就是我们为大模型提供的扩展能力,它可以是一些 Open API(如 Google 搜索、高德天气等等),也可以是我们内部的一些函数,甚至是第三方的服务。get_fruit_price:一个简单的本地函数,用于获取指定水果的价格。 阅读详情

前言

“Agent通过大模型的推理和规划,使得大模型真正实现类似人类的能力”

AI Agent也就是AI智能体,是通过把大模型作为“大脑”,通过利用大模型的推理和规划能力,然后调用外部工具来完成复杂任务的一种方式。

简单来说,Agent就是一种让大模型自己思考和分析问题,选择合适的工具,最终解决问题的一种方法,其背后原理就来自于ReAct。

ReAct是Reasoning And Acting的缩写,意思是LLM可以根据逻辑推理(Reson),构建完整系列行动(Act),从而达到期望目标。

LLM的灵感来源于人类和推理之间的协同关系,人类根据这种协同关系学习新的知识,做出决策,然后执行。

从本质上来说,智能体的作用就是模仿人类的思维和处理复杂问题的方式。

基于LLM 和 Function Call实现Agent

ReAct的作用就是协同LLM和外部的信息获取,与其它功能交互,如果说LLM模型是大脑,那么ReAct框架就是这个大脑的手脚和五官。

下面我们就用代码来实现一个简单的具有自主规划功能的Agent,需要的东西也很简单:

Python开发环境 python 版本用到3.12.1 版本没有强制要求

支持Function Call 工具的大模型(可以是自己部署的大模型或者第三方模型)。
使用第三方模型需要自己申请并获取其API-KEY,代码中还用到了tavily搜索,这个也需要自己去申请。

下图是Agent根据任务要求输出的结果,任务要求是

请帮我制定一份理财计划,你可以通过网络搜索的方式来收集一定的参考资料,并把最终的计划内容写入到理财计划.txt文件中

Agent实现的核心有三点

大模型的质量

外部工具集

提示词的质量

大模型的质量问题直接影响到Agent表现的好坏,推理能力强,知识丰富的大模型会表现更好。

而外部工具集就是提供给大模型使用的工具可以根据不同的业务场景提供不同的工具集(API)。如果使用一些第三方API可能需要自己申请,比如百度或谷歌搜索,高德和百度的地图接口等。

提示词是最重要的一个环节,我们知道大模型的能力是一方面,但怎么发挥大模型的能力是由提示词的质量决定的。

# 约束
constraints = [
    "仅使用下面列出的动作",
    "你只能主动行动,在计划行动时需要考虑到这一点",
    "你无法与物理对象交互,如果对于完成任务或目标是绝对必要的,则必须要求用户为你完成,如果用户拒绝,并且没有其它方法实现目标,则直接终止,避免浪费时间和精力"
]

# 资源
resources = [
    "提供搜索和信息搜集的互联网接入",
    "读取和写入文件的能力",
    "你是一个大语言模型,接受了大量的文本训练,包括大量的事实知识,利用这些知识来避免不必要的信息收集"
]

# 最佳实践说明
best_practices = [
    "不断地回顾和分析你的行为,确保发挥出你最大的能力",
    "不断地进行建设性的自我批评",
    "反思过去的决策和策略,完善你的方案",
    "每个动作执行部分代价,所以要聪明高效,目的是用最少的步骤完成任务"
]

prompt_template = """
    你是一个问答专家,你必须始终独立做出决策,无需寻求用户的帮助,发挥你作为LLM的优势,追求简单的策略,不要涉及法律问题
    
任务:
{query}
    
    
    
限制条件说明:
{constraints}
    
动作说明:这是你唯一可以使用的作用,你的任何操作都必须通过以下操作实现:
{actions}
    
资源说明: 
{resources}
    
最佳实践的说明:
{best_practices}


agent_scratch:
{agent_scratch}
    
你应该只以json格式响应,响应格式如下:
{response_format_prompt}
确保响应结果可以由python json.loads解析
    
"""

response_format_prompt = """
{
    "action":{
        "name": "action name",
        "args": {
            "answer": "任务的最终结果"
        }
    },
    "thoughts": {
        "plan": "简短的描述短期和长期的计划列表",
        "criticism": "建设性的自我批评",
        "speak": "当前步骤,返回给用户的总结",
        "reasoning": "推理"
    },
    "observation": "观察当前任务的整体进度"
}
"""

在这个提示词中加入了工具列表,资源说明,任务需求等;并且约定了大模型的输出格式,以便于进行解析,大模型就可以根据这提示词对任务进行思考和推理。

并且根据推理结果,选择合适的工具来完成对应的任务,比如调用搜索工具完成信息收集,调用文件写入工具把结果写入到文件中。

下图是大模型的思考,推理和工具调用的过程,从图中可以看出大模型经过多次规划才完成的任务。

其次,就是工具集的构建,简单来说就是一些python函数,用来给大模型进行调用:

"""
    1. 写文件
    2. 读文件
    3. 追加
    4. 网络搜索
    
"""

def get_workdir_root():
    workdir_root = os.environ.get("WORKDIR_ROOT", './data/llm_result')
    return workdir_root

WORKDIR_ROOT = get_workdir_root()

def read_file(filename):

    if not os.path.exists(filename):
        return f"{filename} not exist, please check file exist before read"

    with open(filename, "r") as f:
        return "\n".join(f.readline())


def append_to_file(filename, content):
    filename = os.path.join(WORKDIR_ROOT, filename)

    if not os.path.exists(filename):
        return f"{filename} not exist, please check file exist before read"

    with open(filename, 'a') as f:
        f.write(content)

    return "append content to file success"

def write_to_file(filename, content):
    filename = os.path.join(WORKDIR_ROOT, filename)

    if not os.path.exists(WORKDIR_ROOT):
        os.makedirs(WORKDIR_ROOT)

    with open(filename, 'w') as f:
        f.write(content)

    return "write content to file success"

def search(query):
    tavily = TavilySearchResults(max_results=5)

    try:
        ret = tavily.invoke(input=query)

        """
            ret:
            [{
                "content": "",
                "url": ""
            }]
        """
        print("搜索结果", ret)
        content_list = [obj["content"] for obj in ret]
        return "\n".join(content_list)
    except Exception as err:
        return "search err: {}".format(err)

tools_info = [
    {
        "name": "read_file",
        "description": "read file from agent generate, should write file before read.",
        "args": [
            {
                "name": "filename",
                "type": "string",
                "description": "read file name"
            }
        ]
    },
    {
        "name": "append_to_file",
        "description": "append llm content to file, should write file before read.",
        "args": [
            {
                "name": "filename",
                "type": "string",
                "description": "file name"
            },
            {
                "name": "filename",
                "type": "string",
                "description": "append to file content"
            }
        ]
    },
{
        "name": "write_to_file",
        "description": "write llm content to file",
        "args": [
            {
                "name": "filename",
                "type": "string",
                "description": "file name"
            },
            {
                "name": "filename",
                "type": "string",
                "description": "write to file content"
            }
        ]
    },
    {
        "name": "search",
        "description": "this is a search engine, you can gain additional knowledge though this search engine when you are unsure of what large model return",
        "args": [
            {
                "name": "query",
                "type": "string",
                "description": "search query to lookup"
            }
        ]
    },
    {
        "name": "finish",
        "description": "完成用户目标",
        "args": [{
            "name": "answer",
            "type": "string",
            "description": "最后的目标结果"
        }]
    }
]

tools_map = {
    "read_file": read_file,
    "append_to_file": append_to_file,
    "write_to_file": write_to_file,
    "search": search
}

def gen_tools_desc():
    tools_desc = []
    for idx, t in enumerate(tools_info):
        args_desc = []
        for info in t['args']:
            args_desc.append({
                "name": info['name'],
                "description": info["description"],
                "type": info['type']
            })
        args_desc = json.dumps(args_desc, ensure_ascii=False)
        tool_desc = f"{idx + 1}. {t['name']}: {t['description']}, args: {args_desc}"
        tools_desc.append(tool_desc)

    tools_prompt = "\n".join(tools_desc)
    return tools_prompt

最后两个就是大模型的调用模块和业务的解析模块,大模型的调用模块相对比较简单,这里就不仔细说了,感兴趣的可以直接看代码。

解析模块说简单也简单,说复杂也复杂;因为当前的功能比较简单,因此只需要使用大模型本身的能力即可,然后完成对大模型每次思考和规划数据的解析即可。

而如果后续需要开发更加复杂的业务功能,比如说金融行业的投资分析,需要非常复杂的业务分析等环节,这时只依靠大模型本身的能力就不行了。

比如说,由于大模型在垂直领域的表现不佳,直接使用可能会带来幻觉等问题;还有就是Agent的记忆模块,在大量的复杂业务分析中,需要增加外部存储模块来记录历史记忆功能,这样才能更好地完成复杂的任务处理。

"""
todo:
环境变量的设置
工具的引入
prompt模板
模型的初始化
"""

# 初始化模型
mp = ModelProvider()

# 解析大模型的响应
def parse_thoughts(response):
    try:
        thoughts = response.get("thoughts")
        observation = response.get("observation")

        plan = thoughts.get("plan")
        reasoning = thoughts.get("reasoning")
        criticism = thoughts.get("criticism")
        prompt = f"plan: {plan}\n reasoning: {reasoning}\n criticism: {criticism}\nobservation: {observation}"
        print("thoughts: ", prompt)
        return prompt
    except Exception as err:
        print("parse thoughts err: {}".format(err))
        return "".format(err)

def agent_execute(query, max_request_time=10):
    cur_request_time = 0
    # 大模型记忆 包括短期记忆和长期记忆
    chat_history = []
    # agent 反思 规划等
    agent_scratch = ''
    while cur_request_time < max_request_time:
        cur_request_time += 1
        """
            如果返回结果达到预期,则直接返回
        """
        # 提示词模板
        """
            prompt包含的功能:
            1. 任务描述
            2. 工具描述
            3. 用户的输入user_msg
            4. assistant_msg
            5. 限制
            6. 给出更好实践的描述
        """
        prompt = gen_prompt(query, agent_scratch)

        start_time = time.time()
        print("--------------------------{}, 开始调用大模型LLM------------".format(cur_request_time), flush=True)

        # 调用大模型 直接返回json格式数据
        """
            sys_prompt:
            user_msg, assistant, history
        """

        if cur_request_time < 3:
            print("prompt: ", prompt)

        # response = call_llm()

        response = mp.chat(prompt, chat_history=chat_history)
        end_time = time.time()
        print("--------------------------{}, 调用大模型結束,耗时:{}---------------".format(cur_request_time, end_time-start_time), flush=True)

        if not response or not isinstance(response, dict):
            print("调用大模型错误, 即将重试: ", response)
            continue

        """
        大模型返回格式约定
            response: 
            {
                "action":{
                    "name": "action name",
                    "args": {
                        "args name": "args values"
                    }
                },
                "thoughts": {
                    "text": "thought",
                    "plan": "plan",
                    "criticism": "criticism",
                    "speak": "当前步骤,返回给用户的总结",
                    "reasoning": ""
                }
            }
        """


        action_info = response.get("action")
        action_name = action_info.get("name")
        action_args = action_info.get("args")
        print("当前action name: ", action_name, action_args)

        if action_name == "finish":
            final_answer = action_args.get("answer")
            print("final_answer: ", final_answer)
            break

        observation = response.get("observation")

        try:
            """
                action_name 到函数的映射, map -> { action_name: func }
                
            """
            # todo: tools_map 的实现
            # tools_map = {}
            func = tools_map.get(action_name)
            call_func_result = func(**action_args)

        #  { action_name: func }
        except Exception as err:
            print("调用工具异常: ", err)
            call_func_result = "{}".format(err)
        agent_scratch = agent_scratch + "\n:observation:{}\n execute action result: {}".format(observation, call_func_result)

        # 由于大模型没有记忆功能,因此需要把大模型之前的输入和输出加入到history中,这也是Agent四大块中的记忆模块 由于目前的业务并不复杂,因此不需要外部记忆模块 如果业务比较复杂可能还需要外部模块进行存储
        assistant_msg = parse_thoughts(response)

        chat_history.append([user_prompt, assistant_msg])

    if cur_request_time == max_request_time:
        print("很遗憾,本次任务失败")
    else:
        print("恭喜你,任务完成")

def main():
     # 支持用户多次交互 最大规划次数设置为10次 当超过10次时 则说明任务失败 用户可以根据自己的情况进行调整
    max_request_time = 10
    while True:
        query = input("请输入你的目标:")
        if query == "exit":
            return

        agent_execute(query, max_request_time=max_request_time)


if __name__ == "__main__":
    main()

最后,这里只是为了实现Agent的实现流程,并且由于大模型的质量问题,也不能保证每次都能成功。

受限于大模型的性能问题,大模型在推理和规划方面表现还不尽人意,因此怎么才能让大模型更好实现复杂推理规划是一个值得研究的问题。

里面主要涉及两个第三方模块,一个是第三方大模型的申请,个人使用的是阿里的通义千问;第二个是Travily的搜索接口,官网地址:https://app.tavily.com用户也可以自己去申请或者使用其它搜索工具,比如百度搜索等。

最后唠两句

为什么AI大模型成为越来越多程序员转行就业、升职加薪的首选

很简单,这些岗位缺人且高薪

智联招聘的最新数据给出了最直观的印证:2025年2月,AI领域求职人数同比增幅突破200% ,远超其他行业平均水平;整个人工智能行业的求职增速达到33.4%,位居各行业榜首,其中人工智能工程师岗位的求职热度更是飙升69.6%。

在这里插入图片描述

AI产业的快速扩张,也让人才供需矛盾愈发突出。麦肯锡报告明确预测,到2030年中国AI专业人才需求将达600万人,人才缺口可能高达400万人,这一缺口不仅存在于核心技术领域,更蔓延至产业应用的各个环节。

那0基础普通人如何学习大模型 ?

深耕科技一线十二载,亲历技术浪潮变迁。我见证那些率先拥抱AI的同行,如何建立起效率与薪资的代际优势。如今,我将积累的大模型面试真题、独家资料、技术报告与实战路线系统整理,分享于此,为你扫清学习困惑,共赴AI时代新程。

我整理出这套 AI 大模型突围资料包【允许白嫖】:

  • ✅从入门到精通的全套视频教程

  • ✅AI大模型学习路线图(0基础到项目实战仅需90天)

  • ✅大模型书籍与技术文档PDF

  • ✅各大厂大模型面试题目详解

  • ✅640套AI大模型报告合集

  • ✅大模型入门实战训练

这份完整版的大模型 AI 学习和面试资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费】

在这里插入图片描述

①从入门到精通的全套视频教程

包含提示词工程、RAG、Agent等技术点

在这里插入图片描述

② AI大模型学习路线图(0基础到项目实战仅需90天)

全过程AI大模型学习路线

在这里插入图片描述

③学习电子书籍和技术文档

市面上的大模型书籍确实太多了,这些是我精选出来的

在这里插入图片描述

④各大厂大模型面试题目详解

在这里插入图片描述

⑤640套AI大模型报告合集

在这里插入图片描述

⑥大模型入门实战训练

在这里插入图片描述

如果说你是以下人群中的其中一类,都可以来智泊AI学习人工智能,找到高薪工作,一次小小的“投资”换来的是终身受益!

应届毕业生‌:无工作经验但想要系统学习AI大模型技术,期待通过实战项目掌握核心技术。

零基础转型‌:非技术背景但关注AI应用场景,计划通过低代码工具实现“AI+行业”跨界‌。

业务赋能 ‌突破瓶颈:传统开发者(Java/前端等)学习Transformer架构与LangChain框架,向AI全栈工程师转型‌。

👉获取方式:
有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

在这里插入图片描述

LLM ReAct: 将推理和行为相结合的通用范式 学习记录 阅读详情

相关推荐

教授 LLM 思考和行动:ReAct Prompt Engineering

普林斯顿大学教授和谷歌研究人员最近发表了一篇论文,描述了一种新颖的提示工程方法,该方法使大型语言模型(想想 ChatGPT)能够在模拟环境中进行推理和智能行动。这种 ReAct 方法模仿人类在现实世界中的运作方式,因为我们可以通过口头推理并采取行动来获取信息。ReAct 被发现在各种领域中与其他提示工程(和模仿学习)方法相比表现良好。这标志着朝着人工通用智能 (AGI) 和具身语言模型(像人类一样思考的机器人)迈出了重要一步。

iCloudEnd的博客 803

理解LLM中的ReAct

large language models (LLMs)大语言模型在语义理解和交互式决策方面有着不错的表现。ReAct在一次交互中循环使用推理和行动两个操作解决复杂问题,推理即利用模型自身语义理解能力,行动则利用模型以外的能力(如计算、搜索最新消息,用户自定义的行动)。Observation:可以理解为从模型以外获取的信息(如查询的信息、计算的信息)Action:采取的行动,如:搜索Search,匹配最相近结果Lookup。Thought:模型利用已有信息进行推理。一个使用 ReAct 的例子。

weixin_40994552的博客 2300

用AI画电路板AI EDA初探Creating WiFi Radio with CELUS: A Step-by-Step Tutorial 使用CELU.IO创建WiFi收音机:分步教程

结论:整体还不太成熟,所选器件单元是欧美思维,器件选型成本和咱们华强北还是无法比。可以关注迭代,看客就当走马观花就行了;不过里面的单元模块还带有AI提问的这个比较好,值得国内EDA从业者学习。话不多说上正文:本教程目的是让我们深入了解如何使用CELUS设计平台构建WiFi收音机实战项目。本指南的重点是使用该平台来选择正确的解决方案,并整合一个项目,让您可以将音乐和节目从互联网直接传输到您自己构建的扬声器。

2301_81235726的博客 1万+

进阶篇11ReAct框架案例实现

ReAct是Reasoning and Acting(也有一说是Reason Act)缩写,意思是LLM可以根据逻辑推理(Reason),构建完整系列行动(Act),从而达成期望目标。LLM灵感来源是人类行为和推理之间的协同关系。人类根据这种协同关系学习新知识,做出决策,然后执行。LLM模型在逻辑推理上有着非常优秀的表现,因此有理由相信LLM模型也可以像人类一样进行逻辑推理,学习知识,做出决策,并执行。在实际使用中,LLM会发生幻觉和错误判断的情况。这是因为LLM在训练的时候接触到的知识有限。

omonday1234的专栏 1119

【老生谈算法】可视化通道流中瞬时涡量场的算法实现与MATLAB源码分析——瞬时涡量场

本文旨在探讨可视化通道流中瞬时涡量场的方法,并通过MATLAB编程实现这一过程。涡量场作为描述流体旋涡强度和方向的重要物理量,对于理解复杂流体运动具有重要意义。本文首先介绍了涡量场的基本概念,随后详细阐述了从测量数据收集到涡量场可视化的完整流程,并给出了相应的MATLAB源码。通过实际运行该源码,我们展示了涡量场的可视化结果,并讨论了其在流动结构识别和动力学行为理解中的应用。关键词: 涡量场;流体运动;MATLAB;可视化;PIV一、引言。

m0_53407570的博客 1127

编程小白的自学笔记四(正则表达式模块search函数)

本文仅仅简单介绍了search的使用,供小白学习探讨。

m0_49914128的博客 2322

大模型ReAct框架——打造AI Agent的代码实现——基于LLM + Function Call构建Agent

“Agent通过大模型的推理和规划,使得大模型真正实现类似人类的能力” AI Agent也就是AI智能体,是通过把大模型作为“大脑”,通过利用大模型的推理和规划能力,然后调用外部工具来完成复杂任务的一种方式。 简单来说,Agent就是一种让大模型自己思考和分析问题,选择合适的工具,最终解决问题的一种方法,其背后原理就来自于ReAct。

2401_85325397的博客 3246

BIDS数据存储格式介绍与dcm2bids安装与使用

BIDS格式&dcm2bids安装与使用

machinelearning_er的博客 7318

大模型ReAct框架 | 打造AI Agent的代码实现,基于LLM + Function Call构建Agent

AI Agent也就是AI智能体,是通过把大模型作为“大脑”,通过利用大模型的推理和规划能力,然后调用外部工具来完成复杂任务的一种方式。简单来说,Agent就是一种让大模型自己思考和分析问题,选择合适的工具,最终解决问题的一种方法,其背后原理就来自于ReAct。ReAct是Reasoning And Acting的缩写,意思是LLM可以根据逻辑推理(Reson),构建完整系列行动(Act),从而达到期望目标。

m0_56255097的博客 1469

【逐函数讲解ORB_SLAM3源码】获取普通帧率、关键帧、IMU数据

获得imu的旋转 mRwc * mImuCalib.mTcb.rotationMatrix(); Sophus::SE3 mTwc 创建ORB_SLAM3系统 Create SLAM system. It initializes all system threads and gets ready to process frames. ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::IMU_RGBD, true, 0, file_nam

小秋 AI SLAM 入门实战教程 1245

一、C++反作弊对抗实战 (基础篇 —— 2.注册表注入DLL)

在Windows NT/XP操作系统中,当需要加载user32.dll的程序启动时,user32.dll会加载注册表键HLM\Software\Microsoft\WindowsNT\CurrentVersion\Windows\AppInit_dlls下面列出的所有模块。

Koma的主页 1098

从ReAct到AI Agent:工程化实现与架构设计实战指南

大语言模型(LLM)与函数调用(Function Call)的结合,为构建能够自主执行复杂任务的智能体(Agent)提供了技术基础。其核心原理在于通过“思考-行动-观察”(ReAct)的循环机制,使LLM能够规划决策并调用外部工具。这种模式的技术价值在于将大模型的通用推理能力与专用工具的执行能力相结合,从而解决单一模型在实时性、精确操作和领域知识上的局限。在应用场景上,它广泛适用于需要与外部系统交互的自动化任务,如信息检索、数据分析和流程编排。本文聚焦于工程实践,详细探讨了如何将ReAct理论框架落地为稳定

anchang7456的博客 412

微信小程序 - 最新详细实现模板消息订阅通知功能,给用户微信发送“服务通知“模板消息并点击进入跳转到小程序页面路由,订阅消息通知详细后台申请流程及示例代码,解决授权申请弹框被拒绝后无法调起、常见报错!

微信小程序,vue2,vue3,模板消息,订阅通知,服务通知,小程序模板通知,订阅微信模板消息功能,唤起模板消息订阅弹框并发送服务通知,消息订阅与模板消息发送,一次性订阅,长期永久订阅,申请模板id,详细示例代码教程,配置流程,消息模板,模板ID,用户收不到消息,订阅了通知但微信不来服务通知,报错,小程序平台模板消息订阅功能,唤起订阅模板消息弹框,订阅模板消息发送服务通知功能,如何做模板消息订阅,一直收不到通知,用户通过弹窗订阅,订阅消息,无法打开申请授权弹框,用户拒绝/关闭后,如何引导用户再开启,拒绝后怎

🏆 前端领域优质创作者 5329
上一篇: 【AI大模型】一文彻底搞懂人工智能的嵌入(Embedding)
下一篇: 深度解析从RAG到多模态RAG,收藏这一篇就够了!!!
Agent学习路线
博客等级 码龄6年 1万+粉丝 1904原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值