[datawhale202405]从零手搓大模型实战:TinyAgent

结论速递

TinyAgent项目实现了一个简单的Agent智能体,主要是实现了ReAct策略(推理+调用工具的能力),及封装了一个Tool。

项目实现有一定的疏漏。为了正确运行代码,本次对代码Agent部分进行了简单修改(完善ReAct prompt及LLM的多次循环调用)。

前情回顾

  1. TinyRAG

目录

    • 结论速递
    • 前情回顾
  • 1 绪论
    • 1.1 LLM Agent
    • 1.2 ReAct
    • 1.3 如何手搓Agent
  • 2 TinyAgent
    • 2.1 项目结构
    • 2.2 代码阅读
      • 2.2.1 Agent
      • 2.2.2 Tool
      • 2.2.3 LLM
    • 2.3 运行案例
      • 2.3.1 代码修改
      • 2.3.2 运行结果
    • 参考阅读

1 绪论

1.1 LLM Agent

Agent是人工智能中一个广为人知的概念,指代理人类完成部分工作的AI程序。

LLM Agent是利用LLM构建Agent,比较受到广泛认可的方式是使用LLM作为Agent的大脑,让其自主规划、利用工具来完成人类指定的任务。如下图所示,图片出自The Rise and Potential of Large Language Model Based Agents: A Survey。

Conceptual framework of LLM-based agent with three components: brain, perception, and
action

关于Agent有很多有名的项目,除了单Agent之外,Multi-agent也是目前一个比较流行的研究方向(simulated agent society)。
请添加图片描述

  • AI小镇
  • ChatDev
  • MetaGPT

1.2 ReAct

ReAct是一种prompt策略,它将CoT(思维链策略)和action(操作工具)结合,使LLM能够实时规划和调整操作工具的策略,从而完成较复杂的任务。下图出自ReAct project。

1.3 如何手搓Agent

之前简单玩过Langchain和CrewAI的agent,都是ReAct策略的agent,简单理解agent是prompt-based的role+tool use,其中tool use借助ReAct实现

所以,手搓Agent需要完成

  • 定义Agent的prompt构建:
    • 角色
    • 任务
    • ReAct策略
  • tool:
    • input处理:把agent的动作处理为API的输入
    • 调用API

2 TinyAgent

2.1 项目结构

项目由三大部分构成

  • Agent:集成了prompt模板,其中agent的动作的截取也在此实现
  • Tool:实现了tool的封装
  • LLM:实现LLM的调用

2.2 代码阅读

2.2.1 Agent

代码详见tinyAgent/Agent.py,下为笔记

有两大部分组成

  • prompt:分为两块,一块是tool描述的模板,一块是ReAct的模板
    在这里插入图片描述
    • tool描述:由三个部分组成,tool唯一名name_for_model,tool描述(name_for_human工具人类名,description_for_model工具功能),调用tool所需要生成的格式及参数(JSON格式,指定parameters)。
      其中tool唯一名 和 调用tool所需要生成的格式及参数 是decode LLM的回复时需要的,tool描述是方便LLM理解这个工具是干什么的(这个在多工具时很重要)
    {name_for_model}: Call this tool to interact with the {name_for_human} API. What is the {name_for_human} API useful for? {description_for_model} Parameters: {parameters} Format the arguments as a JSON object.
    
    • ReAct策略:规定了由Question,Thought,Action,Action Input, Observation构成,并且从思考动作到观测这个步骤可以重复多次。这个是ReAct的核心。
  • Agent:
    • LLM调用:build_system_input构建调用LLM所需的prompt,text_completion调用LLM生成回复。只执行了两次调用
    • 工具调用:parse_latest_plugin_call解析/解码LLM回复中关于调用工具的部分,确定调用的tool唯一名 和 调用tool的参数;call_plugin调用工具得到结果。
      疑问:parse_latest_plugin_call没有用正则,而使用的字符串遍历,是出于什么考虑呢?
class Agent:def __init__(self, path: str = '') -> None:passdef build_system_input(self):# 构造上文中所说的系统提示词passdef parse_latest_plugin_call(self, text):# 解析第一次大模型返回选择的工具和工具参数passdef call_plugin(self, plugin_name, plugin_args):# 调用选择的工具passdef text_completion(self, text, history=[]):# 整合两次调用pass

Agent的一次回答(解决问题)是LLM多次回复的结果,这是和先前的ChatLLM显著不同的地方。

疑问:是不是应该有action回合数控制?以实现多次调用

2.2.2 Tool

代码详见tinyAgent/tool.py,下为笔记

实现了Tools类,其实应该是写成abstract类及继承子类的形式会比较合理,但是因为这里只有一个tool,所以就混在了一起。

  • 内部方法_tools,包含了构建tool描述prompt的四大基本信息:name_for_modelname_for_humandescription_for_modelparameters
  • 调用API的功能方法:这里是Google search所以是 google_search的调用google搜索的http POST。

2.2.3 LLM

代码详见tinyAgent/LLM.py,下为笔记

abstract类+继承子类的形式,就是LLM的调用封装(因为这里是开源模型调用),两个核心功能

  • 加载模型
  • 推理

如果改调用API的话,可以参考TinyRAG的实现。

2.3 运行案例

2.3.1 代码修改

用Colab跑的,开源模型调用的是internlm/internlm2-chat-1_8b,把所有中文描述都改成了英文。

internlm/internlm2-chat-1_8b会编造工具,所以修改了system_prompt,要求它不能使用其他工具。

完整的prompt:

Answer the following questions as best you can. You have access to the following tools:google_search: Call this tool to interact with the Google Search API. What is the Google Search API useful for? Google Search is a general search engine that can be used to access the internet, consult encyclopedias, learn about current news, and more. Parameters: [{'name': 'search_query', 'description': 'Search for a keyword or phrase', 'required': True, 'schema': {'type': 'string'}}] Format the arguments as a JSON object.Do not use other tools!Use the following format:Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [google_search]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can be repeated zero or more times)
Thought: I now know the final answer
Final Answer: the final answer to the original input questionBegin!

修改了Agent类的两个函数,使其:

  • 在调用其他工具时返回Wrong input的提示、
  • 多次调用LLM,直到获得Final Answer或者达到调用上限(设为5)
class Agent:...def call_plugin(self, plugin_name, plugin_args):plugin_args = json5.loads(plugin_args)if plugin_name == 'google_search':return '\nObservation:' + self.tool.google_search(**plugin_args)else:return '\nWrong input!'def text_completion(self, text, history=[]):response = "\nQuestion:" + textfor i in range(5):response, history = self.model.chat(response, history, self.system_prompt)if response.rfind('\nFinal Answer:') > 0:breakplugin_name, plugin_args, response = self.parse_latest_plugin_call(response)if plugin_name:response += self.call_plugin(plugin_name, plugin_args)print(response)return response, history

2.3.2 运行结果

运行示例如下,可以正确解决问题

  • 周杰伦哪年生
response, _ = agent.text_completion(text='Which year was Jay Chou born?', history=_)
print(response)
Thought: To answer this question, I need to search for information about Jay Chou's birth year. I will use the Google Search API to find relevant search results.
Action: google_search
Action Input: {"search_query": "Jay Chou birth year"}
Observation:Overview · Born. January 18, 1979 · New Taipei, Taiwan · Birth name. Chieh-Lun Chou · Nicknames. President Chou; Director Chou · Height. 5′ 8″ (1.73 m) ...
Thought: Jay Chou was born on January 18, 1979. He is a Taiwanese singer, songwriter, and actor. He is known for his contributions to the Taiwanese music industry and has released numerous hit songs throughout his career. Chou has also acted in Taiwanese television dramas and films. He is considered one of the most successful and influential Taiwanese artists of all time.
Final Answer: Jay Chou was born on January 18, 1979. He is a Taiwanese singer, songwriter, and actor. He is known for his contributions to the Taiwanese music industry and has released numerous hit songs throughout his career. Chou has also acted in Taiwanese television dramas and films. He is considered one of the most successful and influential Taiwanese artists of all time.
  • 第一张专辑什么时候发的
response, _ = agent.text_completion(text='What was his first album?', history=_)
print(response)
Thought: To answer this question, I need to search for information about Jay Chou's first album. I will use the Google Search API to find relevant search results.
Action: google_search
Action Input: {"search_query": "Jay Chou first album"}
Observation:Jay is the debut studio album by Taiwanese singer Jay Chou. It was released on November 7, 2000, by BMG Taiwan. It was entirely produced and composed by ...
Thought: Jay Chou's first album is titled \"Jay\" and was released on November 7, 2000. It was entirely produced and composed by Jay Chou himself. The album features a mix of pop, rock, and electronic music and includes popular tracks such as \"Jay\" and \"Jay, Jay, Jay\".
Final Answer: Jay Chou's first album is titled \"Jay\" and was released on November 7, 2000. It was entirely produced and composed by Jay Chou himself. The album features a mix of pop, rock, and electronic music and includes popular tracks such as \"Jay\" and \"Jay, Jay, Jay\".

参考阅读

  1. TinyAgent

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/331628.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】Linux的安装

文章目录 一、Linux环境的安装虚拟机 镜像文件云服务器(可能需要花钱) 未完待续 一、Linux环境的安装 我们往后的学习用的Linux版本为——CentOs 7 ,使用 Ubuntu 也可以 。这里提供几个安装方法: 电脑安装双系统(不…

关于burp的intruder返回包空白问题

记录一下被自己蠢笑的问题 burp返回包为空怎么办,在查询无果后经过多次试验,确实没有效果 看那三个点还以为加载呢,攻击完了怎么一个显示没有 于是…… 鼠标到三个点,往下一拉 哈哈哈哈哈哈哈,真是被自己给蠢到了

基于地理坐标的高阶几何编辑工具算法(2)——相交面裁剪

文章目录 工具步骤应用场景算法输入算法输出算法示意图算法原理后处理 工具步骤 选中一个需要裁剪的面,点击“相交面裁剪”工具,多选裁剪模板面,空格执行。 应用场景 常用于基于遥感影像的建筑物几何面编辑。 算法输入 一个待裁剪的面&a…

Mysql 备份恢复 mysqldump与xtrabackup备份

1.1 备份的原因 备份是数据安全的最后一道防线,对于任何数据丢失的场景,备份虽然不一定能恢复百分之百的数据 (取决于备份周期),但至少能将损失降到最低。衡量备份恢复有两个重要的指标:恢复点目标(RPO) 和恢复时间目标(RTO)&…

vue+elemntui 加减表单框功能样式

<el-form ref"form" :model"form" :rules"rules" label-width"80px"><el-form-item label"配置时间" prop"currentAllocationDate"><div v-for"(item,key) in timeList"><el-date…

实验一:通过路由器实现内外网互联

通过路由器实现内外网互联 一、实验拓扑 相关配置详见下图&#xff0c;内网区域为AR2以内设备&#xff0c;外网区域以AR1和PC1代替进行实验测试。 二、实验要求 通过路由器实现内外网互联&#xff1a; 1.各内网PC可自动获取ip地址&#xff1b; 2.各内网PC可ping通外网PC&…

认知架构 cognitive architecture

Assistants API&#xff1a;以开发人员为中心。 有状态的API&#xff1a;允许存储以前的消息、上传文件、访问内置工具&#xff08;代码解释器&#xff09;、通过函数调用控制其他工具。 认知架构应用的两个组件&#xff1a;&#xff08;1&#xff09;如何提供上下文给应用 &…

【DevOps】深入了解RabbitMQ:AMQP协议基础、消息队列工作原理和应用场景

目录 一、核心功能 二、优势 三、核心概念 四、工作原理 五、交换机类型 六、消息确认 七、持久性和可靠性 八、插件和扩展 九、集群和镜像队列 十、客户端库 十一、管理界面 十二、应用场景 RabbitMQ是一个基于AMQP协议的消息队列中间件&#xff0c;提供高可用、可…

C++ | Leetcode C++题解之第112题路径总和

题目&#xff1a; 题解&#xff1a; class Solution { public:bool hasPathSum(TreeNode *root, int sum) {if (root nullptr) {return false;}if (root->left nullptr && root->right nullptr) {return sum root->val;}return hasPathSum(root->left…

el-table 划入划出方法

<template><div><el-table :data"tableData" style"width: 100%" cell-mouse-enter"handleMouseEnter" cell-mouse-leave"handleMouseLeave"><el-table-column prop"ddd" label"日期2" widt…

【TB作品】stm32单片机读取DS2401程序

DS2401是由Analog Devices公司生产的一种硅序列号芯片&#xff0c;它提供了一个绝对唯一的64位ROM识别码&#xff0c;用于确保可追溯性。以下是对DS2401器件的分析&#xff1a; 特点和优势&#xff1a; 唯一性&#xff1a;每个DS2401芯片都有一个独一无二的64位注册码&#x…

【实际项目精选源码】ehr人力资源管理系统实现案例(java,vue)

一、项目介绍 一款全源码可二开&#xff0c;可基于云部署、私有部署的企业级数字化人力资源管理系统&#xff0c;涵盖了招聘、人事、考勤、绩效、社保、酬薪六大模块&#xff0c;解决了从人事招聘到酬薪计算的全周期人力资源管理&#xff0c;符合当下大中小型企业组织架构管理运…

List Control控件绑定变量

创建基于对话框的mfc项目 添加 List Control控件 右击控件&#xff0c;选择“添加变量” 在初始化对话框代码中增加一些代码 BOOL CMFCApplication3Dlg::OnInitDialog() { //...// TODO: 在此添加额外的初始化代码DWORD dwStyle m_programLangList.GetExtendedStyle(); …

用户态下屏蔽全局消息钩子 —— ClientLoadLibrary 指针覆盖

目录 前言 一、研究 SetWindowsHookEx 的机制 二、概念验证 三、运行效果分析 四、总结与展望 参考文献 原文出处链接&#xff1a;[https://blog.csdn.net/qq_59075481/article/details/139206017] 前言 SetWindowsHookEx 函数帮助其他人员注入模块到我们的进程&#x…

PHP质量工具系列之php_CodeSniffer

PHP_CodeSniffer 是一组两个 PHP 脚本&#xff1a;主脚本 phpcs 对 PHP、JavaScript 和 CSS 文件进行标记&#xff0c;以检测是否违反定义的编码标准&#xff1b;第二个脚本 phpcbf 自动纠正违反编码标准的行为。PHP_CodeSniffer 是一个重要的开发工具&#xff0c;可以确保你的…

二叉树—先后序线索化和先后序线索遍历

有了上篇文章的基础&#xff0c;先序和后序的线索化逻辑一样。 代码如下&#xff1a; void preOrderThreadTree(TreeNode* T,TreeNode** pre) {if (T NULL) {;}else {//printf("%c ", T->val);if (T->lchild NULL) {T->ltag 1;T->lchild *pre;}if …

翻译《The Old New Thing》- What‘s the deal with the EM_SETHILITE message?

Whats the deal with the EM_SETHILITE message? - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20071025-00/?p24693 Raymond Chen 2007年10月25日 简要 文章讨论了EM_SETHILITE和EM_GETHILITE消息在文档中显示为“未实现”的原因。这些…

Python数字比大小获取大的数

目录 一、引言 二、数字比较的基本语法 三、获取较大的数 使用条件语句 使用内置函数 四、处理特殊情况 比较非数字类型 处理无穷大和NaN 五、应用实例 在游戏开发中比较分数 在数据分析中找出最大值 六、优化与性能 七、总结 一、引言 在Python编程的广阔天地中…

Redis 性能管理

一、Redis 性能管理 #查看Redis内存使用 172.168.1.11:6379> info memory 1. 内存碎片率 操作系统分配的内存值 used_memory_rss 除以 Redis 使用的内存总量值 used_memory 计算得出。内存值 used_memory_rss 表示该进程所占物理内存的大小&#xff0c;即为操作系统分配给…

【qt】纯代码界面设计

界面设计目录 一.界面设计的三种方式1.使用界面设计器2.纯代码界面设计3.混合界面设计 二.纯代码进行界面设计1.代码界面设计的总思路2.创建项目3.设计草图4.添加组件指针5.初始化组件指针6.添加组件到窗口①水平布局②垂直布局③细节点 7.定义槽函数8.初始化信号槽9.实现槽函数…