CAMEL-Task2-Agent的構成組件

CAMEL-Task2-Agent的構成組件

本文筆記主要關于2.7章節:CAMEL框架中agents如何使用工具。

一、工具說明

為什么要額外使用工具?

  • agents本身的知識和能力有限,比如一些問題需要聯網搜索才能準確回答(而不是亂答,即“幻覺”),一些計算需要數學工具才能符合精度要求等。
  • agents本身不能和世界交互,需要依賴接口。比如:agents可以基于LLM的語言理解和生成能力對問題給予回應,但無法訪問外部數據或執行具體的操作。

此時,工具的存在相當于為agents配備與外界交互的接口。工具的本質是一個具有名稱、描述、輸入參數和輸出的函數,當agents“認為”自己需要使用工具時,只要agents能夠正確地生成調用工具名稱、參數,對應的工具就會被調用,工具的輸出會成為agents繼續回答的依據。

CAMEL提供了各種常用工具(包),也支持自定義工具。

二、工具自定義

以數學計算為例子,展示如何通過自定義工具,讓agents的回答具備需要的精度。此處需要agents原生具備調用工具的能力(即支持function call)

無使用工具

from camel.agents import ChatAgent
from camel.models import ModelFactory
from camel.types import ModelPlatformTypeimport os
from dotenv import load_dotenv
import mathload_dotenv()# 定義系統消息
sys_msg = "你是一個數學大師,擅長各種數學問題。"# 初始化agent
api_key = os.getenv('QWEN_API_KEY')model = ModelFactory.create(model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,model_type="Qwen/Qwen2.5-72B-Instruct",url='https://api-inference.modelscope.cn/v1/',api_key=api_key
)# 創建agent并添加工具
agent = ChatAgent(system_message=sys_msg,model=model,output_language='中文',tools=[]
)# 定義用戶消息
usr_msg = "2的平方根是多少?"# 發送消息給agent
response = agent.step(usr_msg)
print(response.msgs[0].content)

此時得到的輸出:

2的平方根是 \(\sqrt{2}\),約等于 1.414。

雖然沒有錯誤,但精度不夠高。此時可以借助數學計算工具達到更高的精度。

使用(自定義)工具

此處以“計算一個數的平方根”為例進行工具定義。示例代碼(tool.py)如下:

from camel.toolkits import FunctionTool
import mathdef calculate_sqrt(x: float) -> float:r"""計算一個數的平方根。Args:x (float): 需要計算平方根的數字。Returns:float: 輸入數字的平方根。"""return math.sqrt(x)# 用 FunctionTool 包裝該函數
sqrt_tool = FunctionTool(calculate_sqrt)print(sqrt_tool.get_function_name()) # 檢索函數的名稱
print(sqrt_tool.get_function_description()) # 獲取函數作用的描述

輸出:

calculate_sqrt
計算一個數的平方根。

接下來將工具sqrt_tool引入,重新完成前述數學計算任務,代碼如下:

from camel.agents import ChatAgent
from camel.models import ModelFactory
from camel.types import ModelPlatformType
from tool import sqrt_toolimport os
from dotenv import load_dotenv
import mathload_dotenv()# 定義系統消息
sys_msg = "你是一個數學大師,擅長各種數學問題。"# 初始化agent
api_key = os.getenv('QWEN_API_KEY')model = ModelFactory.create(model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,model_type="Qwen/Qwen2.5-72B-Instruct",url='https://api-inference.modelscope.cn/v1/',api_key=api_key
)# 定義系統消息
sys_msg = "你是一個數學大師,擅長各種數學問題。當你遇到數學問題的時候,你要調用工具,將工具計算的結果作為答案"# 定義用戶消息
usr_msg = "2的平方根是多少?"# 創建agent并添加工具
tool_agent = ChatAgent(tools = [sqrt_tool], # 使用自定義的sqrt_toolsystem_message=sys_msg,model=model,output_language="中文")# 重新發送消息給toolagent
response = tool_agent.step(usr_msg)
print(response.msgs[0].content)
print(response.info['tool_calls']) # 檢查工具是否真的被調用

輸出:

2的平方根是1.4142135623730951。
[ToolCallingRecord(tool_name='calculate_sqrt', args={'x': 2}, result=1.4142135623730951, tool_call_id='call_7c18733f4d324bfb98944f', images=None)]

可以看到agents給出了更精確的結果,并且工具確實被調用。

三、使用CAMEL內置工具

此處以“查詢牛津大學校齡”為問題(假設現在是2024年,牛津大學的成立年份,并計算出其當前年齡。然后再將這個年齡加上10年。使用百度搜索工具。),考察agents在CAMEL框架下能否正確使用工具(SearchToolkitMathToolkit)回答問題。

代碼如下:

from camel.toolkits import SearchToolkit,MathToolkit
from camel.types.agents import ToolCallingRecord
from camel.models import ModelFactory
from camel.types import ModelPlatformType
from camel.societies import RolePlaying
from camel.utils import print_text_animated
from colorama import Foreimport os
from dotenv import load_dotenvload_dotenv()
api_key = os.getenv('QWEN_API_KEY')#定義工具包
tools_list = [*SearchToolkit().get_tools(),*MathToolkit().get_tools()
]# 設置任務
task_prompt = ("假設現在是2024年,""牛津大學的成立年份,并計算出其當前年齡。""然后再將這個年齡加上10年。使用百度搜索工具。")# 創建模型
model = ModelFactory.create(model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,model_type="Qwen/Qwen2.5-72B-Instruct",url='https://api-inference.modelscope.cn/v1/',api_key=api_key
)# 設置角色扮演
role_play_session = RolePlaying(assistant_role_name="搜索者",user_role_name="教授",assistant_agent_kwargs=dict(model=model,tools=tools_list, # 允許agent使用SearchToolkit,MathToolkit),user_agent_kwargs=dict(model=model,),task_prompt=task_prompt,with_task_specify=False,output_language='中文'
)# 設置聊天輪次限制
chat_turn_limit=10print(Fore.GREEN+ f"AI助手系統消息:\n{role_play_session.assistant_sys_msg}\n"
)
print(Fore.BLUE + f"AI用戶系統消息:\n{role_play_session.user_sys_msg}\n"
)print(Fore.YELLOW + f"原始任務提示:\n{task_prompt}\n")
print(Fore.CYAN+ "指定的任務提示:"+ f"\n{role_play_session.specified_task_prompt}\n"
)
print(Fore.RED + f"最終任務提示:\n{role_play_session.task_prompt}\n")n = 0
input_msg = role_play_session.init_chat()
while n < chat_turn_limit:n += 1assistant_response, user_response = role_play_session.step(input_msg)if assistant_response.terminated:print(Fore.GREEN+ ("AI助手終止。原因: "f"{assistant_response.info['termination_reasons']}."))breakif user_response.terminated:print(Fore.GREEN+ ("AI用戶終止。"f"原因: {user_response.info['termination_reasons']}."))break# 打印用戶的輸出print_text_animated(Fore.BLUE + f"AI用戶:\n\n{user_response.msg.content}\n")if "CAMEL_TASK_DONE" in user_response.msg.content:break# 打印助手的輸出,包括任何函數執行信息print_text_animated(Fore.GREEN + "AI助手:")tool_calls: list[ToolCallingRecord] = assistant_response.info['tool_calls']for func_record in tool_calls:print_text_animated(f"{func_record}")print_text_animated(f"{assistant_response.msg.content}\n")input_msg = assistant_response.msg

先安裝beautifulsoup4這個python包,否則后續調用工具時,會因為缺少這個包而無法調用。

輸出記錄

AI助手系統消息
BaseMessage(role_name='搜索者', role_type=<RoleType.ASSISTANT: 'assistant'>, meta_dict={'task': '假設現在是2024年,牛津大學的成立年份,并計算出其當前年齡。然后再將這個年齡加上10年。使用百度搜索工具。', 'assistant_role': '搜索者', 'user_role': '教授'}, content='===== RULES OF ASSISTANT =====\nNever forget you are a 搜索者 and I am a 教授. Never flip roles! Never instruct me!\nWe share a common interest in collaborating to successfully complete a task.\nYou must help me to complete the task.\nHere is the task: 假設現在是2024年,牛津大學的成立年份,并計算出其當前年齡。然后再將這個年齡加上10年。使用百度搜索工具。. Never forget our task!\nI must instruct you based on your expertise and my needs to complete the task.\n\nI must give you one instruction at a time.\nYou must write a specific solution that appropriately solves the requested instruction and explain your solutions.\nYou must decline my instruction honestly if you cannot perform the instruction due to physical, moral, legal reasons or your capability and explain the reasons.\nUnless I say the task is completed, you should always start with:\n\nSolution: <YOUR_SOLUTION>\n\n<YOUR_SOLUTION> should be very specific, include detailed explanations and provide preferable detailed implementations and examples and lists for task-solving.\nAlways end <YOUR_SOLUTION> with: Next request.\nRegardless of the input language, you must output text in 中文.', video_bytes=None, image_list=None, image_detail='auto', video_detail='auto', parsed=None)
AI用戶系統消息
BaseMessage(role_name='教授', role_type=<RoleType.USER: 'user'>, meta_dict={'task': '假設現在是2024年,牛津大學的成立年份,并計算出其當前年齡。然后再將這個年齡加上10年。使用百度搜索工具。', 'assistant_role': '搜索者', 'user_role': '教授'}, content='===== RULES OF USER =====\nNever forget you are a 教授 and I am a 搜索者. Never flip roles! You will always instruct me.\nWe share a common interest in collaborating to successfully complete a task.\nI must help you to complete the task.\nHere is the task: 假設現在是2024年,牛津大學的成立年份,并計算出其當前年齡。然后再將這個年齡加上10年。使用百度搜索工具。. Never forget our task!\nYou must instruct me based on my expertise and your needs to solve the task ONLY in the following two ways:\n\n1. Instruct with a necessary input:\nInstruction: <YOUR_INSTRUCTION>\nInput: <YOUR_INPUT>\n\n2. Instruct without any input:\nInstruction: <YOUR_INSTRUCTION>\nInput: None\n\nThe "Instruction" describes a task or question. The paired "Input" provides further context or information for the requested "Instruction".\n\nYou must give me one instruction at a time.\nI must write a response that appropriately solves the requested instruction.\nI must decline your instruction honestly if I cannot perform the instruction due to physical, moral, legal reasons or my capability and explain the reasons.\nYou should instruct me not ask me questions.\nNow you must start to instruct me using the two ways described above.\nDo not add anything else other than your instruction and the optional corresponding input!\nKeep giving me instructions and necessary inputs until you think the task is completed.\nWhen the task is completed, you must only reply with a single word <CAMEL_TASK_DONE>.\nNever say <CAMEL_TASK_DONE> unless my responses have solved your task.\nRegardless of the input language, you must output text in 中文.', video_bytes=None, image_list=None, image_detail='auto', video_detail='auto', parsed=None)
任務提示
原始任務提示:
假設現在是2024年,牛津大學的成立年份,并計算出其當前年齡。然后再將這個年齡加上10年。使用百度搜索工具。指定的任務提示:
None最終任務提示:
假設現在是2024年,牛津大學的成立年份,并計算出其當前年齡。然后再將這個年齡加上10年。使用百度搜索工具。Warning: No results found. Check if Baidu HTML structure has changed.
AI用戶
Instruction: 使用百度搜索工具查找牛津大學的成立年份。
Input: None
AI助手
Tool Execution: search_baiduArgs: {'query': '牛津大學 成立年份', 'number_of_result_pages': 1}Result: {'results': []}
Tool Execution: subArgs: {'a': 2024, 'b': 1167}Result: 857
看起來直接從百度搜索結果中沒有獲取到具體的信息,但我可以根據已知的資料來回答您的問題。牛津大學的成立年份普遍認為是在1096年或者1167年,但確切的日期并不確定,因為大學是一個逐漸形成的過程而不是一個具體的事件。如果我們假設牛津大學的成立年份為1167年,那么到2024年,牛津大學的年齡將是857年。接下來,我將這個年齡再加上10年。857 + 10 = 867年。因此,如果現在是2024年,那么牛津大學在2024年的年齡是857年,而再過10年后,它的年齡將會是867年。如果您需要進一步確認牛津大學的確切成立年份,請告訴我,我可以嘗試通過其他途徑查詢。 Next request.
AI用戶
Instruction: 確認牛津大學的成立年份是否為1167年,并計算其在2024年的年齡以及再過10年的年齡。
Input: 1167
AI助手
Tool Execution: search_baiduArgs: {'query': '牛津大學 確切成立年份', 'number_of_result_pages': 1}Result: {'results': [{'result_id': 1, 'title': '...世界中最古老的大學。A哈佛大學B劍橋大學B劍橋大學C牛津大學D...', 'description': '', 'url': 'http://www.baidu.com/link?url=R4hnTfV9RxjVwHauc21YLg_AUDUwVSCLVJ2A6a7rLBeHkg2sIHQXi7D6NUMtvyLfliWl5mPj2NPg_HMkLVtjZdeWIw1jNGDYnh9L2YrL6nWt3HnADJ4UGP8oZsFTRsqWmKBPYaaYC5NumQRQYwRCmK'}]}
根據百度搜索的結果,雖然沒有直接明確指出牛津大學的具體成立年份,但根據歷史記載和學術界的共識,牛津大學的成立年份通常被認為是1167年。因此,按照1167年作為牛津大學的成立年份,我們可以計算出:
- 到2024年,牛津大學的年齡為857年(2024 - 1167 = 857)。
- 再過10年,即2034年,牛津大學的年齡將是867年(857 + 10 = 867)。所以,牛津大學在2024年的年齡是857年,而在2034年的年齡將是867年。 Next request.
AI用戶
Instruction: 確認上述計算結果是否正確,并完成任務。
Input: 857年,867年
AI助手
根據之前的計算和信息確認,牛津大學的成立年份為1167年。因此:- 2024年時,牛津大學的年齡為 \(2024 - 1167 = 857\) 年。
- 再過10年,即2034年時,牛津大學的年齡為 \(857 + 10 = 867\) 年。這些計算結果是正確的。至此,我們已經完成了任務,確認了牛津大學在2024年的年齡為857年,以及再過10年后其年齡為867年。如果您有其他任何問題或需要進一步的幫助,請隨時告知。任務已完成。 Next request.
AI用戶
CAMEL_TASK_DONE

觀察

此案例中同樣使用RolePlaying。由于使用的LLM基座不是很厲害,所以AI用戶和AI助手的對話其實會隨著每次運行的不同而改變,這里選取了一次確實調用了工具查證后再回答問題的對話記錄進行分析。

是的,有時候agents會假裝自己用了工具,但實際上工具函數的輸入參數是自己編的。

在AI用戶和AI助手的對話過程中,第一回合里面AI助手其實工具調用沒有返回有用的信息,但自己先假設了一個結果,再第二回合里再去驗證。驗證的時候,工具返回了有用的信息(可以通過response.info['tool_calls']查看工具調用的具體信息),這使得后續對話內容更具有真實性。

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

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

相關文章

數據整理自動化 - 讓AI成為你的數據助手

文章目錄數據整理自動化 - 讓AI成為你的數據助手引言&#xff1a;數據整理的時代挑戰與機遇1. 常見數據整理場景分析1.1 數據整理的多元場景圖譜1.2 數據質量問題的分類與影響1.3 傳統處理方法的局限性2. AI與傳統腳本的協同工作流2.1 智能數據整理架構設計2.2 協同工作流的最佳…

react速成

項目目錄package.json文件&#xff1a;包含核心兩個依賴&#xff08;react、react-dom&#xff09;和命令&#xff08;start、bulid&#xff09;src&#xff1a;源碼目錄&#xff0c;開始之用的到index.js和App.jsindex.js&#xff1a;是項目的入口&#xff0c;一切的運行起點/…

Maven的進階使用(上)

pom.xml文件 就像 Make 的 MakeFile、Ant 的 build.xml 一樣&#xff0c;Maven 項目的核心是 pom.xml。POM(全稱 Project Object Model&#xff0c;項目對象模型 ) 定義了項目的基本信息&#xff0c;用于描述項目如何構建&#xff0c;聲明項目依賴&#xff0c;等等。 Gredele--…

【最后203篇系列】034 使用SQLite構建簡單的任務管理

表數據同步的斷點續傳 有時候需要將一個表的數據復制到另一個表&#xff0c;循環是常用的方式。當表比較大&#xff0c;執行的時間很長&#xff0c;會有很多因素引起失敗。我希望可以比較簡單的跑數&#xff0c;所以做一個簡單的任務系統。 SQLitre是嵌入式數據庫&#xff0c;這…

SpringCloud Alibaba核心知識點

Spring Cloud Alibaba 是阿里巴巴開源的一套微服務解決方案&#xff0c;與 Spring Cloud 生態深度集成。以下是其主要組件及其功能&#xff1a;Nacos服務注冊與發現&#xff1a;支持動態服務注冊、健康監測及DNS-Based服務發現。配置中心&#xff1a;提供分布式配置管理&#x…

LeetCode 分類刷題:34. 在排序數組中查找元素的第一個和最后一個位置

題目給你一個按照非遞減順序排列的整數數組 nums&#xff0c;和一個目標值 target。請你找出給定目標值在數組中的開始位置和結束位置。如果數組中不存在目標值 target&#xff0c;返回 [-1, -1]。你必須設計并實現時間復雜度為 O(log n) 的算法解決此問題。示例 1&#xff1a;…

自建知識庫,向量數據庫 (十二)之 文章向量搜索——仙盟創夢IDE

“未來之窗” 文章向量搜索&#xff1a;多領域應用與學習指南 在數字化浪潮中&#xff0c;“未來之窗” 文章向量搜索憑借其獨特的技術優勢&#xff0c;在酒店、電商、診療及知識庫等多個領域展現出巨大的應用潛力&#xff0c;為各行業的信息處理與檢索帶來了全新的視角和高效…

深度剖析:基于反射的.NET二進制序列化器設計與實現

&#x1f50d; 深度剖析&#xff1a;基于反射的.NET二進制序列化器設計與實現本文將從底層原理到高級優化&#xff0c;全面剖析一個基于反射的.NET二進制序列化器的設計與實現&#xff0c;涵蓋類型系統處理、內存布局、遞歸算法、性能優化等核心主題。1. 設計哲學與架構總覽 1.…

如何在 Ubuntu 上安裝和配置 Samba ?

Samba 是一個開源程序&#xff0c;用于文件共享和網絡打印&#xff0c;使用 SMB 協議。現在基本上用于提供在 Windows 上可訪問的 Linux 文件共享系統。 本文介紹如何在 Ubuntu 上安裝和配置 Samba 服務器&#xff0c;以便跨文件夾共享網絡上不同的計算機。 Update Your Syst…

MATLAB實現CNN-GRU-Attention時序和空間特征結合-融合注意力機制混合神經網絡模型的風速預測

該 MATLAB 代碼實現了一個基于 CNN-GRU-Attention 時序和空間特征結合-融合注意力機制混合神經網絡模型的風速預測。以下是對代碼的簡要分析&#xff1a;一、主要功能 該代碼用于風速時間序列預測&#xff0c;使用歷史風速特征數據&#xff08;18個特征&#xff0c;75天&#x…

【升級版】從零到一訓練一個 0.6B 的 MoE 大語言模型

前文&#xff1a;從零到一訓練一個 0.6B 的 MoE 大語言模型&#xff0c;本次升級完全重新從零開始重新訓練。主要升級如下&#xff1a; 替換預訓練數據集&#xff0c;使用序列猴子通用文本數據集進行預訓練。使用更先進的訓練方法。新增思考模式控制&#xff0c;可通過添加/th…

51單片機-實現定時器模塊教程

本章概述思維導圖&#xff1a; 51單片機驅動定時器模塊 CPU時序簡介 CPU時序定義了CPU內部操作的時間節奏&#xff0c;以下從四個時序周期進行逐步解析&#xff1b; 1、振蕩周期 振蕩周期&#xff1a;CPU內部時鐘源產生的最小時間單位&#xff0c;由晶振或內部振蕩器決定&am…

7.Kotlin的日期類

以下是 Kotlin 中常用時間類&#xff08;基于 java.time 包&#xff09;的核心方法及使用示例&#xff0c;參考數組方法的表格形式&#xff0c;按類分類展示&#xff1a; 一、LocalDate&#xff08;日期&#xff1a;年/月/日&#xff09;方法簽名返回值說明示例now(): LocalDat…

【Big Data】Hive技術解析:大數據倉庫的SQL橋梁

Hive作為Apache頂級項目&#xff0c;是Hadoop生態系統中最具影響力的SQL查詢引擎&#xff0c;它解決了大數據處理與傳統SQL技能之間的鴻溝。Hive的核心價值在于將類SQL查詢語言HiveQL無縫轉換為分布式計算框架MapReduce的任務&#xff0c;使數據分析師能夠利用熟悉的SQL語法操作…

Ubuntu2204server系統安裝postgresql14并配置密碼遠程連接

前言&#xff1a; 最近因項目需要安裝postgresql14&#xff0c;系統是ubuntu2204server系統&#xff0c;安裝好后發現無法實現遠程連接&#xff0c;解決了之后在此記錄一下解決方法。 疑問&#xff1a; 什么情況下需要配置postgresql遠程連接&#xff1f; ①如果是postgresql和…

【嵌入式】【搜集】狀態機、狀態遷移圖及狀態模式材料

文章目錄狀態機狀態機狀態機定義與核心特點狀態機總結狀態遷移圖狀態遷移圖狀態遷移圖核心概念與要素狀態遷移圖常見錯誤與規避狀態遷移圖總結狀態模式狀態模式狀態模式核心概念與組成狀態模式核心價值與適用場景狀態模式優缺點分析進階優化技巧行為模式總結狀態機 狀態機 狀…

Java學習歷程14——制作一款五子棋游戲(4)

上次我們基本實現了五子棋游戲的功能&#xff0c;這次我們進行一些優化和添加一些便于用戶使用的功能。新增功能及優化一、復盤功能復盤功能就是指在下完一局棋后&#xff0c;我們可以通過復盤按鈕使本局棋的所有棋子重頭開始自動下一遍。分析得知&#xff0c;我們首先要保存以…

記錄一次el-table+sortablejs的拖拽bug

bug回顧出現bug的情況時 當編輯表格過于緊湊的時候 有些非必要編輯或需要一眼看到的數據 移動到了el-table-column typeexpand時 同事&#xff1a;怎么拖拽功能用不了了 ok開始檢查代碼 當原來是個簡單的編輯表格 不涉及展開和簡單拖拽時 不會出現問題 解決了 出現了展開行以后…

利用go sort.Sort()排序自定義切片

1 sort.Sort()簡介2 核心功能3 調用前提4 代碼示例 1 sort.Sort()簡介 Go語言中的sort.Sort函數是標準庫提供的通用排序接口 2 核心功能 核心功能支持多種類型進行快速排序 基礎類型支持?&#xff1a;內置Ints、Float64s、Strings等函數直接排序常見切片 自定義排序?&a…

Elasticsearch腦裂緊急處理與預防

在 Elasticsearch 中出現 網絡分區&#xff08;Network Partition&#xff09; 或 腦裂&#xff08;Split-Brain&#xff09; 導致兩個子集群各自選出 Master 的情況&#xff0c;是非常嚴重的問題。比如這個場景&#xff08;20個節點分裂成兩個10節點的子集群&#xff0c;各自選…