AutoGPT中的复杂任务分解是如何做的?

什么是Auto-GPT

地址:github.com/Torantulino…
这个程序由GPT-4驱动,将LLM"思想"链接在一起,以自主实现您设定的任何目标。
Auto-GPT是将OpenAI的GPT模型的多个实例链接在一起,使其能够在没有帮助的情况下完成任务、编写和调试代码以及纠正自己的编写错误等事情。
Auto-GPT不是简单地要求ChatGPT创建代码,而是让多个AI代理协同工作,因为它将语言模型变成了一个更有能力的代理,可以采取行动并从错误中学习。

安装步骤

 
bash
复制代码
git clone https://github.com/Torantulino/Auto-GPT.git
cd 'Auto-GPT'
pip install -r requirements.txt
python scripts/main.py
// 如果需要debug
python scripts/main.py --debug

1、必要的配置:
(1)先将.env.template拷贝.env,必须配置:OPENAI_API_KEY(在openai平台申请platform.openai.com/account/api…
(2)如果您使用的是Azure实例,使用USE_AZURE=True,配置OPENAI_AZURE_API_BASE,OPENAI_AZURE_API_VERSION,OPENAI_AZURE_DEPLOYMENT_ID;
2、非必要的配置:
(1)语音模式需要去elevenlabs.io申请ElevenLabs API密钥,配置:ELEVEN_LABS_API_KEY;
(2)谷歌API密钥配置,主要是如果提问的过程中需要搜索,就需要配置;
(3)Redis或者Pinecone配置,主要是存储一些历史问题和回答的向量缓存;
(4)生成图片,默认情况下,Auto-GPT 使用 DALL-e 进行图像生成,也可以配置HUGGINGFACE_API_TOKEN使用Stable Diffusion;
(5)由于国内用户没有GPT4权限,可以走gpt3.5模式:

 
css
复制代码
python scripts/main.py --gpt3only

实现原理

AutoGPT实现:行动 -> 观察行动结果 -> 思考 -> 决定下一步行动的自我循环,如何实现的呢? 

我的配置文件(ai_settings.yaml,使用--gpt3only) :

 
diff
复制代码
ai_goals:
- 告诉我LangChain如何使用.
- 帮我安装LangChain.
- 告诉我一些可以直接在我电脑上运行LangChain的例子.
ai_name: 我是GPT
ai_role: LangChain如何使用

1、Prompt模板

首先AutoGPT会将问题转换为Prompt模板,拼接{ai_name}和{ai_role},填入GOALS:{ai_goals};
然后加上一些限制条件CONSTRAINTS,COMMANDS,RESOURCES和PERFORMANCE EVALUATION模板;
最后提供一个JSON的返回格式,如果ChatGPT返回回来,是一段JSON,并且补充需要用python json.loads可以直接执行的;
具体如下:

 
vbnet
复制代码
You are 我是GPT, LangChain如何使用
Your decisions must always be made independently without seeking user assistance. Play to your strengths as an LLM and pursue simple strategies with no legal complications.

GOALS:

1. 告诉我LangChain如何使用.
2. 帮我安装LangChain.
3. 告诉我一些可以直接在我电脑上运行LangChain的例子.
4. 所有的问题都用中文回答.

CONSTRAINTS:

1. ~4000 word limit for short term memory. Your short term memory is short, so immediately save important information to files.
2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember.
3. No user assistance
4. Exclusively use the commands listed in double quotes e.g. "command name"

COMMANDS:

1. Google Search: "google", args: "input": "<search>"
5. Browse Website: "browse_website", args: "url": "<url>", "question": "<what_you_want_to_find_on_website>"
6. Start GPT Agent: "start_agent",  args: "name": "<name>", "task": "<short_task_desc>", "prompt": "<prompt>"
7. Message GPT Agent: "message_agent", args: "key": "<key>", "message": "<message>"
8. List GPT Agents: "list_agents", args: ""
9. Delete GPT Agent: "delete_agent", args: "key": "<key>"
10. Write to file: "write_to_file", args: "file": "<file>", "text": "<text>"
11. Read file: "read_file", args: "file": "<file>"
12. Append to file: "append_to_file", args: "file": "<file>", "text": "<text>"
13. Delete file: "delete_file", args: "file": "<file>"
14. Search Files: "search_files", args: "directory": "<directory>"
15. Evaluate Code: "evaluate_code", args: "code": "<full_code_string>"
16. Get Improved Code: "improve_code", args: "suggestions": "<list_of_suggestions>", "code": "<full_code_string>"
17. Write Tests: "write_tests", args: "code": "<full_code_string>", "focus": "<list_of_focus_areas>"
18. Execute Python File: "execute_python_file", args: "file": "<file>"
19. Task Complete (Shutdown): "task_complete", args: "reason": "<reason>"
20. Generate Image: "generate_image", args: "prompt": "<prompt>"
21. Do Nothing: "do_nothing", args: ""

RESOURCES:

1. Internet access for searches and information gathering.
2. Long Term memory management.
3. GPT-3.5 powered Agents for delegation of simple tasks.
4. File output.

PERFORMANCE EVALUATION:

1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.
2. Constructively self-criticize your big-picture behavior constantly.
3. Reflect on past decisions and strategies to refine your approach.
4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.

You should only respond in JSON format as described below

RESPONSE FORMAT:
{
    "thoughts":
    {
        "text": "thought",
        "reasoning": "reasoning",
        "plan": "- short bulleted\
- list that conveys\
- long-term plan",
        "criticism": "constructive self-criticism",
        "speak": "thoughts summary to say to user"
    },
    "command": {
        "name": "command name",
        "args":{
            "arg name": "value"
        }
    }
}

Ensure the response can be parsed by Python json.loads

  

源码会调用到:

 
ini
复制代码
# 这里实际就是将以上组装的数据发送给openai的接口
assistant_reply = create_chat_completion(
    model=model,
    messages=current_context,
    max_tokens=tokens_remaining,
)

# Update full message history
full_message_history.append(
    create_chat_message(
        "user", user_input))
full_message_history.append(
    create_chat_message(
        "assistant", assistant_reply))

2、处理获取结果

执行第一步以后就能拿到结果,如下:

 
swift
复制代码
{
    "thoughts":{
        "text": "LangChain is a programming language that can be used for blockchain development. To use it, we need to first download and install it on our computer. After installation, we can run some code examples to test it out. ",
        "reasoning": "I reviewed the purpose and usage of LangChain and suggested a plan for installation and testing",
        "plan": "- Download and install LangChain.\n- Run code examples to test it out.",
        "criticism": "I should have provided more specific detailed steps on how to download and install LangChain",
        "speak": "We need to download and install LangChain before we can use it. Do you have any experience with this?"
    },
    "command":{
        "name": "browse_website",
        "args":{
            "url": "https://langchain.org/docs/getting-started/",
            "question": "How to download and install LangChain?"
        }
    }
}

可以看到返回的plan拆分为两个步骤:

 
css
复制代码
-  Download and install LangChain.
-  Run code examples to test it out.

然后也给出了命令:browse_website和参数;

3、执行任务

可以从AutoGPT的源码中看到,提供了很多执行脚本的方式,比如google搜索,执行execute_shell脚本等。

 
kotlin
复制代码
try:
    if command_name == "google":

        # Check if the Google API key is set and use the official search method
        # If the API key is not set or has only whitespaces, use the unofficial search method
        if cfg.google_api_key and (cfg.google_api_key.strip() if cfg.google_api_key else None):
            return google_official_search(arguments["input"])
        else:
            return google_search(arguments["input"])
    elif command_name == "memory_add":
        return memory.add(arguments["string"])
    elif command_name == "start_agent":
        return start_agent(
            arguments["name"],
            arguments["task"],
            arguments["prompt"])
    elif command_name == "message_agent":
        return message_agent(arguments["key"], arguments["message"])
    elif command_name == "list_agents":
        return list_agents()
    elif command_name == "delete_agent":
        return delete_agent(arguments["key"])
    elif command_name == "get_text_summary":
        return get_text_summary(arguments["url"], arguments["question"])
    elif command_name == "get_hyperlinks":
        return get_hyperlinks(arguments["url"])
    elif command_name == "read_file":
        return read_file(arguments["file"])
    elif command_name == "write_to_file":
        return write_to_file(arguments["file"], arguments["text"])
    elif command_name == "append_to_file":
        return append_to_file(arguments["file"], arguments["text"])
    elif command_name == "delete_file":
        return delete_file(arguments["file"])
    elif command_name == "search_files":
        return search_files(arguments["directory"])
    elif command_name == "browse_website":
        return browse_website(arguments["url"], arguments["question"])
    # TODO: Change these to take in a file rather than pasted code, if
    # non-file is given, return instructions "Input should be a python
    # filepath, write your code to file and try again"
    elif command_name == "evaluate_code":
        return ai.evaluate_code(arguments["code"])
    elif command_name == "improve_code":
        return ai.improve_code(arguments["suggestions"], arguments["code"])
    elif command_name == "write_tests":
        return ai.write_tests(arguments["code"], arguments.get("focus"))
    elif command_name == "execute_python_file":  # Add this command
        return execute_python_file(arguments["file"])
    elif command_name == "execute_shell":
        if cfg.execute_local_commands:
            return execute_shell(arguments["command_line"])
        else:
            return "You are not allowed to run local shell commands. To execute shell commands, EXECUTE_LOCAL_COMMANDS must be set to 'True' in your config. Do not attempt to bypass the restriction."
    elif command_name == "generate_image":
        return generate_image(arguments["prompt"])
    elif command_name == "do_nothing":
        return "No action performed."
    elif command_name == "task_complete":
        shutdown()
    else:
        return f"Unknown command '{command_name}'. Please refer to the 'COMMANDS' list for available commands and only respond in the specified JSON format."
# All errors, return "Error: + error message"
except Exception as e:
    return "Error: " + str(e)

根据以上给出的browse_website,参数是https://langchain.org/docs/getting-started/How to download and install LangChain?
根据以上的代码就会执行:

 
css
复制代码
browse_website(arguments["url"], arguments["question"])

由于https://langchain.org/docs/getting-started/这个地址就是错误的,所以执行报错:

图片

这样就结束了么?AutoGPT会将报错的信息catch:

 
kotlin
复制代码
# All errors, return "Error: + error message"
    except Exception as e:
        return "Error: " + str(e)

图片

将错误组装一下,继续发给ChatGPT,然后得到的回复是- Conduct a Google search to find out how to download and install LangChain.,意思是需要使用Google搜索,其中返回需要执行的命令:

 
css
复制代码
"command":{
    "name": "google",
    "args":{
        "input": "how to download and install LangChain"
    }
}

因此下一步就走到google_search的函数...,由于篇幅原因,具体后续的执行就省略。

4、循环执行任务

在AutoGPT是一步一步确认的,整个逻辑是在一个大循环中:

 
ini
复制代码
# Interaction Loop
while True:
    # 发送数据给AI,然后获得回应
    assistant_reply = chat.chat_with_ai(
            prompt,
            user_input,
            full_message_history,
            memory,
            cfg.fast_token_limit)
    # 解析以获得需要执行的命令和参数(由于返回的JSON需要校准,所以这里会有比较多的处理)
    # 执行命令
    # 将每次的问题和回复记录memory中
    # ...

其中chat_with_ai的参数:
(1)prompt是解释规则给AI的提示,主要有几个信息:
a. AI的名字,每次对话自己设置的
b. 描述AI需要帮你实现的事情
c. 输入几个需要实现的目标(一般设置5个)
(2)user_input是用户输入
(3)full_message_history是用户和AI之间发送的所有消息的列表
(4)memory是包含永久记忆的内存对象
(5)fast_token_limit是API调用中允许的最大令牌数

5、memory的作用

AutoGPT支持三种向量存储:pinecone,redis,local,默认使用LocalCache。如下:

 
python
复制代码
if cfg.memory_backend == "pinecone":
    if not PineconeMemory:
        print("Error: Pinecone is not installed. Please install pinecone"
                " to use Pinecone as a memory backend.")
    else:
        memory = PineconeMemory(cfg)
        if init:
            memory.clear()
elif cfg.memory_backend == "redis":
    if not RedisMemory:
        print("Error: Redis is not installed. Please install redis-py to"
                " use Redis as a memory backend.")
    else:
        memory = RedisMemory(cfg)

if memory is None:
    memory = LocalCache(cfg)
    if init:
        memory.clear()

主要是控制token的数量,通过存储对话的上下文,找到全部历史信息中的最近10个关键上下文继续组成下一次上下文,比如LocalCache就是通过ada算法实现topk搜索:

 
ini
复制代码
def get_relevant(self, text: str, k: int) -> List[Any]:
    embedding = get_ada_embedding(text)
    scores = np.dot(self.data.embeddings, embedding)
    top_k_indices = np.argsort(scores)[-k:][::-1]
    return [self.data.texts[i] for i in top_k_indices]

所以AutoGPT有点像「套娃」,通过你输入的问题,不断去ChatGPT上查找解决方案,然后执行各个命令,如果命令返回不对,继续指定下一步计划,直到你得到结果为止。
专业一点的话来说,这叫模型堆叠,即模型「一路向下」,去套用别的模型来拆解并解决任务。
除了AutoGPT、BabyAGI这些,还有ViperGPT、SayCan和ToolKit等最新工具,以及前面微软发布的VisualGPT和HugginGPT,都差不多是这个思想。
注意:这里如果问题复杂,消耗openai的token有点多。

图片


作者:周末程序猿
链接:https://juejin.cn/post/7221461913003442236

posted @ 2024-04-19 15:46  bonelee  阅读(18)  评论(0编辑  收藏  举报