Skip to content

Commit

Permalink
Merge pull request #19 from GoldWaterFall/chapter4
Browse files Browse the repository at this point in the history
Chapter4
  • Loading branch information
limafang authored May 10, 2024
2 parents 137f4c3 + ec3878b commit 9ccd34a
Show file tree
Hide file tree
Showing 9 changed files with 1,389 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/chapter4/Multi Agent 概念模块.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
comments: true
---
## 4.1 Multi Agent 概念概述
Binary file added docs/chapter4/assets/images/example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/chapter4/assets/images/homework.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/chapter4/assets/images/logic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/chapter4/assets/images/mind.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions docs/chapter4/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
comments: true
---

# 4.第四章:智能体综述及多智能体框架介绍

# 前期准备
本章我们会介绍MetaGPT多智能体的开发流程,通过案例实现多智能体的开发


173 changes: 173 additions & 0 deletions docs/chapter4/多智能体开发作业.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
---
comments: true
---

## 4.4 多智能体开发作业

### 基础作业

基于 env 或 team 设计一个你的多智能体团队,尝试让他们完成 你画我猜文字版 ,要求其中含有两个agent,其中一个agent负责接收来自用户提供的物体描述并转告另一个agent,另一个agent将猜测用户给出的物体名称,两个agent将不断交互直到另一个给出正确的答案

(也可以在系统之上继续扩展,比如引入一个agent来生成词语,而人类参与你画我猜的过程中)

### 进阶作业

进阶作业只面向愿意深入探索MG潜力并检验自己学习成果的同学,只要完成基础作业视为学习完成。

如何检验mg的Agent开发学习程度呢?我认为对于本次学习,如果对于一个问题(过往交由人解决的)SOP可以将SOP迅速抽象成MG的Role和Action形式并且用多智能体协同完成,即达到了本次学习的目的。 重写babyagi是一个非常合适的任务。 babyagi是[yoheinakajima](https://twitter.com/yoheinakajima)的一个demo,他的主业是一位投资人,在2023年上半年AutoGPT爆火之际,完成了这个demo,实际上是这位投资人的日常任务规划优先级解决的一套SOP 以下是babyagi的实现流程

![homework](assets/images/homework.png)

```python
import openai
import pinecone
import time
from collections import deque
from typing import Dict, List

#Set API Keys
OPENAI_API_KEY = ""
PINECONE_API_KEY = ""
PINECONE_ENVIRONMENT = "us-east1-gcp" #Pinecone Environment (eg. "us-east1-gcp")

#Set Variables
YOUR_TABLE_NAME = "test-table"
OBJECTIVE = "Solve world hunger."
YOUR_FIRST_TASK = "Develop a task list."

#Print OBJECTIVE
print("\033[96m\033[1m"+"\n*****OBJECTIVE*****\n"+"\033[0m\033[0m")
print(OBJECTIVE)

# Configure OpenAI and Pinecone
openai.api_key = OPENAI_API_KEY
pinecone.init(api_key=PINECONE_API_KEY, environment=PINECONE_ENVIRONMENT)

# Create Pinecone index
table_name = YOUR_TABLE_NAME
dimension = 1536
metric = "cosine"
pod_type = "p1"
if table_name not in pinecone.list_indexes():
pinecone.create_index(table_name, dimension=dimension, metric=metric, pod_type=pod_type)

# Connect to the index
index = pinecone.Index(table_name)

# Task list
task_list = deque([])

def add_task(task: Dict):
task_list.append(task)

def get_ada_embedding(text):
text = text.replace("\n", " ")
return openai.Embedding.create(input=[text], model="text-embedding-ada-002")["data"][0]["embedding"]

def task_creation_agent(objective: str, result: Dict, task_description: str, task_list: List[str]):
prompt = f"You are an task creation AI that uses the result of an execution agent to create new tasks with the following objective: {objective}, The last completed task has the result: {result}. This result was based on this task description: {task_description}. These are incomplete tasks: {', '.join(task_list)}. Based on the result, create new tasks to be completed by the AI system that do not overlap with incomplete tasks. Return the tasks as an array."
response = openai.Completion.create(engine="text-davinci-003",prompt=prompt,temperature=0.5,max_tokens=100,top_p=1,frequency_penalty=0,presence_penalty=0)
new_tasks = response.choices[0].text.strip().split('\n')
return [{"task_name": task_name} for task_name in new_tasks]

def prioritization_agent(this_task_id:int):
global task_list
task_names = [t["task_name"] for t in task_list]
next_task_id = int(this_task_id)+1
prompt = f"""You are an task prioritization AI tasked with cleaning the formatting of and reprioritizing the following tasks: {task_names}. Consider the ultimate objective of your team:{OBJECTIVE}. Do not remove any tasks. Return the result as a numbered list, like:
#. First task
#. Second task
Start the task list with number {next_task_id}."""
response = openai.Completion.create(engine="text-davinci-003",prompt=prompt,temperature=0.5,max_tokens=1000,top_p=1,frequency_penalty=0,presence_penalty=0)
new_tasks = response.choices[0].text.strip().split('\n')
task_list = deque()
for task_string in new_tasks:
task_parts = task_string.strip().split(".", 1)
if len(task_parts) == 2:
task_id = task_parts[0].strip()
task_name = task_parts[1].strip()
task_list.append({"task_id": task_id, "task_name": task_name})

def execution_agent(objective:str,task: str) -> str:
#context = context_agent(index="quickstart", query="my_search_query", n=5)
context=context_agent(index=YOUR_TABLE_NAME, query=objective, n=5)
#print("\n*******RELEVANT CONTEXT******\n")
#print(context)
response = openai.Completion.create(
engine="text-davinci-003",
prompt=f"You are an AI who performs one task based on the following objective: {objective}. Your task: {task}\nResponse:",
temperature=0.7,
max_tokens=2000,
top_p=1,
frequency_penalty=0,
presence_penalty=0
)
return response.choices[0].text.strip()

def context_agent(query: str, index: str, n: int):
query_embedding = get_ada_embedding(query)
index = pinecone.Index(index_name=index)
results = index.query(query_embedding, top_k=n,
include_metadata=True)
#print("***** RESULTS *****")
#print(results)
sorted_results = sorted(results.matches, key=lambda x: x.score, reverse=True)
return [(str(item.metadata['task'])) for item in sorted_results]

# Add the first task
first_task = {
"task_id": 1,
"task_name": YOUR_FIRST_TASK
}

add_task(first_task)
# Main loop
task_id_counter = 1
while True:
if task_list:
# Print the task list
print("\033[95m\033[1m"+"\n*****TASK LIST*****\n"+"\033[0m\033[0m")
for t in task_list:
print(str(t['task_id'])+": "+t['task_name'])

# Step 1: Pull the first task
task = task_list.popleft()
print("\033[92m\033[1m"+"\n*****NEXT TASK*****\n"+"\033[0m\033[0m")
print(str(task['task_id'])+": "+task['task_name'])

# Send to execution function to complete the task based on the context
result = execution_agent(OBJECTIVE,task["task_name"])
this_task_id = int(task["task_id"])
print("\033[93m\033[1m"+"\n*****TASK RESULT*****\n"+"\033[0m\033[0m")
print(result)

# Step 2: Enrich result and store in Pinecone
enriched_result = {'data': result} # This is where you should enrich the result if needed
result_id = f"result_{task['task_id']}"
vector = enriched_result['data'] # extract the actual result from the dictionary
index.upsert([(result_id, get_ada_embedding(vector),{"task":task['task_name'],"result":result})])

# Step 3: Create new tasks and reprioritize task list
new_tasks = task_creation_agent(OBJECTIVE,enriched_result, task["task_name"], [t["task_name"] for t in task_list])

for new_task in new_tasks:
task_id_counter += 1
new_task.update({"task_id": task_id_counter})
add_task(new_task)
prioritization_agent(this_task_id)

time.sleep(1) # Sleep before checking the task list again
```

以上是来自于babyagi仓库的源码,总行数140行涵盖prompt,同时任务为三个agent进行协同组织。

这个是babyagi的webui演示https://babyagi-ui.vercel.app/zh,同学们可以先体验一下了解一下babyagi的输入输出的workflow结合上图用MG进行重写。 其中MG已经抽象好了许多上层类,以及react的规划模式和actions列表。 思考部分:

1. 什么是enrich
2. 何时应该creat new task,何时应该排序任务优先级
3. 新的new task应该观察什么作为创建的依据(当前任务列表/目标/已完成的任务结果)
4. 人类是否可以介入这个流程比如新任务的合入审核,任务执行时的拆解?

你不一定要完全依据源码的逻辑进行重写,尝试找到更优秀的SOP.

> Chroma/Weaviate 来存储和检索上下文的任务结果。该脚本根据 TABLE_NAME 变量中指定的表名创建 Chroma/Weaviate 集合。然后使用 Chroma/Weaviate 将任务结果以及任务名称和任何其他元数据存储在集合中。而向量数据库并不是本次学习的重点即便MG的example里有对向量检索进行支持,理论上loop的次数较少时是可以将上下文的任务结果完全的作为prompt的输入,所以在本次学习中可以将上下文的任务结果写入一个外部的txt或者直接在memory中调用的,学习者可以不使用向量数据库完成本次任务
Loading

0 comments on commit 9ccd34a

Please sign in to comment.