【智能體Agent】ReAct智能體的實現思路和關鍵技術

基于ReAct(Reasoning + Acting)框架的自主智能體

import re
from typing import List, Tuplefrom langchain_community.chat_message_histories.in_memory import ChatMessageHistory
from langchain_core.language_models.chat_models import BaseChatModel
from langchain.output_parsers import PydanticOutputParser, OutputFixingParser
from langchain.schema.output_parser import StrOutputParser
from langchain.tools.base import BaseTool
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.tools import  render_text_description
from pydantic import ValidationError
from langchain_core.prompts import HumanMessagePromptTemplatefrom Agent.Action import Action
from Utils.CallbackHandlers import *class ReActAgent:"""AutoGPT:基于Langchain實現"""@staticmethoddef __format_thought_observation(thought: str, action: Action, observation: str) -> str:# 將全部JSON代碼塊替換為空ret = re.sub(r'```json(.*?)```', '', thought, flags=re.DOTALL)ret += "\n" + str(action) + "\n返回結果:\n" + observationreturn ret@staticmethoddef __extract_json_action(text: str) -> str | None:# 匹配最后出現的JSON代碼塊json_pattern = re.compile(r'```json(.*?)```', re.DOTALL)matches = json_pattern.findall(text)if matches:last_json_str = matches[-1]return last_json_strreturn Nonedef __init__(self,llm: BaseChatModel,tools: List[BaseTool],work_dir: str,main_prompt_file: str,max_thought_steps: Optional[int] = 10,):self.llm = llmself.tools = toolsself.work_dir = work_dirself.max_thought_steps = max_thought_steps# OutputFixingParser: 如果輸出格式不正確,嘗試修復self.output_parser = PydanticOutputParser(pydantic_object=Action)self.robust_parser = OutputFixingParser.from_llm(parser=self.output_parser,llm=llm)self.main_prompt_file = main_prompt_fileself.__init_prompt_templates()self.__init_chains()self.verbose_handler = ColoredPrintHandler(color=THOUGHT_COLOR)def __init_prompt_templates(self):with open(self.main_prompt_file, 'r', encoding='utf-8') as f:self.prompt = ChatPromptTemplate.from_messages([MessagesPlaceholder(variable_name="chat_history"),HumanMessagePromptTemplate.from_template(f.read()),]).partial(work_dir=self.work_dir,tools=render_text_description(self.tools),tool_names=','.join([tool.name for tool in self.tools]),format_instructions=self.output_parser.get_format_instructions(),)def __init_chains(self):# 主流程的chainself.main_chain = (self.prompt | self.llm | StrOutputParser())def __find_tool(self, tool_name: str) -> Optional[BaseTool]:for tool in self.tools:if tool.name == tool_name:return toolreturn Nonedef __step(self,task,short_term_memory,chat_history,verbose=False) -> Tuple[Action, str]:"""執行一步思考"""inputs = {"input": task,"agent_scratchpad": "\n".join(short_term_memory),"chat_history": chat_history.messages,}config = {"callbacks": [self.verbose_handler]if verbose else []}response = ""for s in self.main_chain.stream(inputs, config=config):response += s# 提取JSON代碼塊json_action = self.__extract_json_action(response)# 帶容錯的解析action = self.robust_parser.parse(json_action if json_action else response)return action, responsedef __exec_action(self, action: Action) -> str:# 查找工具tool = self.__find_tool(action.name)if tool is None:observation = (f"Error: 找不到工具或指令 '{action.name}'. "f"請從提供的工具/指令列表中選擇,請確保按對頂格式輸出。")else:try:# 執行工具observation = tool.run(action.args)except ValidationError as e:# 工具的入參異常observation = (f"Validation Error in args: {str(e)}, args: {action.args}")except Exception as e:# 工具執行異常observation = f"Error: {str(e)}, {type(e).__name__}, args: {action.args}"return observationdef run(self,task: str,chat_history: ChatMessageHistory,verbose=False) -> str:"""運行智能體:param task: 用戶任務:param chat_history: 對話上下文(長時記憶):param verbose: 是否顯示詳細信息"""# 初始化短時記憶: 記錄推理過程short_term_memory = []# 思考步數thought_step_count = 0reply = ""# 開始逐步思考while thought_step_count < self.max_thought_steps:if verbose:self.verbose_handler.on_thought_start(thought_step_count)# 執行一步思考action, response = self.__step(task=task,short_term_memory=short_term_memory,chat_history=chat_history,verbose=verbose,)# 如果是結束指令,執行最后一步if action.name == "FINISH":reply = self.__exec_action(action)break# 執行動作observation = self.__exec_action(action)if verbose:self.verbose_handler.on_tool_end(observation)# 更新短時記憶short_term_memory.append(self.__format_thought_observation(response, action, observation))thought_step_count += 1if thought_step_count >= self.max_thought_steps:# 如果思考步數達到上限,返回錯誤信息reply = "抱歉,我沒能完成您的任務。"# 更新長時記憶chat_history.add_user_message(task)chat_history.add_ai_message(reply)return reply

結合LangChain框架和工具調用能力來逐步解決用戶任務。

以下是代碼的逐模塊解析:


1. 核心結構

class ReActAgent:"""AutoGPT:基于Langchain實現"""
  • 核心類:實現了ReAct范式(推理+行動循環)的自主智能體
  • 核心能力
    • 多步思考推理
    • 工具調用
    • 長短期記憶管理
    • 異常處理與自我修正

2. 關鍵靜態方法

@staticmethod
def __format_thought_observation(...):  # 格式化思考記錄
@staticmethod
def __extract_json_action(...):         # 提取JSON動作
  • 功能
    • __format_thought_observation:將思考過程、動作執行和觀察結果格式化為可讀文本,存入短期記憶
    • __extract_json_action:用正則表達式提取模型輸出中的最后一個JSON代碼塊(確保獲取最新動作)

3. 初始化模塊

def __init__(...):# 核心組件初始化self.llm = llm                    # 大語言模型self.tools = tools                # 可用工具列表self.work_dir = work_dir          # 工作目錄self.max_thought_steps = ...      # 最大思考步數# 輸出解析系統self.output_parser = PydanticOutputParser(pydantic_object=Action)self.robust_parser = OutputFixingParser.from_llm(...)# 提示工程self.__init_prompt_templates()self.__init_chains()
  • 關鍵技術點
    • 雙解析器機制OutputFixingParser可在格式錯誤時自動修復輸出
    • Pydantic驗證:確保動作符合預定義結構(Action模型)
    • 工具描述渲染render_text_description將工具轉化為自然語言描述

4. 提示工程系統

def __init_prompt_templates(self):with open(self.main_prompt_file) as f:self.prompt = ChatPromptTemplate.from_messages(...).partial(tools=...,             # 工具描述tool_names=...,        # 工具名稱列表format_instructions=..., # 格式說明)
  • 核心要素
    • 動態加載提示模板文件
    • 包含:
      • 聊天歷史占位符
      • 工具使用說明
      • 輸出格式要求
      • 工作目錄上下文

5. 執行流程控制

def run(...):while thought_step_count < self.max_thought_steps:# 單步思考action, response = self.__step(...)if action.name == "FINISH":break# 執行動作observation = self.__exec_action(action)# 記憶更新short_term_memory.append(...)
  • ReAct循環
    1. Reasoning:生成思考與動作(__step
    2. Acting:執行工具調用(__exec_action
    3. Observing:記錄執行結果
    4. Loop:直到達到終止條件

6. 關鍵技術實現

6.1 單步推理 (__step)
def __step(...):inputs = {"input": task,"agent_scratchpad": "\n".join(short_term_memory),"chat_history": chat_history.messages,}# 流式處理LLM輸出for s in self.main_chain.stream(inputs):response += s# 提取并解析動作json_action = self.__extract_json_action(response)action = self.robust_parser.parse(...)
  • 輸入組成
    • 任務目標
    • 短期記憶(推理過程)
    • 長期記憶(聊天歷史)
  • 流式處理:實時顯示思考過程
  • 錯誤恢復:自動修復格式錯誤的JSON輸出
6.2 動作執行 (__exec_action)
def __exec_action(...):tool = self.__find_tool(action.name)try:observation = tool.run(action.args)except ValidationError:# 參數驗證錯誤處理except Exception:# 通用錯誤處理
  • 異常處理機制
    • 工具不存在
    • 參數驗證錯誤
    • 運行時異常
  • 觀察反饋:將錯誤信息轉化為自然語言,供后續推理使用

7. 記憶系統

# 短期記憶
short_term_memory = []  # 存儲格式化的推理過程# 長期記憶
chat_history = ChatMessageHistory()  # 保存完整對話記錄
  • 記憶類型
    • 短期記憶:當前任務的推理過程(最多保留max_thought_steps步)
    • 長期記憶:跨會話的完整對話歷史

8. 關鍵設計亮點

  1. 自愈式輸出解析

    • 通過OutputFixingParser實現格式錯誤自動修復
    • 示例場景:當LLM返回非法JSON時,自動嘗試修正
  2. 漸進式推理

    # 示例輸出格式
    Thought: 我需要先查找用戶信息
    Action: {"name": "user_search", "args": {"id": 123}}
    Observation: 用戶張三,年齡30
    • 通過agent_scratchpad維護推理上下文
  3. 工具發現機制

    • 動態渲染工具描述到提示詞
    • 支持工具的熱插拔
  4. 多級異常處理

    • 工具不存在
    • 參數驗證錯誤
    • 執行時異常
    • 最大步數限制

9. 使用示例

# 初始化組件
llm = ChatOpenAI()
tools = [SearchTool(), Calculator()]
agent = ReActAgent(llm, tools, work_dir="/data")# 執行任務
result = agent.run(task="計算馬云當前年齡的平方根",chat_history=ChatMessageHistory(),verbose=True
)
  • 典型執行流程
    1. 搜索"馬云年齡" → 得到60歲
    2. 調用計算器計算√60 → 約7.746
    3. 返回最終結果

10. 可擴展性建議

  1. 增強記憶管理

    • 添加向量數據庫長期記憶
    • 實現記憶壓縮/摘要
  2. 改進推理質量

    • 添加自我驗證步驟
    • 實現多路徑推理
  3. 性能優化

    • 添加異步執行
    • 實現工具并行調用

該實現展示了如何結合LangChain框架構建復雜的自主智能體系統,平衡了LLM的創造力和結構化工具調用的可靠性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72565.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72565.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72565.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Electron打包工具對比

在 Electron 生態中&#xff0c;打包工具的選擇直接影響開發效率、配置復雜度和最終應用的性能。以下是主流的 Electron 打包工具及其優劣分析&#xff0c;結合你的 Vue 項目需求&#xff0c;我會在最后給出推薦方案&#xff1a; 一、主流 Electron 打包工具對比 1. Electron …

云原生系列之本地k8s環境搭建

前置條件 Windows 11 家庭中文版&#xff0c;版本號 23H2 云原生環境搭建 操作系統啟用wsl(windows subsystem for linux) 開啟wsl功能&#xff0c;如下圖 安裝并開啟github加速器 FastGithub 2.1 下載地址&#xff1a;點擊下載 2.2 解壓安裝文件fastgithub_win-x64.zip 2…

【計算機網絡入門】TCP擁塞控制

目錄 1. TCP擁塞控制和TCP流量控制的區別 2. 檢測到擁塞該怎么辦 2.1 如何判斷網絡擁塞&#xff1f; 3. 慢開始算法 擁塞避免算法 4.快重傳事件->快恢復算法 5. 總結 1. TCP擁塞控制和TCP流量控制的區別 TCP流量控制是控制端對端的數據發送量。是局部的概念。 TCP擁…

Spring Boot 整合 JMS-ActiveMQ,并安裝 ActiveMQ

1. 安裝 ActiveMQ 1.1 下載 ActiveMQ 訪問 ActiveMQ 官方下載頁面&#xff0c;根據你的操作系統選擇合適的版本進行下載。這里以 Linux 系統&#xff0c;Java環境1.8版本為例&#xff0c;下載 apache-activemq-5.16.7-bin.tar.gz。 1.2 解壓文件 將下載的壓縮包解壓到指定目…

《幾何原本》命題I.13

《幾何原本》命題I.13 兩條直線相交&#xff0c;鄰角是兩個直角或者相加等于 18 0 ° 180^{\circ} 180°。 若兩角相等&#xff0c;則根據定義&#xff0c;兩角為直角。 兩角若不相等&#xff0c;如圖&#xff0c;則 ( ∠ 1 ∠ 2 ) ∠ 3 ∠ 1 ( ∠ 2 ∠ 3 ) 9 0 ° …

優先級隊列:通過堆的形式實現

描述: 大頂堆: 小頂堆: 索引位置查找: 代碼實現: package com.zy.queue_code.deque;/*** @Author: zy* @Date: 2025-03-05-15:51* @Description:*/ public interface Priority

《OpenCV》—— dlib庫

文章目錄 dlib庫是什么&#xff1f;OpenCV庫與dlib庫對比dlib庫安裝dlib——人臉應用實例——人臉檢測dlib——人臉應用實例——人臉關鍵點定位dlib——人臉應用實例——人臉輪廓繪制 dlib庫是什么&#xff1f; OpenCV庫與dlib庫對比 dlib庫安裝 dlib——人臉應用實例——人臉檢…

藍橋與力扣刷題(藍橋 旋轉)

題目&#xff1a;圖片旋轉是對圖片最簡單的處理方式之一&#xff0c;在本題中&#xff0c;你需要對圖片順時針旋轉 90 度。 我們用一個 nm的二維數組來表示一個圖片&#xff0c;例如下面給出一個 34 的 圖片的例子&#xff1a; 1 3 5 7 9 8 7 6 3 5 9 7 這個圖片順時針旋轉…

隨機播放音樂 偽隨機

import java.util.*;/*** https://cloud.tencent.com.cn/developer/news/1045747* 偽隨機播放音樂*/ public class MusicPlayer {private List<String> allSongs; // 所有歌曲列表private List<String> playedSongs; // 已經播放過的歌曲列表private Map<String…

MiniMind用極低的成本訓練屬于自己的大模型

本篇文章主要講解&#xff0c;如何通過極低的成本訓練自己的大模型的方法和教程&#xff0c;通過MiniMind快速實現普通家用電腦的模型訓練。 日期&#xff1a;2025年3月5日 作者&#xff1a;任聰聰 一、MiniMind 介紹 基本信息 在2小時&#xff0c;訓練出屬于自己的28M大模型。…

區塊鏈中的數字簽名:安全性與可信度的核心

數字簽名是區塊鏈技術的信任基石&#xff0c;它像區塊鏈世界的身份證和防偽標簽&#xff0c;確保每一筆交易的真實性、完整性和不可抵賴性。本文會用通俗的語言&#xff0c;帶你徹底搞懂區塊鏈中的數字簽名&#xff01; 文章目錄 1. 數字簽名是什么&#xff1f;從現實世界到區塊…

LLM自動金融量化-CFGPT

LLM自動金融量化-CFGPT 簡介 CFGPT是一個開源的語言模型,首先通過在收集和清理的中國金融文本數據(CFData-pt)上進行繼續預訓練,包括金融領域特定數據(公告、金融文章、金融考試、金融新聞、金融研究論文)和通用數據(維基百科),然后使用知識密集的指導調整數據(CFD…

解決Docker拉取鏡像超時錯誤,docker: Error response from daemon:

當使用docker pull或docker run時遇到net/http: request canceled while waiting for connection的報錯&#xff0c;說明Docker客戶端在訪問Docker Hub時出現網絡連接問題。可以不用掛加速器也能解決&#xff0c;linux不好用clash。以下是經過驗證的方法&#xff08;感謝軒轅鏡…

03.05 QT事件

實現一個繪圖工具&#xff0c;具備以下功能&#xff1a; 鼠標繪制線條。 實時調整線條顏色和粗細。 橡皮擦功能&#xff0c;覆蓋繪制內容。 撤銷功能&#xff0c;ctrl z 快捷鍵撤銷最后一筆 程序代碼&#xff1a; <1> Widget.h: #ifndef WIDGET_H #define WIDGET…

【文生圖】windows 部署stable-diffusion-webui

windows 部署stable-diffusion-webui AUTOMATIC1111 stable-diffusion-webui Detailed feature showcase with images: 帶圖片的詳細功能展示: Original txt2img and img2img modes 原始的 txt2img 和 img2img 模式 One click install and run script (but you still must i…

go語言因為前端跨域導致無法訪問到后端解決方案

前端服務8080訪問后端8081這端口顯示跨域了 ERROR Network Error AxiosError: Network Error at XMLHttpRequest.handleError (webpack-internal:///./node_modules/axios/lib/adapters/xhr.js:116:14) at Axios.request (webpack-internal:///./node_modules/axios/lib/core/A…

hive之lag函數

從博客上發現兩個面試題&#xff0c;其中有個用到了lag函數。整理學習 LAG 函數是 Hive 中常用的窗口函數&#xff0c;用于訪問同一分區內 前一行&#xff08;或前 N 行&#xff09;的數據。它在分析時間序列數據、計算相鄰記錄差異等場景中非常有用。 一、語法 LAG(column,…

【軟考-架構】1.3、磁盤-輸入輸出技術-總線

GitHub地址&#xff1a;https://github.com/tyronczt/system_architect ?資料&文章更新? 文章目錄 存儲系統&#x1f4af;考試真題輸入輸出技術&#x1f4af;考試真題第一題第二題 存儲系統 尋道時間是指磁頭移動到磁道所需的時間&#xff1b; 等待時間為等待讀寫的扇區…

盛鉑科技PDROUxxxx系列鎖相介質振蕩器(點頻源):高精度信號源

——超低相位噪聲、寬頻覆蓋、靈活集成&#xff0c;賦能下一代射頻系統 核心價值&#xff1a;以突破性技術解決行業痛點 在雷達、衛星通信、高速數據采集等高端射頻系統中&#xff0c;信號源的相位噪聲、頻率穩定度及集成靈活性直接決定系統性能上限。盛鉑科技PDROUxxxx系列鎖…

【安裝】SQL Server 2005 安裝及安裝包

安裝包 SQLEXPR.EXE&#xff1a;SQL Server 服務SQLServer2005_SSMSEE.msi&#xff1a;數據庫管理工具&#xff0c;可以創建數據庫&#xff0c;執行腳本等。SQLServer2005_SSMSEE_x64.msi&#xff1a;同上。這個是 64 位操作系統。 下載地址 https://www.microsoft.com/zh-c…