garyfeng / Auto-GPT

An experimental open-source attempt to make GPT-4 fully autonomous.
MIT License
0 stars 0 forks source link

Q: what does human feedback do? #5

Closed garyfeng closed 1 year ago

garyfeng commented 1 year ago

AutoGPT by default stops after each step for human input. You can simply type y to go on; internally the y response is translated into

            if console_input.lower().rstrip() == "y":
                user_input = "GENERATE NEXT COMMAND JSON"
                break

But if you actually type something, your response is incorporated into the memory:

        while True:
            console_input = utils.clean_input(Fore.MAGENTA + "Input:" + Style.RESET_ALL)
            if console_input.lower().rstrip() == "y":
                user_input = "GENERATE NEXT COMMAND JSON"
                break
            elif console_input.lower().startswith("y -"):
                try:
                    next_action_count = abs(int(console_input.split(" ")[1]))
                    user_input = "GENERATE NEXT COMMAND JSON"
                except ValueError:
                    print("Invalid input format. Please enter 'y -n' where n is the number of continuous tasks.")
                    continue
                break
            elif console_input.lower() == "n":
                user_input = "EXIT"
                break
            else:
                user_input = console_input
                command_name = "human_feedback"
                break

        if user_input == "GENERATE NEXT COMMAND JSON":
            logger.typewriter_log(
            "-=-=-=-=-=-=-= COMMAND AUTHORISED BY USER -=-=-=-=-=-=-=",
            Fore.MAGENTA,
            "")
        elif user_input == "EXIT":
            print("Exiting...", flush=True)
            break

Of course, if your input is EXIT, you kill the agent.

Question is, what does AutoGPT do with your 'human feedback'? It gets added to the memory:

    # Execute command
    if command_name is not None and command_name.lower().startswith( "error" ):
        result = f"Command {command_name} threw the following error: " + arguments
    elif command_name == "human_feedback":
        result = f"Human feedback: {user_input}"
    else:
        result = f"Command {command_name} returned: {cmd.execute_command(command_name, arguments)}"
        if next_action_count > 0:
            next_action_count -= 1

    memory_to_add = f"Assistant Reply: {assistant_reply} " \
                    f"\nResult: {result} " \
                    f"\nHuman Feedback: {user_input} "

    memory.add(memory_to_add)

Then what? Does AutoGPT then send memory_to_add to GPT as context for the next action?

garyfeng commented 1 year ago

Let's follow up memory.add(). This is in the folder memory, and we look at local.py. It seems that we take the memory_to_add as a string text, and get the embedding of text by get_ada_embedding(text). This embedding vector gets concatenated with previous embedding vectors.

    def add(self, text: str):
        """
        Add text to our list of texts, add embedding as row to our
            embeddings-matrix

        Args:
            text: str

        Returns: None
        """
        if 'Command Error:' in text:
            return ""
        self.data.texts.append(text)

        embedding = get_ada_embedding(text)

        vector = np.array(embedding).astype(np.float32)
        vector = vector[np.newaxis, :]
        self.data.embeddings = np.concatenate(
            [
                self.data.embeddings,
                vector,
            ],
            axis=0,
        )

        with open(self.filename, 'wb') as f:
            out = orjson.dumps(
                self.data,
                option=SAVE_OPTIONS
            )
            f.write(out)
        return text

The same function for pinecone.py is even simpler:

    def add(self, data):
        vector = get_ada_embedding(data)
        # no metadata here. We may wish to change that long term.
        resp = self.index.upsert([(str(self.vec_num), vector, {"raw_text": data})])
        _text = f"Inserting data into memory at index: {self.vec_num}:\n data: {data}"
        self.vec_num += 1
        return _text
garyfeng commented 1 year ago

You can use human feedback to basically chat with GPT. For example, in one of the tasks where I asked GPT to do research and write a business plan, it continued to 'research' endlessly. When it stopped for human feedback, I said "great work. Now write me the business plan". And it did. Then you can say "revise the business plan to provide more details", etc.