【AI Agent系列】【MetaGPT多智能體學習】6. 多智能體實戰 - 基于MetaGPT實現游戲【你說我猜】(附完整代碼)

本系列文章跟隨《MetaGPT多智能體課程》(https://github.com/datawhalechina/hugging-multi-agent),深入理解并實踐多智能體系統的開發。

本文為該課程的第四章(多智能體開發)的第四篇筆記。今天我們來完成第四章的作業:

基于 env 或 team 設計一個你的多智能體團隊,嘗試讓他們完成 你畫我猜文字版 ,要求其中含有兩個agent,其中一個agent負責接收來自用戶提供的物體描述并轉告另一個agent,另一個agent將猜測用戶給出的物體名稱,兩個agent將不斷交互直到另一個給出正確的答案

系列筆記

  • 【AI Agent系列】【MetaGPT多智能體學習】0. 環境準備 - 升級MetaGPT 0.7.2版本及遇到的坑
  • 【AI Agent系列】【MetaGPT多智能體學習】1. 再理解 AI Agent - 經典案例和熱門框架綜述
  • 【AI Agent系列】【MetaGPT多智能體學習】2. 重溫單智能體開發 - 深入源碼,理解單智能體運行框架
  • 【AI Agent系列】【MetaGPT多智能體學習】3. 開發一個簡單的多智能體系統,兼看MetaGPT多智能體運行機制
  • 【AI Agent系列】【MetaGPT多智能體學習】4. 基于MetaGPT的Team組件開發你的第一個智能體團隊
  • 【AI Agent系列】【MetaGPT多智能體學習】5. 多智能體案例拆解 - 基于MetaGPT的智能體辯論(附完整代碼)

文章目錄

  • 系列筆記
  • 0. 需求分析
  • 1. 寫代碼 - 初版
    • 1.1 智能體1 - Describer實現
      • 1.1.1 Action定義 - DescribeWord
      • 1.1.2 Role定義 - Describer
    • 1.2 智能體2 - Guesser實現
      • 1.2.1 Action定義 - GuessWord
      • 1.2.2 Role定義 - Gusser
    • 1.3 定義Team,運行及結果
  • 2. 修改代碼 - 效果優化
    • 2.1 存在的問題及分析
    • 2.2 Prompt優化
    • 2.3 回答正確后如何立刻停止游戲
    • 2.4 如何輸出“游戲失敗”的結果
  • 3. 完整代碼
  • 4. 拓展 - 與人交互,人來猜詞
  • 5. 總結

0. 需求分析

從上面的需求描述來看,你說我猜 游戲需要兩個智能體:

  • 智能體1:Describer,用來接收用戶提供的詞語,并給出描述
  • 智能體2:Guesser,用來接收智能體1的描述,猜詞

1. 寫代碼 - 初版

1.1 智能體1 - Describer實現

智能體1 Describer的任務是根據用戶提供的詞語,用自己的話描述出來。

1.1.1 Action定義 - DescribeWord

重點是 Prompt,這里我設置的Prompt接收兩個參數,第一個參數word為用戶輸入的詞語,也就是答案。第二個參數是Describer智能體的描述歷史,因為在實際游戲過程中,描述是不會與前面的描述重復的。另外還設置了每次描述最多20個字,用來限制token的消耗。

class DescribeWord(Action):"""Action: Describe a word in your own language"""PROMPT_TMPL: str = """## 任務你現在在玩一個你畫我猜的游戲,你需要用你自己的語言來描述"{word}"## 描述歷史之前你的描述歷史:{context}## 你必須遵守的限制1. 描述長度不超過20個字2. 描述中不能出現"{word}"中的字3. 描述不能與描述歷史中的任何一條描述相同"""name: str = "DescribeWord"async def run(self, context: str, word: str):prompt = self.PROMPT_TMPL.format(context=context, word=word)logger.info(prompt)rsp = await self._aask(prompt)print(rsp)return rsp

1.1.2 Role定義 - Describer

(1)設置其 Action 為 DescribeWord
(2)設置其關注的消息來源為 UserRequirement 和 GuessWord
(3)重點重寫了 _act 函數。

因為前面的Prompt中需要歷史的描述信息,而描述是其自身發出的,因此歷史描述信息的獲取為:

if msg.sent_from == self.name:context = "\n".join(f"{msg.content}") # 自己的描述歷史

另外,也在這里加了判斷是否猜對了詞語的邏輯:

elif msg.sent_from == "Gusser" and msg.content.find(self.word) != -1:print("回答正確!")return Message()

當回答對了之后,直接返回。

完整代碼如下:

class Describer(Role):name: str = "Describer"profile: str = "Describer"word: str = ""def __init__(self, **data: Any):super().__init__(**data)self.set_actions([DescribeWord])self._watch([UserRequirement, GuessWord])async def _act(self) -> Message:logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")todo = self.rc.todo  # An instance of DescribeWordmemories = self.get_memories() # 獲取全部的記憶context = ""for msg in memories:if msg.sent_from == self.name:context = "\n".join(f"{msg.content}") # 自己的描述歷史elif msg.sent_from == "Gusser" and msg.content.find(self.word) != -1:print("回答正確!")return Message()print(context)rsp = await todo.run(context=context, word=self.word)msg = Message(content=rsp,role=self.profile,cause_by=type(todo),sent_from=self.name,)self.rc.memory.add(msg)return msg

1.2 智能體2 - Guesser實現

智能體2 - Guesser,用來接收智能體1的描述,猜詞。

1.2.1 Action定義 - GuessWord

與 DescribeWord Action的Prompt類似,猜詞的Prompt接收一個context來表示之前它的猜詞歷史,避免它老重復猜同一個詞,陷入死循環。然后一個description來接收Describer的描述語句。

class GuessWord(Action):"""Action: Guess a word from the description"""PROMPT_TMPL: str = """## 背景你現在在玩一個你畫我猜的游戲,你的任務是根據給定的描述,猜一個詞語。## 猜測歷史之前你的猜測歷史:{context}## 輪到你了現在輪到你了,你需要根據描述{description}猜測一個詞語,并遵循以下限制:### 限制1. 猜測詞語不超過5個字2. 猜測詞語不能與猜測歷史重復3. 只輸出猜測的詞語,NO other texts"""name: str = "GuessWord"async def run(self, context: str, description: str):prompt = self.PROMPT_TMPL.format(context=context, description=description)logger.info(prompt)rsp = await self._aask(prompt)return rsp

1.2.2 Role定義 - Gusser

(1)設置其 Action 為 GuessWord
(2)設置其關注的消息來源為 DescribeWord
(3)重點重寫了 _act 函數。

因為前面的Prompt中需要歷史的猜詞信息,而猜詞是其自身發出的,因此猜詞歷史信息的獲取為:

if msg.sent_from == self.name:context = "\n".join(f"{msg.content}")

Describer的描述信息獲取為:

elif msg.sent_from == "Describer":description = "\n".join(f"{msg.content}")

完整代碼如下:


class Gusser(Role):name: str = "Gusser"profile: str = "Gusser"def __init__(self, **data: Any):super().__init__(**data)self.set_actions([GuessWord])self._watch([DescribeWord])async def _act(self) -> Message:logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")todo = self.rc.todo  # An instance of DescribeWordmemories = self.get_memories() # 獲取全部的記憶context= ""description = ""for msg in memories:if msg.sent_from == self.name:context = "\n".join(f"{msg.content}")elif msg.sent_from == "Describer":description = "\n".join(f"{msg.content}")print(context)rsp = await todo.run(context=context, description=description)msg = Message(content=rsp,role=self.profile,cause_by=type(todo),sent_from=self.name,)self.rc.memory.add(msg)print(rsp)return msg

1.3 定義Team,運行及結果

async def start_game(idea: str, investment: float = 3.0, n_round: int = 10):team = Team()team.hire([Describer(word=idea),Gusser(), ])team.invest(investment)team.run_project(idea)await team.run(n_round=n_round)def main(idea: str, investment: float = 3.0, n_round: int = 10):if platform.system() == "Windows":asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())asyncio.run(start_game(idea, investment, n_round))if __name__ == "__main__":fire.Fire(main("籃球"))

運行結果如下:

智能體產生描述:
在這里插入圖片描述

猜詞,檢測結果:

在這里插入圖片描述
可以看到,運行成功了,也能進行簡單的交互。但是還是能看出不少問題的。

下面是進一步優化的過程。

2. 修改代碼 - 效果優化

2.1 存在的問題及分析

(1)猜對答案后,它后面還是在循環運行,直到運行完剛開始設置的運行輪數:n_round: int = 10。如上面的運行結果,后面一直在輸出“回答正確”。

(2)看下圖的運行結果,回答了英文,導致一直認為不是正確答案。并且一直在重復這個詞,所以,Prompt還需要優化:

在這里插入圖片描述

(3)10輪后結束運行,如果這時候沒有猜對答案,沒有輸出“你失敗了”類似的文字。

總結下主要問題:

  • 回答正確后如何立刻停止游戲
  • Prompt需要優化
  • 如何輸出“游戲失敗”的結果

2.2 Prompt優化

Prompt優化的原則是,有啥問題堵啥問題…

(1)它既然輸出了英文詞語,那就限制它不讓它輸出英文單詞,只輸出中文。
(2)它重復輸出了之前的猜詞,說明猜詞歷史的限制沒有生效,改變話術各種試(沒有好的方法,只有各種試)。

修改之后的 Prompt:

class DescribeWord(Action):"""Action: Describe a word in your own language"""PROMPT_TMPL: str = """## 任務你現在在玩一個你畫我猜的游戲,你需要用你自己的語言來描述"{word}"## 描述歷史之前你的描述歷史:{context}## 你必須遵守的限制1. 描述長度不超過20個字2. 描述中不能出現與"{word}"中的任何一個字相同的字,否則會有嚴重的懲罰。例如:描述的詞為"雨傘",那么生成的描述中不能出現"雨","傘","雨傘"3. 描述不能與描述歷史中的任何一條描述相同, 例如:描述歷史中已經出現過"一種工具",那么生成的描述就不能再是"一種工具""""
class GuessWord(Action):"""Action: Guess a word from the description"""PROMPT_TMPL: str = """## 任務你現在在玩一個你畫我猜的游戲,你需要根據描述"{description}"猜測出一個詞語## 猜測歷史之前你的猜測歷史:{context}### 你必須遵守的限制1. 猜測詞語不超過5個字,詞語必須是中文2. 猜測詞語不能與猜測歷史重復3. 只輸出猜測的詞語,NO other texts"""

優化之后的運行效果,雖然還是有點小問題(描述中出現了重復和出現了答案中的字),但最終效果還行吧… :

在這里插入圖片描述

2.3 回答正確后如何立刻停止游戲

await team.run(n_round=n_round) 之后,不運行完 n_round 是不會返回的,而 Team 組件目前也沒有接口來設置停止運行。因此想要立刻停止游戲,用Team組件幾乎是不可能的(有方法的歡迎指教)。

所以我想了另一種辦法:既然無法立刻停止游戲,那就停止兩個智能體的行動,讓他們一直等待n_round完就行了,就像等待游戲時間結束。

代碼修改也很簡單:

elif msg.sent_from == "Gusser" and msg.content.find(self.word) != -1:print("回答正確!")return ""

只要在回答正確后,直接return一個空字符串就行。為什么這樣就可以?看源碼:

def publish_message(self, msg):"""If the role belongs to env, then the role's messages will be broadcast to env"""if not msg:return

在運行完動作_act后,往環境中放結果消息,如果為空,就不忘環境中放消息了。這樣Guesser也就接收不到 Describer 的消息,也就不動作了。剩下的 n_round 就是在那空轉了。

看下運行效果:

在這里插入圖片描述
可以看到,只輸出了一次“回答正確”,之后就沒有其余打印了,直到程序結束。

2.4 如何輸出“游戲失敗”的結果

如果 n_round 運行完之后,還沒有猜對結果,就要宣告游戲失敗了。怎么獲取這個結果呢?

程序運行結束,只能是在這里返回:await team.run(n_round=n_round)

我們將它的返回值打出來看下是什么:

result = await team.run(n_round=n_round)
print(result)

打印結果如下:

在這里插入圖片描述
可以看到它的返回結果就是所有的對話歷史。那么判斷游戲是否失敗就好說了,有很多種方法,例如直接比較用戶輸入的詞語是否與這個結果中的最后一行相同:

result = result.split(':')[-1].strip(' ')
if (result.find(idea) != -1):print("恭喜你,猜對了!")
else:print("很遺憾,你猜錯了!")

運行效果:

在這里插入圖片描述

3. 完整代碼


import asyncio
from typing import Any
import platformimport firefrom metagpt.actions import Action, UserRequirement
from metagpt.logs import logger
from metagpt.roles import Role
from metagpt.schema import Message
from metagpt.team import Teamclass DescribeWord(Action):"""Action: Describe a word in your own language"""PROMPT_TMPL: str = """## 任務你現在在玩一個你畫我猜的游戲,你需要用你自己的語言來描述"{word}"## 描述歷史之前你的描述歷史:{context}## 你必須遵守的限制1. 描述長度不超過20個字2. 描述中不能出現與"{word}"中的任何一個字相同的字,否則會有嚴重的懲罰。例如:描述的詞為"雨傘",那么生成的描述中不能出現"雨","傘","雨傘"3. 描述不能與描述歷史中的任何一條描述相同, 例如:描述歷史中已經出現過"一種工具",那么生成的描述就不能再是"一種工具""""name: str = "DescribeWord"async def run(self, context: str, word: str):prompt = self.PROMPT_TMPL.format(context=context, word=word)logger.info(prompt)rsp = await self._aask(prompt)# print(rsp)return rspclass GuessWord(Action):"""Action: Guess a word from the description"""PROMPT_TMPL: str = """## 任務你現在在玩一個你畫我猜的游戲,你需要根據描述"{description}"猜測出一個詞語## 猜測歷史之前你的猜測歷史:{context}### 你必須遵守的限制1. 猜測詞語不超過5個字,詞語必須是中文2. 猜測詞語不能與猜測歷史重復3. 只輸出猜測的詞語,NO other texts"""name: str = "GuessWord"async def run(self, context: str, description: str):prompt = self.PROMPT_TMPL.format(context=context, description=description)logger.info(prompt)rsp = await self._aask(prompt)return rspclass Describer(Role):name: str = "Describer"profile: str = "Describer"word: str = ""def __init__(self, **data: Any):super().__init__(**data)self.set_actions([DescribeWord])self._watch([UserRequirement, GuessWord])async def _act(self) -> Message:logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")todo = self.rc.todo  # An instance of DescribeWordmemories = self.get_memories() # 獲取全部的記憶context = ""for msg in memories:if msg.sent_from == self.name:context += f"{msg.content}\n" # 自己的描述歷史elif msg.sent_from == "Gusser" and msg.content.find(self.word) != -1:print("回答正確!")return ""# print(context)rsp = await todo.run(context=context, word=self.word)msg = Message(content=rsp,role=self.profile,cause_by=type(todo),sent_from=self.name,)self.rc.memory.add(msg)return msgclass Gusser(Role):name: str = "Gusser"profile: str = "Gusser"def __init__(self, **data: Any):super().__init__(**data)self.set_actions([GuessWord])self._watch([DescribeWord])async def _act(self) -> Message:logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")todo = self.rc.todo  # An instance of DescribeWordmemories = self.get_memories() # 獲取全部的記憶context= ""description = ""for msg in memories:if msg.sent_from == self.name:context += f"{msg.content}\n"elif msg.sent_from == "Describer":description += f"{msg.content}\n"print(context)rsp = await todo.run(context=context, description=description)msg = Message(content=rsp,role=self.profile,cause_by=type(todo),sent_from=self.name,)self.rc.memory.add(msg)# print(rsp)return msgasync def start_game(idea: str, investment: float = 3.0, n_round: int = 10):team = Team()team.hire([Describer(word=idea),Gusser(), ])team.invest(investment)team.run_project(idea)result = await team.run(n_round=n_round)result = result.split(':')[-1].strip(' ')if (result.find(idea) != -1):print("恭喜你,猜對了!")else:print("很遺憾,你猜錯了!")def main(idea: str, investment: float = 3.0, n_round: int = 3):if platform.system() == "Windows":asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())asyncio.run(start_game(idea, investment, n_round))if __name__ == "__main__":fire.Fire(main("打籃球運行"))

4. 拓展 - 與人交互,人來猜詞

可以做下拓展,將猜詞的Role換成你自己,你自己來猜詞,與智能體進行交互。這實現起來比較簡單。

代表人的智能體,只需要在實例化智能體時,將 Role 的 is_human 屬性置為 true 即可:

team.hire([Describer(word=idea),Gusser(is_human=True),  # is_human=True 代表這個角色是人類,需要你的輸入])

運行效果:

在這里插入圖片描述
還可以引入另一個智能體來自動出詞語。大家可以思考下應該怎么實現。

5. 總結

本文我們利用MetaGPT的Team組件實現了一個“你說我猜”的游戲。因為游戲比較簡單,所以整體邏輯也比較簡單。重點在于Prompt優化比較費勁,還有就是要注意何時結束游戲等細節。最后,也向大家展示了一下如何讓人參與到游戲中。


站內文章一覽

在這里插入圖片描述

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

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

相關文章

java垃圾回收

垃圾回收 一個對象如果不再使用,需要手動釋放,否則就會出現內存泄漏。我們稱這種釋放對象的過程為垃圾回收,而需要程序員編寫代碼進行回收的方式為手動回收。 內存泄漏指的是不再使用的對象在系統中未被回收,內存泄漏的積累可能…

美國經濟政策轉向標記之一

美聯儲沃勒在紐約舉行的 2024 年美國貨幣政策論壇上表示,他希望看到美聯儲投資組合出現兩項關鍵進展: 首先,我希望看到美聯儲的機構MBS持有量降至零。其次,我希望美聯儲轉向增加短期美國國債在持有資產中的占比。在金融危機之前&a…

【ArcGIS Pro二次開發】(83):ProWindow和WPF的一些技巧

在ArcGIS Pro二次開發中,SDK提供了一種工具界面【ArcGIS Pro ProWindow】。 關于ProWindow的用法,之前寫過一篇基礎的教程: 【ArcGIS Pro二次開發】(13):ProWindow的用法_arcgispro二次開發教程-CSDN博客 主要是對幾個常用控件…

異步編程實戰之webflux

一, 快速搭建webflux項目 1, 引入相關依賴 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.5</version><relativePath/> <!-- lookup parent fr…

【嵌入式實踐】【芝麻】【設計篇-2】從0到1給電動車添加指紋鎖:項目可行性分析

0. 前言 該項目是基于stm32F103和指紋模塊做了一個通過指紋鎖控制電動車的小工具。支持添加指紋、刪除指紋&#xff0c;電動車進入P檔等待時計時&#xff0c;計時超過5min則自動鎖車&#xff0c;計時過程中按剎車可中斷P檔狀態&#xff0c;同時中斷鎖車計時。改項目我稱之為“芝…

EMR StarRocks實戰——猿輔導的OLAP演進之路

目錄 一、數據需求產生 二、OLAP選型 2.1 需求 2.2 調研 2.3 對比 三、StarRocks的優勢 四、業務場景和技術方案 4.1 整體的數據架構 4.2 BI自助/報表/多維分析 4.3 實時事件分析 4.5 直播教室引擎性能監控 4.4 B端業務后臺—斑馬 4.5 學校端數據產品—飛象星球 4…

Ajax(黑馬學習筆記)

Ajax介紹 Ajax概述 我們前端頁面中的數據&#xff0c;如下圖所示的表格中的學生信息&#xff0c;應該來自于后臺&#xff0c;那么我們的后臺和前端是互不影響的2個程序&#xff0c;那么我們前端應該如何從后臺獲取數據呢&#xff1f;因為是2個程序&#xff0c;所以必須涉及到…

【ACM】—藍橋杯大一暑期集訓Day3

&#x1f680;歡迎來到本文&#x1f680; &#x1f349;個人簡介&#xff1a;陳童學哦&#xff0c;目前學習C/C、算法、Python、Java等方向&#xff0c;一個正在慢慢前行的普通人。 &#x1f3c0;系列專欄&#xff1a;陳童學的日記 &#x1f4a1;其他專欄&#xff1a;CSTL&…

langchain學習筆記(九)

RunnableBranch: Dynamically route logic based on input | &#x1f99c;?&#x1f517; Langchain 基于輸入的動態路由邏輯&#xff0c;通過上一步的輸出選擇下一步操作&#xff0c;允許創建非確定性鏈。路由保證路由間的結構和連貫。 有以下兩種方法執行路由 1、通過Ru…

Unity引擎中光源都有哪幾種,都有什么作用

本文由 簡悅 SimpRead 轉碼&#xff0c; 原文地址 mp.weixin.qq.com Unity 引擎為了實現游戲場景的明暗和光影效果&#xff0c;提供了四種類型的光源&#xff0c;分別是方向光&#xff08;Directional Lights&#xff09;、點光源&#xff08;Point Lights&#xff09;、聚光燈…

Vue開發實例(一)Vue環境搭建第一個項目

Vue環境搭建&第一個項目 一、環境搭建二、安裝Vue腳手架三、創建Vue項目 一、環境搭建 下載方式從官網下載&#xff1a;http://nodejs.cn/download/ 建議下載v12.16.0版本以上的&#xff0c;因為版本低無法創建Vue的腳手架 檢驗是否安裝成功 配置環境變量 新增NODE_HOME&…

win11系統中nginx簡單的代理配置

一.背景 為了公司安排的師帶徒任務。 操作系統版本&#xff1a;win11家庭版 nginx版本&#xff1a;1.24.0 二.配置代理 之前文章已經說明了nginx簡單的安裝&#xff0c;要看閱讀這個文章哈。web服務器nginx下載及在win11的安裝-CSDN博客 1.配置需求識別 前端服務nginx(80…

【探索AI】十七 深度學習之第3周:卷積神經網絡(CNN)(一)-CNN的基本原理與結構

第3周&#xff1a;卷積神經網絡&#xff08;CNN&#xff09; CNN的基本原理與結構 常見的卷積層、池化層與全連接層 LeNet、AlexNet等經典CNN模型 實踐&#xff1a;使用CNN進行圖像分類任務 CNN的基本原理與結構 引言與背景介紹 卷積神經網絡&#xff08;CNN&#xff09;是…

雙周回顧#007 - 前端與后端

前端的問題不是難&#xff0c;而是它面對最終用戶。只要用戶的喜好和口味發生變化&#xff0c;前端就必須跟上。 這導致前端不得不快速變化&#xff0c;因為用戶的口味正在越來越快地改變。 后端不需要面對最終用戶&#xff0c;需要解決的都是一些經典的計算機科學問題&#…

什么是Vue指令?請列舉一些常見的Vue指令以及它們的用法

Vue.js 是一款流行的前端框架&#xff0c;它的指令&#xff08;Directives&#xff09;是 Vue.js 提供的一種特殊屬性&#xff0c;用于在模板中對 DOM 元素進行直接操作。指令通常是以 v- 開頭的特殊屬性&#xff0c;用于響應式地將數據綁定到 DOM 元素上。 在 Vue 中&#xf…

C語言初階—函數(函數的聲明和定義,函數遞歸)

函數聲明&#xff1a; 1.告訴編譯器有一個函數叫什么&#xff0c;參數是什么&#xff0c;返回類型是什么&#xff0c;但是具體是不是存在&#xff0c;函數聲明決定不了。 2.函數的聲明一般出現在函數使用之前&#xff0c;要滿足先聲明后使用。 3.函數的聲明一般要放在頭文件中。…

Launch學習

參考博客&#xff1a; (1) 史上最全的launch的解析來啦&#xff0c;木有之一歐 1 ROS工作空間簡介 2 元功能包 src目錄下可以包含多個功能包&#xff0c;假設需要使用機器人導航模塊&#xff0c;但是這個模塊中包含著地圖、定位、路徑規劃等不同的功能包&#xff0c;它們的邏…

agent內存馬

搭建一個簡單的Servlet項目 ServletDemo package com.naihe;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;…

【探索AI】十一 深度學習之機器學習基礎

鑒于之前文章中提到的深度學習計劃&#xff0c;后續的文章會根據之前的接著繼續學習&#xff0c;python基礎略過&#xff0c;想學的同學請自學&#xff1a; python入門 python進階 機器學習基礎 機器學習是人工智能領域的一個子集&#xff0c;它專注于從數據中自動學習并提升…

vue2+若依框架plus交互 路由介紹

本周及寒假 參加了校企合作的工程過程管理&#xff0c;和學長學姐一起寫項目&#xff0c;之前學了vue也沒有應用&#xff0c;然后對框架很多組件的用法不太了解&#xff0c;前期耽誤了一些時間。 框架模塊 首先是框架模塊的介紹 api存了一些系統管理及發送請求的方法 例如p…