TinyAgent: 从零开始构建最小化Agent系统
引言
随着大模型(LLM)的崛起,特别是ChatGPT等大模型的广泛应用,基于LLM的系统越来越受欢迎。然而,尽管大模型具备强大的生成能力和推理能力,它们在处理某些专有领域或实时问题时仍然存在局限性。因此,结合工具和Agent的概念,增强大模型的实时交互能力,成为解决问题的关键方法。
本文将从零开始,手动构建一个基于React方式的最小化Agent结构,我们称之为TinyAgent。本文会展示如何通过结合LLM与外部工具的方式,赋予大模型实时处理问题的能力。
实现细节
Step 1: 构建大模型
首先,我们需要加载一个大模型作为核心,这里我们选择InternLM2模型。InternLM2是一个Decoder-Only的对话大模型,具备较强的生成能力。我们可以使用transformers
库来加载并运行该模型。
首先,我们定义一个通用的大模型基类BaseModel
,该类用于加载模型和处理输入输出。
class BaseModel:def __init__(self, path: str = '') -> None:self.path = pathdef chat(self, prompt: str, history: List[dict]):passdef load_model(self):pass
然后,我们实现一个继承自BaseModel
的类InternLM2Chat
,这个类实现了具体的模型加载和与模型对话的方法。
class InternLM2Chat(BaseModel):def __init__(self, path: str = '') -> None:super().__init__(path)self.load_model()def load_model(self):print('================ Loading model ================')self.tokenizer = AutoTokenizer.from_pretrained(self.path, trust_remote_code=True)self.model = AutoModelForCausalLM.from_pretrained(self.path, torch_dtype=torch.float16, trust_remote_code=True).cuda().eval()print('================ Model loaded ================')def chat(self, prompt: str, history: List[dict], meta_instruction: str = '') -> str:response, history = self.model.chat(self.tokenizer, prompt, history, temperature=0.1, meta_instruction=meta_instruction)return response, history
Step 2: 构造工具
接下来,我们定义工具类,支持外部功能的调用,比如Google搜索。通过这些工具,可以扩展大模型的能力,从而处理实时或专有领域的任务。
我们首先定义工具的描述信息,并在类Tools
中实现具体的工具操作。
class Tools:def __init__(self) -> None:self.toolConfig = self._tools()def _tools(self):tools = [{'name_for_human': '谷歌搜索','name_for_model': 'google_search','description_for_model': '谷歌搜索是一个通用搜索引擎,可用于访问互联网、查询百科知识、了解时事新闻等。','parameters': [{'name': 'search_query','description': '搜索关键词或短语','required': True,'schema': {'type': 'string'},}],}]return toolsdef google_search(self, search_query: str):url = "https://google.serper.dev/search"payload = json.dumps({"q": search_query})headers = {'X-API-KEY': '你的API_KEY','Content-Type': 'application/json'}response = requests.request("POST", url, headers=headers, data=payload).json()return response['organic'][0]['snippet']
Step 3: 构建Agent
接下来,我们创建一个Agent类,实现ReAct(Reasoning and Acting)范式的Agent。这个Agent可以通过LLM处理输入,并在需要时调用工具。
我们需要构造system_prompt
,让模型了解可以使用哪些工具,以及如何调用这些工具。
class Agent:def __init__(self, path: str = '') -> None:self.path = pathself.tool = Tools()self.system_prompt = self.build_system_input()self.model = InternLM2Chat(path)def build_system_input(self):tool_descs, tool_names = [], []for tool in self.tool.toolConfig:tool_descs.append(TOOL_DESC.format(**tool))tool_names.append(tool['name_for_model'])tool_descs = '\n\n'.join(tool_descs)tool_names = ','.join(tool_names)sys_prompt = REACT_PROMPT.format(tool_descs=tool_descs, tool_names=tool_names)return sys_prompt
通过system_prompt
,我们告知模型可以使用哪些工具,以及如何格式化输入输出。
然后,我们实现一个解析工具调用的逻辑,模型通过解析用户输入决定何时调用工具,并将结果返回。
def parse_latest_plugin_call(self, text):plugin_name, plugin_args = '', ''i = text.rfind('\nAction:')j = text.rfind('\nAction Input:')k = text.rfind('\nObservation:')if 0 <= i < j: # 如果包含Action和Action Inputif k < j: # 且没有Observationtext = text.rstrip() + '\nObservation:' # 添加Observationk = text.rfind('\nObservation:')plugin_name = text[i + len('\nAction:') : j].strip()plugin_args = text[j + len('\nAction Input:') : k].strip()text = text[:k]return plugin_name, plugin_args, text
最后,整合工具调用和LLM的生成过程。
def text_completion(self, text, history=[]):text = "\nQuestion:" + textresponse, his = self.model.chat(text, history, self.system_prompt)print(response)plugin_name, plugin_args, response = self.parse_latest_plugin_call(response)if plugin_name:response += self.call_plugin(plugin_name, plugin_args)response, his = self.model.chat(response, history, self.system_prompt)return response, his
Step 4: 运行Agent
最后,运行我们的Agent,测试其功能。
if __name__ == '__main__':agent = Agent('/root/share/model_repos/internlm2-chat-7b')response, _ = agent.text_completion(text='周杰伦是哪一年出生的?', history=[])print(response)response, _ = agent.text_completion(text='周杰伦是谁?', history=[])print(response)
结语
通过本文的讲解,我们从零开始构建了一个最小化的Agent系统。我们一步一步地实现了如何结合大语言模型(LLM)与外部工具来增强大模型的实际应用能力。尽管大语言模型在很多任务中展现出了惊人的能力,但在面对特定领域的专有任务或实时性要求较高的场景时,单靠语言模型可能会表现不足。Agent系统的核心理念就是让大模型能够借助外部工具(如搜索引擎、数据库等)来完成更加复杂和个性化的任务。
在本项目中,我们基于React范式设计了一个简单的Agent,通过提供工具描述与交互模板,让模型可以理解如何合理调用外部工具。在我们的示例中,模型能够调用Google搜索引擎来获取实时信息,从而补充大模型在某些领域的知识盲点。这种方式大大拓展了大模型的应用边界,不再仅仅依赖于模型参数内的知识,而是能够动态连接外部信息资源。
Agent系统的意义
- 增强信息获取能力:通过工具接口,模型可以即时获取最新信息或查询外部资源,从而突破模型知识更新滞后的局限性。
- 提高任务处理效率:Agent能够通过合理地调用外部工具,更加快速、准确地完成复杂任务。
- 灵活扩展性:我们构建的系统框架具备高度的扩展性,后续可以通过简单的工具插件接口,轻松接入其他任务场景,如金融数据分析、地理信息查询等。
- 实现智能决策:通过多次推理和工具调用,Agent能够像人类一样通过多步推理,获得更符合问题背景的答案,而不是单一的响应。
通过手搓这个TinyAgent,我们不仅熟悉了ReAct范式的原理与实现,还学习了如何通过系统提示与多次推理循环,让大模型具备更强的推理与行动能力。在未来,我们可以进一步优化该框架,将其应用到更广泛的场景中,如智能客服、实时金融预测、医疗信息查询等。
最后,构建Agent系统为大模型的应用开辟了新的可能性,它不仅提升了大模型的智能化水平,也为探索更复杂的任务提供了技术基础。希望本文的讲解能够帮助你深入理解Agent的运作机制,并激发更多关于大模型与工具结合的创新思路。
如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!
欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。
谢谢大家的支持!
相关文章:

TinyAgent: 从零开始构建最小化Agent系统
引言 随着大模型(LLM)的崛起,特别是ChatGPT等大模型的广泛应用,基于LLM的系统越来越受欢迎。然而,尽管大模型具备强大的生成能力和推理能力,它们在处理某些专有领域或实时问题时仍然存在局限性。因此&#…...

Android Studio New里面没有New Flutter Project
跟着Flutter中文网的配置教程,安装好了flutter,在Android studio里面也安装了dart和flutter的插件。重启后还是在FIle->New里面没有显示New Flutter Project。 反复卸载重装dart和flutter插件好几次,依然没有效果。 原来是没有把Android APK Suppor…...

linux信号 | 学习信号四步走 | 透析信号是如何被处理的?
前言:本节内容讲述linux信号的捕捉。 我们通过前面的学习, 已经学习了信号的概念, 信号的产生, 信号的保存。 只剩下信号的处理。 而信号的处理我们应该着重注意的是第三种处理方式——信号的捕捉。 也就是说, 这篇文章…...

mysql语句执行过程
具体流程如下: 1】当客户端的SOL发送到MySQL时,首先是到达服务器层的连接器,连接器会对你此次发起的连接进行权限校验,以此来获取你这个账号拥有的权限。当你的账号或密码不正确时,会报用户错误。连接成功如果后续没有任何操作&am…...

最新版本SkyWalking【10.1.0】部署
这里写目录标题 前言前置条件启动Skywalking下载解压启动说明 集成Skywalking Agent下载Agent在IDEA中添加agent启动应用并访问SpringBoot接口 说明 前言 基于当前最新版10.1.0搭建skywalking 前置条件 装有JDK11版本的环境了解SpringBoot相关知识 启动Skywalking 下载 地…...

WSL2 中配置桥接模式、虚拟交换机及固定 IP
WSL2 中配置桥接模式、虚拟交换机及固定 IP 一、创建虚拟交换机1.1 使用 Hyper-V 管理器创建虚拟交换机1.2 使用 PowerShell 创建虚拟交换机 二、更新 WSL 配置三、设置 WSL2 中的静态 IP、网关和 DNS3.1 编辑网络配置文件3.2 应用网络配置3.3 测试网络连接 四、重启 WSL 在使用…...

Unite Shanghai 2024 团结引擎专场 | 团结引擎 OpenHarmony 工程剖析
在 2024 年 7 月 24 日的 Unite Shanghai 2024 团结引擎专场演讲中,Unity中国 OpenHarmony 技术负责人刘伟贤对团结引擎导出的 OpenHarmony 工程进行了细节剖析,详细讲解 XComponent 如何与引擎结合,UI 线程和引擎线程的关联以及 ts/ets 的代…...

计算机毕业设计 基于Hadoop的智慧校园数据共享平台的设计与实现 Python毕业设计 Python毕业设计选题 Spark 大数据【附源码+安装调试】
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...

2022CCPC绵阳站VP题解报告(CGHMAE六题)
文章目录 2022CCPC绵阳站VP题解报告前言[Problem - C ](https://codeforces.com/gym/104065/problem/C) (签到思维)[H (codeforces.com)](https://codeforces.com/gym/104065/problem/H) (签到构造)[Problem - G ](https://codefo…...

代码随想录day23:贪心part1
455. 分发饼干 class Solution {public int findContentChildren(int[] g, int[] s) {Arrays.sort(g);Arrays.sort(s);int res 0;int index s.length - 1;for(int i g.length - 1; i > 0; i--){if(index > 0 && s[index] > g[i]){res;index--;}}return r…...

通过网页设置参数,submit还是json
在通过网页设置参数并发送到服务器时,选择使用submit(通常是通过HTML表单的提交)还是直接发送JSON数据(通常是通过AJAX请求,如使用fetch API)取决于几个因素,包括你的服务器端如何处理这些请求、…...

C语言 | Leetcode C语言题解之第463题岛屿的周长
题目: 题解: const int dx[4] {0, 1, 0, -1}; const int dy[4] {1, 0, -1, 0};int dfs(int x, int y, int** grid, int n, int m) {if (x < 0 || x > n || y < 0 || y > m || grid[x][y] 0) {return 1;}if (grid[x][y] 2) {return 0;}g…...

逼近理论及应用精解【12】
文章目录 卷积卷积层与滤波层定义数学原理与公式定理架构例子例题 卷积层和滤波层概念的详细解释卷积层滤波层 滤波层和卷积层在卷积神经网络(CNN)中区别滤波层卷积层总结卷积层的数学原理滤波层的数学原理 参考文献 卷积 卷积层与滤波层 定义 卷积层…...

LIN总线学习大全(基于CANoe和CAPL)
🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】🍅 玩转CANoe&…...

国庆作业
day1 1.开发环境 Linux系统GCCFDBmakefilesqlite3 2.功能描述 项目功能: 服务器:处理客户端的请求,并将数据存入数据库中,客户端请求的数据从数据库进行获取,服务器转发给客户端。 用户客户端:实现账号的注册、登…...

Android OpenGLES2.0开发(四):矩阵变换和相机投影
事物的本质是事物本身所固有的、深藏于现象背后并决定或支配现象的方面。 还记得我们上一篇绘制的三角形吗,我们确实能够顺利用OpenGL ES绘制出图形了,这是一个好的开始,但这还远远不够。我们定义的坐标是正三角形,但是绘制出…...

快递查询软件:实现单号识别与批量物流查询的高效工具
随着网络购物的普及,快递物流行业迎来了前所未有的发展机遇,同时也面临着巨大的挑战。跟踪物流信息成为一个难题,因此,快递查询软件的核心功能之一便是单号识别。传统的快递单号输入方式繁琐且易出错在此背景下,快递查…...

nodejs与npm版本对应表
Node.js — Node.js 版本 (nodejs.org)...

Spring Boot 项目中如何使用异步任务
前置知识: 同步任务: 同步任务是在单线程中按顺序执行,每次只有一个任务在执行,不会引发线程安全和数据一致性等并发问题 同步任务需要等待任务执行完成后才能执行下一个任务,无法同时处理多个任务,响应慢…...

Scrum实战中遇到的问题与解决方法
在当今快速变化的技术环境中,IT企业面临着持续的市场压力和竞争,传统的瀑布式开发模式已经难以满足现代企业的需要。瀑布模型过于僵化,缺乏灵活性,导致项目经常延期,成本增加,最终可能无法达到预期效果。为…...

全面介绍 Windows 录屏工具:开启录制新篇章
高质量的录屏工具是我们录屏的得力助手。但是日常因为侧重点的不同,比如有的喜欢录制游戏画面、有的需要录制教学视频、演示操作也需要录屏工具。这次我们就来探讨一下windows录屏工具有哪些吧。 1.福晰录屏大师 链接:www.foxitsoftware.cn/REC/ 从这…...

Maven 和 NetBeans:集成与使用
Maven 和 NetBeans:集成与使用 Maven 和 NetBeans 是两款强大的工具,常用于Java开发。Maven是一个项目管理工具,它能够帮助管理项目的构建、报告和文档。NetBeans是一个集成开发环境(IDE),它为Java开发提供了丰富的功能和友好的用户界面。将Maven集成到NetBeans中,可以…...

【系统架构设计师】目录提纲
一、绪论(TODO) 二、计算机与网络基础知识(TODO) 三、信息系统基础知识(TODO) 四、系统开发基础知识(TODO) 五、软件架构设计(TODO) 六、UML建模与架构文…...

【微服务】—SpringBoot入门
⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记仓库👉https://github.com/A-BigTree/tree-learning-notes 个人主页👉https://www.abigtree.top ⭐⭐⭐⭐⭐⭐ 文章目录 1 SpringBoot快速入门1.1 SpringBoot简介1.1.1 简介1.1.2…...

Linux: debug: perf: report: --sort
文章目录 简介实例简介 接上回:https://mzhan017.blog.csdn.net/article/details/142689870。 这里介绍perf的这个参数,还是非常的有用,尤其是分析对整个系统做perf record的数据,而不是单个进程做perf record。-s, --sort= : Sort histogram entries by given key(s) - …...

like 模糊查询的底层算法
like 模糊查询的底层算法 全文搜索算法、模糊查询、n-gram分隔算法功能介绍 百度搜索,文心一言给出的结果: SQL模糊查询底层通常使用全文搜索算法,如LIKE操作符和全文索引通常使用的n-gram分割算法。 n-gram是一种将文本分割成固定大小的词…...

【Linux实践】实验九:Shell流程控制语句
文章目录 实验九:Shell流程控制语句实验目的:实验内容:操作步骤:1. 复制*.c文件并排序2. 计算1-10的平方 实验九:Shell流程控制语句 实验目的: 掌握条件判断语句,如if语句、case语句。掌握循环…...

YOLOv8实战TT100K中国交通标志检测【数据集+YOLOv8模型+源码+PyQt5界面】
YOLOv8实战TT100k交通标志识别 文章目录 研究背景资源获取1.前言1.1 YOLO 系列:中国交通标志检测领域的璀璨明星1.2 Transformer与注意力机制:为中国交通标志检测注入新活力1.3 中国交通标志检测技术:迎接挑战,砥砺前行1.4 YOLOv8…...

SQLite3
文章目录 SQLite3 C/CAPI介绍SQLite3 C/C API 使⽤ SQLite3 C/CAPI介绍 C/C API是SQLite3数据库的⼀个客⼾端,提供⼀种⽤C/C操作数据库的⽅法。 SQLite3 C/C API 使⽤ 下⾯我们将这⼏个接⼝封装成⼀个类,快速上⼿这⼏个接口 创建/打开数据库文件针对打开…...

我的创作纪念日一年
目录 机缘 收获 日常 成就 憧憬 机缘 我之所以开始写CSDN博客,源于一段特殊的时光。去年此时,我独自待在实验室,周围的世界仿佛与我无关。没有旅游,没有与朋友的欢聚,情感的挫折和学业的压力如潮水般袭来。在这样的…...