上一节中咱们简单的介绍了一个BabyAgi的首要功用,以及首要功用。没有看过的朋友能够直接点击babyagi: 人工智能使命办理体系前去查看

在本篇中,咱们将深化讨论经过prompt和context约束GPT-4完结的BabyAGI体系的源代码解析与运用。文章将详细介绍BabyAGI的中心组件,如使命履行、使命创立与使命优先级等功用,以及如何结合GPT-4、Pinecone和LangChain等技术完结这一高效的使命驱动智能署理。经过对源代码的分析,咱们将提醒这一体系在处理使命、生成新使命以及实时优先级调整方面的要害技术细节,并讨论潜在的改善和危险。本文旨在帮助读者更好地了解和利用GPT-4的强大功用,以完结多样化的运用场景。

源代码

为了尽量节约篇幅,我这儿就不直接贴源代码了。咱们能够去github上babyagi 查看源代码,其实也就只要一个python文件,200行代码左右,因为现在项目更新的比较快,本文选用的是2023年04月07日的之前的版别进行解读。

首要流程

先给咱们看一下我自己经过阅览源码,整理出来的babyagi履行流程图。这儿咱们先看一下全部流程,先有个形象

通过prompt和context约束GPT4: babyagi源代码解读

首要流程代码如下所示:

# 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']}"
        # print(f"使命履行成果 {enriched_result}   使命履行ID {result_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)
  • 依据.env文件中读取的FIRST_TASK创立第一个使命并设置使命id,初始化使命计数器task_id_counter
  • 进入循环,判别使命列表傍边是否有使命,如果有使命那么就将当前使命列表傍边的使命打印出来
  • 从deque队列的尾部取出第一个元素,也便是第一个使命,打印使命id和使命称号
  • 将第一个使命放入履行署理execution_agent并获取履行成果,并将当期先使命的id保存在this_task_id傍边
  • 将使命成果运用get_ada_embedding变为高维向量,作为向量方针的值,再使命称号和使命成果封装为一个map作为向量方针的meta元数据。最终将向量方针刺进到向量索引傍边
  • 将用户设定的方针以及刚刚履行的使命,使命履行成果,当前使命列表,放入到使命创立署理函数task_creation_agent创立出新的使命,并将新的使命添加到使命列表傍边,
  • 调用prioritization_agent函数,依据当前使命列表和GPT-4的指导,从头调整使命的优先级。

处理函数

在介绍完了大概得履行流程之后,下面咱们来别离讲解下各个处理的函数的完结办法以及原理。

GPT处理函数

该函数用于处理传入的prompt,在运用对应的模型进行处理之后,回来对应的complete。

def openai_call(prompt: str, model: str = OPENAI_API_MODEL, temperature: float = 0.5, max_tokens: int = 100):
    if not model.startswith('gpt-'):
        # Use completion API
        response = openai.Completion.create(
            engine=model,
            prompt=prompt,
            temperature=temperature,
            max_tokens=max_tokens,
            top_p=1,
            frequency_penalty=0,
            presence_penalty=0
        )
        return response.choices[0].text.strip()
    else:
        # Use chat completion API
        messages=[{"role": "user", "content": prompt}]
        response = openai.ChatCompletion.create(
            model=model,
            messages=messages,
            temperature=temperature,
            max_tokens=max_tokens,
            n=1,
            stop=None,
        )
        return response.choices[0].message.content.strip()

了解openai的api的小伙伴应该知道,openai的对话模型需求咱们传入一个prompt,然后openai依据运用的model以及相关参数的设置(详细看openai开发者官方网站介绍)。它就会回来给咱们一个complete也便是咱们需求的成果。这儿opanai_call函数只需求接纳一个参数prompt即可,回来值为complete

向量处理函数

get_ada_embedding

顾名思义该函数的用处是将text文本转化为向量的。

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

这儿运用的是openai向量转化模型text-embedding-ada-002,该模型的运用办法如下

通过prompt和context约束GPT4: babyagi源代码解读
这样一来咱们就能够依照openai的规则将文本转化为其支撑的向量。

context_agent

向量索引查询函数,承受传入的查询条件,以及查询成果限制数量n,回来与查询条件相关度最高的使命。

def context_agent(query: str, n: int):
    query_embedding = get_ada_embedding(query)
    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]

履行署理

该函数的首要逻辑是传入用户设置的方针objective,和需求履行的使命称号,回来履行的使命成果,当然履行署理在履行进程傍边,也会经过context_agent函数获取与方针最相关的使命。

def execution_agent(objective: str, task: str) -> str:
    context=context_agent(query=objective, n=5)
    # print("\n*******RELEVANT CONTEXT******\n")
    # print(context)
    prompt =f"You are an AI who performs one task based on the following objective: {objective}.\nTake into account these previously completed tasks: {context}\nYour task: {task}\nResponse:"
    return openai_call(prompt, temperature=0.7, max_tokens=2000)

中心prompt

为了便当咱们了解prompt对模型的约束,这儿供给prompt的中英文对照版 原始prompt

You are an AI who performs one task based on the following objective:{objective}
Take into account these previously completed tasks:{context}
Your task:{task}  
Response:

中文版

你是一个依据以下方针履行使命的AI: objective
考虑这些之前完结的使命:context 
你的使命:task 
履行成果:也便是AI的答复

经过这些prompt咱们成功的给ai设置的使命,这个使命首要切合咱们设置的方针,还有考虑之前做的使命,防止类似的使命重复履行,让AI有了上下文相关防止了无效的使命履行

使命创立署理

该函数的首要使命是依据给定的使命方针、已完结使命的成果、已完结使命的描绘以及未完结使命列表,运用 GPT-4 生成一组新使命

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_call(prompt)
    new_tasks = response.split('\n')
    return [{"task_name": task_name} for task_name in new_tasks]

接纳以下四个参数:

  • objective:当前使命的方针。
  • result:已完结使命的成果。
  • task_description:已完结使命的描绘。
  • task_list:未完结使命的列表。

中心prompt

//prompt1
You are an task creation AI that uses the result of an execution agent to create new tasks with the following objective: {objective}, 
//prompt2 
The last completed task has the result: {result}. 
//prompt3 
This result was based on this task description: {task_description}. 
//prompt4 
These are incomplete tasks: {', '.join(task_list)}. 
//prompt5 
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.

中文版

//prompt1
你是一个使命创立AI,运用履行署理的成果来创立新的使命,方针如下:{objective} 
//prompt2
最近一个完结的使命的成果是:{task_description}. 
//prompt3
最近一个完结的使命称号是:{task_description} 
//prompt4
以下是未完结的使命: {', '.join(task_list)}. 
//prompt5
依据成果,创立新的使命,由AI体系完结,不与未完结的使命堆叠。以数组的方式回来使命。

经过这些prompt咱们能够规定AI在创立新的使命的时候,防止当前使命列表傍边现已存在的使命,并参考最近一次使命履行成果,以及使命称号。来实时生成新的不重复的使命下一次循环履行。

优先级署理

首要作用是从头对使命列表进行优先级排序。它依据供给的当前使命ID(this_task_id)和大局使命列表(task_list),运用GPT-4为使命生成一个新的优先级次序


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_call(prompt)
    new_tasks = response.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})

中心prompt

原prompt

//prompt1
You are an task prioritization AI tasked with cleaning the formatting of and reprioritizing the following tasks: {task_names}.
//prompt2
Consider the ultimate objective of your team:{OBJECTIVE}.
//prompt3
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}.

中文版别

//prompt1
你是一个使命优先级AI,使命是清理以下使命的格式和从头排序:{task_names} 
//prompt2
需求考虑团队的最终方针:{OBJECTIVE} 
//prompt3
不要删去任何使命。回来成果为一个编号的列表,
如: 
#。第一个使命 
#。第二个使命 
运用数字{next_task_id}启动使命列表。

该prompt构建一个包含使命称号、团队的最终方针(OBJECTIVE)以及要求按次序排列使命的字符串提示(prompt)将提示传递给 GPT-4,以获取新的使命优先级次序。

当然GPT4回来给咱们的成果肯定是一个字符串,如下方式,所以咱们需求运用分隔符 \n ,将字符串转化为成果数组new_tasks,然后在将new_tasks中的每一个使命字符串(1.xxxxx) 切开开来,分为task_id部分和task内容部分,存入到大局task_list傍边。

"1.xxx\n2.xxx\n3.xxxxx\n....."

结束

本文讨论了如安在GPT-4模型中运用prompt和context对AI体系施加约束,以完结使命自动生成与自主履行的能力。这些办法有助于前进AI体系的针对性、可控性和可靠性,为完结真实的人工智能(AGI)供给了重要基础。

咱们阐述了经过精心设计的prompt和充分利用上下文信息,如何确保AI在生成新使命时遵从预定规则,防止与现有使命重复。同时,AI体系能够依据最近一次使命履行成果和使命描绘,实时生成不重复的使命并进行下一轮的自主履行。这种自主性有助于前进AI体系的工作效率,下降资源耗费和冗余操作。

将prompt与GPT-4模型相结合,有望更好地应对实际运用场景中的挑战,为构建更智能、更自主的AI体系奠定基础。跟着技术的不断发展,咱们预期未来的AGI将能够更深化地了解人类需求,自主地创立和履行使命,为咱们的生活和工作带来更多的便当与价值。这种前进将推动人工智能研讨领域的发展,为未来AI体系的运用供给更广阔的前景。

最终欢迎咱们留言与我一起讨论问题。喜欢的话也能够给我点个赞,趁便重视我一波