構建LangChain應用程序的示例代碼:56、如何實現一個多智能體模擬,其中沒有固定的發言順序。智能體自行決定誰來發言,通過競價機制實現

多智能體分散式發言人選擇

示例展示了如何實現一個多智能體模擬,其中沒有固定的發言順序。智能體自行決定誰來發言,通過競價機制實現。

我們將在下面的示例中展示一場虛構的總統辯論來演示這一過程。

導入LangChain相關模塊

from typing import Callable, Listimport tenacity
from langchain.output_parsers import RegexParser
from langchain.prompts import PromptTemplate
from langchain.schema import (HumanMessage,SystemMessage,
)
from langchain_openai import ChatOpenAI# 導入所需的模塊和類
# typing: 用于類型注解
# tenacity: 用于實現重試機制
# langchain相關模塊: 用于構建對話系統

DialogueAgentDialogueSimulator

我們將使用在 Multi-Player Dungeons & Dragons 中定義的相同 DialogueAgentDialogueSimulator 類。

class DialogueAgent:def __init__(self,name: str,system_message: SystemMessage,model: ChatOpenAI,) -> None:self.name = nameself.system_message = system_messageself.model = modelself.prefix = f"{self.name}: "self.reset()def reset(self):self.message_history = ["Here is the conversation so far."]def send(self) -> str:"""將聊天模型應用于消息歷史記錄并返回消息字符串"""message = self.model.invoke([self.system_message,HumanMessage(content="\n".join(self.message_history + [self.prefix])),])return message.contentdef receive(self, name: str, message: str) -> None:"""將{name}說的{message}連接到消息歷史記錄中"""self.message_history.append(f"{name}: {message}")class DialogueSimulator:def __init__(self,agents: List[DialogueAgent],selection_function: Callable[[int, List[DialogueAgent]], int],) -> None:self.agents = agentsself._step = 0self.select_next_speaker = selection_functiondef reset(self):for agent in self.agents:agent.reset()def inject(self, name: str, message: str):"""用{name}的{message}開始對話"""for agent in self.agents:agent.receive(name, message)# 增加時間步self._step += 1def step(self) -> tuple[str, str]:# 1. 選擇下一個發言者speaker_idx = self.select_next_speaker(self._step, self.agents)speaker = self.agents[speaker_idx]# 2. 下一個發言者發送消息message = speaker.send()# 3. 所有人接收消息for receiver in self.agents:receiver.receive(speaker.name, message)# 4. 增加時間步self._step += 1return speaker.name, message# DialogueAgent類: 表示對話中的一個智能體
# DialogueSimulator類: 用于模擬多個智能體之間的對話

BiddingDialogueAgent

我們定義了 DialogueAgent 的一個子類,它有一個 bid() 方法,根據消息歷史和最近的消息產生一個出價。

class BiddingDialogueAgent(DialogueAgent):def __init__(self,name,system_message: SystemMessage,bidding_template: PromptTemplate,model: ChatOpenAI,) -> None:super().__init__(name, system_message, model)self.bidding_template = bidding_templatedef bid(self) -> str:"""要求聊天模型輸出一個發言出價"""prompt = PromptTemplate(input_variables=["message_history", "recent_message"],template=self.bidding_template,).format(message_history="\n".join(self.message_history),recent_message=self.message_history[-1],)bid_string = self.model.invoke([SystemMessage(content=prompt)]).contentreturn bid_string# BiddingDialogueAgent類: DialogueAgent的子類,增加了競價功能

定義參與者和辯論主題

character_names = ["Donald Trump", "Kanye West", "Elizabeth Warren"]
topic = "transcontinental high speed rail"
word_limit = 50# 定義參與辯論的人物和辯論主題
# character_names: 參與者姓名列表
# topic: 辯論主題
# word_limit: 回答字數限制

生成系統消息

game_description = f"""Here is the topic for the presidential debate: {topic}.
The presidential candidates are: {', '.join(character_names)}."""player_descriptor_system_message = SystemMessage(content="You can add detail to the description of each presidential candidate."
)def generate_character_description(character_name):character_specifier_prompt = [player_descriptor_system_message,HumanMessage(content=f"""{game_description}Please reply with a creative description of the presidential candidate, {character_name}, in {word_limit} words or less, that emphasizes their personalities. Speak directly to {character_name}.Do not add anything else."""),]character_description = ChatOpenAI(temperature=1.0)(character_specifier_prompt).contentreturn character_descriptiondef generate_character_header(character_name, character_description):return f"""{game_description}
Your name is {character_name}.
You are a presidential candidate.
Your description is as follows: {character_description}
You are debating the topic: {topic}.
Your goal is to be as creative as possible and make the voters think you are the best candidate.
"""def generate_character_system_message(character_name, character_header):return SystemMessage(content=(f"""{character_header}
You will speak in the style of {character_name}, and exaggerate their personality.
You will come up with creative ideas related to {topic}.
Do not say the same things over and over again.
Speak in the first person from the perspective of {character_name}
For describing your own body movements, wrap your description in '*'.
Do not change roles!
Do not speak from the perspective of anyone else.
Speak only from the perspective of {character_name}.
Stop speaking the moment you finish speaking from your perspective.
Never forget to keep your response to {word_limit} words!
Do not add anything else."""))character_descriptions = [generate_character_description(character_name) for character_name in character_names
]
character_headers = [generate_character_header(character_name, character_description)for character_name, character_description in zip(character_names, character_descriptions)
]
character_system_messages = [generate_character_system_message(character_name, character_headers)for character_name, character_headers in zip(character_names, character_headers)
]# 生成系統消息和角色描述
# generate_character_description: 生成角色描述
# generate_character_header: 生成角色頭部信息
# generate_character_system_message: 生成角色系統消息
for (character_name,character_description,character_header,character_system_message,
) in zip(character_names,character_descriptions,character_headers,character_system_messages,
):print(f"\n\n{character_name} Description:")print(f"\n{character_description}")print(f"\n{character_header}")print(f"\n{character_system_message.content}")# 打印生成的角色描述、頭部信息和系統消息

出價的輸出解析器

我們要求智能體輸出一個發言出價。但由于智能體是輸出字符串的LLM,我們需要:

  1. 定義他們將產生輸出的格式
  2. 解析他們的輸出

我們可以繼承 RegexParser 來實現我們自己的自定義出價輸出解析器。

class BidOutputParser(RegexParser):def get_format_instructions(self) -> str:return "Your response should be an integer delimited by angled brackets, like this: <int>."bid_parser = BidOutputParser(regex=r"<(\d+)>", output_keys=["bid"], default_output_key="bid"
)# BidOutputParser類: 自定義的出價輸出解析器
# bid_parser: 實例化的出價解析器

生成競價系統消息

這受到 Generative Agents 中使用LLM確定記憶重要性的提示的啟發。這將使用我們的 BidOutputParser 的格式指令。

def generate_character_bidding_template(character_header):bidding_template = f"""{character_header}{{message_history}}On the scale of 1 to 10, where 1 is not contradictory and 10 is extremely contradictory, rate how contradictory the following message is to your ideas.{{recent_message}}{bid_parser.get_format_instructions()}
Do nothing else."""return bidding_templatecharacter_bidding_templates = [generate_character_bidding_template(character_header)for character_header in character_headers
]# generate_character_bidding_template: 生成角色競價模板
# character_bidding_templates: 所有角色的競價模板列表
for character_name, bidding_template in zip(character_names, character_bidding_templates
):print(f"{character_name} Bidding Template:")print(bidding_template)# 打印生成的競價模板

使用LLM詳細闡述辯論主題

topic_specifier_prompt = [SystemMessage(content="You can make a task more specific."),HumanMessage(content=f"""{game_description}You are the debate moderator.Please make the debate topic more specific. Frame the debate topic as a problem to be solved.Be creative and imaginative.Please reply with the specified topic in {word_limit} words or less. Speak directly to the presidential candidates: {*character_names,}.Do not add anything else."""),
]
specified_topic = ChatOpenAI(temperature=1.0)(topic_specifier_prompt).contentprint(f"Original topic:\n{topic}\n")
print(f"Detailed topic:\n{specified_topic}\n")# 使用LLM生成更詳細的辯論主題

定義發言人選擇函數

最后,我們將定義一個發言人選擇函數 select_next_speaker,它接受每個智能體的出價并選擇出價最高的智能體(同分隨機打破平局)。

我們將定義一個 ask_for_bid 函數,使用我們之前定義的 bid_parser 來解析智能體的出價。我們將使用 tenacity 來裝飾 ask_for_bid,在智能體的出價無法正確解析時多次重試,并在達到最大嘗試次數后生成默認出價0。

@tenacity.retry(stop=tenacity.stop_after_attempt(2),wait=tenacity.wait_none(),  # 重試之間沒有等待時間retry=tenacity.retry_if_exception_type(ValueError),before_sleep=lambda retry_state: print(f"ValueError occurred: {retry_state.outcome.exception()}, retrying..."),retry_error_callback=lambda retry_state: 0,
)  # 當所有重試都用盡時的默認值
def ask_for_bid(agent) -> str:"""請求智能體出價并將出價解析為正確的格式。"""bid_string = agent.bid()bid = int(bid_parser.parse(bid_string)["bid"])return bid# ask_for_bid: 請求智能體出價并解析
# 使用tenacity裝飾器處理可能的錯誤和重試
import numpy as npdef select_next_speaker(step: int, agents: List[DialogueAgent]) -> int:bids = []for agent in agents:bid = ask_for_bid(agent)bids.append(bid)# 在多個具有相同出價的智能體中隨機選擇max_value = np.max(bids)max_indices = np.where(bids == max_value)[0]idx = np.random.choice(max_indices)print("Bids:")for i, (bid, agent) in enumerate(zip(bids, agents)):print(f"\t{agent.name} bid: {bid}")if i == idx:selected_name = agent.nameprint(f"Selected: {selected_name}")print("\n")return idx# select_next_speaker: 選擇下一個發言者
# 根據智能體的出價選擇出價最高的智能體

主循環

characters = []
for character_name, character_system_message, bidding_template in zip(character_names, character_system_messages, character_bidding_templates
):characters.append(BiddingDialogueAgent(name=character_name,system_message=character_system_message,model=ChatOpenAI(temperature=0.2),bidding_template=bidding_template,))# 創建BiddingDialogueAgent實例列表
max_iters = 10
n = 0simulator = DialogueSimulator(agents=characters, selection_function=select_next_speaker)
simulator.reset()
simulator.inject("Debate Moderator", specified_topic)
print(f"(Debate Moderator): {specified_topic}")
print("\n")
while n < max_iters:name, message = simulator.step()print(f"({name}): {message}")print("\n")n += 1# 主循環
# max_iters: 最大對話輪數
# simulator: 對話模擬器實例
# 循環執行對話步驟,每步選擇一個發言者并打印其消息

擴展知識:

  1. 多智能體系統:這個例子展示了一個復雜的多智能體系統,其中多個AI智能體互相交互。這種系統可以用于模擬各種復雜的社會互動場景,如辯論、談判或團隊協作。

  2. 競價機制:使用競價機制來決定發言順序是一種創新的方法。這模擬了真實辯論中參與者爭奪發言機會的動態過程。

  3. 角色扮演:每個AI智能體都被賦予了特定的角色和個性。這種方法可以用于創建更加真實和多樣化的對話場景。

  4. 錯誤處理:使用tenacity庫進行錯誤處理和重試是一個很好的實踐,特別是在處理可能不穩定的AI模型輸出時。

  5. 提示工程:代碼中展示了如何通過精心設計的提示來引導AI模型生成特定格式的輸出,這是LLM應用中的一個關鍵技能。

  6. 輸出解析:使用正則表達式解析器來處理AI模型的輸出,確保獲取所需的信息格式。

  7. 模塊化設計:代碼通過定義不同的類和函數,實現了良好的模塊化設計,使得系統易于理解和擴展。

這個例子展示了如何將多個LangChain和OpenAI的功能結合起來,創建一個復雜的AI驅動的對話系統。它不僅模擬了一個有趣的總統辯論場景,還展示了如何處理多智能體交互、角色扮演、動態發言順序等復雜問題。這種方法可以擴展到各種需要模擬復雜人際互動的應用場景中。

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

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

相關文章

正向代理反向代理

nginx的正向代理和反向代理: 正向代理以及緩存配置: 代理:客戶端不再是直接訪問服務端&#xff0c;通過代理服務器訪問服務端。 正向代理&#xff1a;面向客戶端&#xff0c;通過代理服務器的ip地址訪問目標服務端 服務端只知道代理服務器的地址&#xff0c;真正的客戶端ip可以…

【MySQL系列】隱式轉換

&#x1f49d;&#x1f49d;&#x1f49d;歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:kwan 的首頁,持續學…

ctfshow web入門 nodejs

web334 有個文件下載之后改后綴為zip加壓就可以得到兩個文件 一個文件類似于index.php 還有一個就是登錄密碼登錄成功就有flag username:ctfshow password:123456因為 return name!CTFSHOW && item.username name.toUpperCase() && item.password passwor…

產科管理系統 專科電子病歷系統源碼,前后端分離架構,多家醫院產科廣泛運用,系統穩定,功能齊全

產科管理系統 專科電子病歷系統源碼&#xff0c;前后端分離架構&#xff0c;多家醫院產科廣泛運用&#xff0c;系統穩定&#xff0c;功能齊全 產科管理系統&#xff0c;特別是產科信息管理系統&#xff08;Obstetrical Information Management System&#xff0c;簡稱OIMS&…

智能井蓋監測系統:守護城市安全的新防線

? ??在快速發展的現代都市中&#xff0c;井蓋作為連接地上與地下世界的“隱形門”&#xff0c;其安全狀態直接關系到市民的生命財產安全。隨著物聯網、大數據及人工智能技術的飛速發展&#xff0c;智能井蓋監測系統的出現為解決傳統井蓋管理難題提供了創新方案&#xff0…

【算法筆記自學】入門篇(2)——算法初步

4.1排序 自己寫的題解 #include <stdio.h> #include <stdlib.h>void selectSort(int A[], int n) {for(int i 0; i < n - 1; i) { // 修正索引范圍int k i;for(int j i 1; j < n; j) { // 修正索引范圍if(A[j] < A[k]) {k j;}}if (k ! i) { // 僅在…

跨境人最怕的封店要怎么規避?

跨境人最怕的是什么&#xff1f;——封店 造成封店的原因很多&#xff0c;IP關聯、無版權售賣、虛假發貨等等&#xff0c;其中IP關聯這個問題導致店鋪被封在跨境商家中簡直是屢見不鮮 IP關聯&#xff0c;是指被海外平臺檢測到多家店鋪開設在同一個站點上的情況。我們知道有些…

賣家必讀:阿里巴巴國際站登錄與入駐全流程

阿里巴巴國際站作為全球最大的B2B電子商務平臺之一&#xff0c;為品牌建立和業務拓展提供了可能。那么跨境賣家如何才能成功登錄和入駐阿里巴巴國際站&#xff1f;本文將講解如何用阿里巴巴國際站網頁版進行登錄&#xff0c;以及阿里巴巴國際站賣家的入駐條件、流程和費用。此外…

統計信號處理基礎 習題解答11-12

題目 證明 的MAP估計量為 其中是一個的矢量, 是一個可逆的p*p的矩陣。也就是說&#xff0c;MAP估計量對可逆的線性變換是可以變換的。 解答 已知的聯合概率密度 且&#xff1a; 現在知道&#xff1a; 那么為了獲得變換后的MAP&#xff0c;首先需要根據求出 根據概率密度變換…

2024年軟件測試面試題,精選100+,附答案+文檔

&#x1f345; 視頻學習&#xff1a;文末有免費的配套視頻可觀看 &#x1f345; 點擊文末小卡片 &#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 Part1 1、你的測試職業發展是什么&#xff1f; 測試經驗越多&#xff0c;測試能力越高。所以我…

C++入門 容器適配器 / stack queue模擬實現

目錄 容器適配器 deque的原理介紹 stack模擬實現 queue模擬實現 priority_queue模擬實現 仿函數 容器適配器 適配器是一種設計模式(設計模式是一套被反復使用的、多數人知曉的、經過分類編目的、代碼設計經驗的總 結)&#xff0c;該種模式是將一個類的接口轉換成客戶希望…

深度學習Week19——學習殘差網絡和ResNet50V2算法

文章目錄 深度學習Week18——學習殘差網絡和ResNet50V2算法 一、前言 二、我的環境 三、論文解讀 3.1 預激活設計 3.2 殘差單元結構 四、模型復現 4.1 Residual Block 4.2 堆疊Residual Block 4.3. ResNet50V2架構復現 一、前言 &#x1f368; 本文為&#x1f517;365天深度學…

Kubernetes k8s 命名空間 namespace 介紹以及應用 資源限額配置

目錄 命名空間 什么是命名空間&#xff1f; namespace應用場景 namespacs使用案例分享 namespace資源限額 文檔中的YAML文件配置直接復制粘貼可能存在格式錯誤&#xff0c;故實驗中所需要的YAML文件以及本地包均打包至網盤 鏈接&#xff1a;https://pan.baidu.com/s/1qv8Tc…

Python中異步事件觸發

1、問題背景 在Python中&#xff0c;我想創建一個由事件生成控制流程的類結構。為此&#xff0c;我做了以下工作&#xff1a; class MyEvent: EventName_FunctionName {}classmethoddef setup(cls, notificationname, functionname):if notificationname in MyEvent.EventN…

ONLYOFFICE 8.1版本震撼來襲,讓辦公更高效、更智能

官網鏈接&#xff1a; 在線PDF查看器和轉換器 | ONLYOFFICE 在線辦公套件 | ONLYOFFICE 隨著科技的不斷發展&#xff0c;辦公軟件已經成為現代企業提高工作效率、實現信息共享的重要工具。在我國&#xff0c;一款名為ONLYOFFICE的在線辦公套件受到了越來越多企業的青睞。今天…

golang中的類型轉換那些事

由于golang是一門強類型的語言&#xff0c; 所以我們在golang的開發中不可避免的會對一些數據類型進行手動轉換&#xff0c;以適應我們的業務需求。 golang中類型轉換的途徑大致有4種&#xff0c;強制轉換&#xff0c;類型斷言&#xff0c;類型匹配 還有使用strconv包中提供的…

[TensorFlow-Lite][深度學習]【快速簡介-1】

前言&#xff1a; 很多場景下面我們需要需要把我們的深度學習模型部署到Android,IOS 手機上面. Google 通過TensorFlow Lite 提供了對應的解決方案. 目錄&#xff1a; 端側部署優點 硬件支持 性能 應用案例 一 端側部署優點 1; 很多場景下面&#xff1a; 無網絡,數據無法…

Hadoop 遠程 debug

Hadoop 命令行 在執行 hadoop fs 命令行之前&#xff0c;先執行以下命令&#xff1a; export HADOOP_CLIENT_OPTS"-Xdebug -Xrunjdwp:transportdt_socket,servery,suspendy,address8000"

昇思25天學習打卡營第10天|基于MindSpore實現BERT對話情緒識別

基于MindSpore實現BERT對話情緒識別 模型簡介數據集模型構建模型驗證模型推理自定義推理數據集 模型簡介 BERT全稱是來自變換器的雙向編碼器表征量&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;&#xff0c;它是Google于2018年末開發并發…

HTML超鏈接和錨鏈接

HTML超鏈接和錨鏈接 一、定義 HTML的超鏈接&#xff08;Hyperlink&#xff09;用于在網頁之間創建鏈接&#xff0c;使用戶可以點擊這些鏈接來導航到其他頁面或資源。 二、基本語法 1、語法 HTML中的超鏈接使用a標簽來定義 <a href"URL">鏈接文本</a&g…