LangChain BabyAGI代理系统 | 豆包MarsCode AI刷题

73 阅读7分钟

LangChain 的 BabyAGI(Autonomous General Intelligence)是一个基于任务管理和智能执行的自适应代理系统,能够根据设定目标执行一系列任务,并在任务执行过程中生成、排序和执行新的任务。BabyAGI 系统的核心是任务链(Task Chain),包括任务生成、优先级排序和任务执行三个主要部分。此代理不仅能够处理输入的目标并根据任务之间的依赖关系自动调整任务顺序,还能根据反馈生成新的任务来推进目标的实现。以下是 BabyAGI 系统的详细解析。

1. 代理系统的结构与任务链

BabyAGI 是一个以任务链为核心的代理系统,分为三个主要任务链:

  • 任务生成链(Task Creation Chain) :这个链的职责是根据已完成任务的结果生成新的任务。这些新任务是动态的,基于当前任务的输出和全局目标进行生成,并且保证不会与尚未完成的任务重叠。通过这种方式,BabyAGI 可以在执行过程中不断扩展任务列表,以应对复杂和变化的目标需求。

    class TaskCreationChain(LLMChain):
        """负责生成任务的链"""
    
        @classmethod
        def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
            """从LLM获取响应解析器"""
            task_creation_template = (
                "You are a 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: {incomplete_tasks}."
                " 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 string split by \n."
            )
            prompt = PromptTemplate(
                template=task_creation_template,
                input_variables=[
                    "result", "task_description", "incomplete_tasks", "objective",
                ],
            )
            return cls(prompt=prompt, llm=llm, verbose=verbose)
    
  • 任务优先级链(Task Prioritization Chain) :该链负责对新生成的任务进行优先级排序,确保最关键的任务能够被优先执行。排序过程考虑了任务的重要性和目标的紧迫性,并且在任务列表中不丢失任何任务。

    class TaskPrioritizationChain(LLMChain):
        """负责任务优先级排序的链"""
    
        @classmethod
        def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
            """从LLM获取响应解析器"""
            task_prioritization_template = (
                "You are a 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:"
                " 1. First task"
                " 2. Second task"
                " Start the task list with number {next_task_id}."
            )
            prompt = PromptTemplate(
                template=task_prioritization_template,
                input_variables=["task_names", "next_task_id", "objective"],
            )
            return cls(prompt=prompt, llm=llm, verbose=verbose)
    
  • 任务执行链(Execution Chain) :任务执行链负责执行具体的任务。它不仅要根据目标和上下文生成执行步骤,还要在执行过程中考虑到已完成的任务,为当前任务提供相关背景信息。

    class ExecutionChain(LLMChain):
        """负责执行任务的链"""
    
        @classmethod
        def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
            """从LLM获取响应解析器"""
            execution_template = (
                "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:"
            )
            prompt = PromptTemplate(
                template=execution_template,
                input_variables=["objective", "context", "task"],
            )
            return cls(prompt=prompt, llm=llm, verbose=verbose)
    

2. 任务执行的流程

执行流程由以下几个主要步骤组成:

BabyAGI 系统的工作流程由以下几个步骤构成:

  • 任务初始化:首先,系统会创建并初始化第一个任务。例如,任务可以是一个简单的初始步骤,如“生成待办事项列表”。该任务被添加到任务列表中。

    def get_next_task(
        task_creation_chain: LLMChain,
        result: Dict,
        task_description: str,
        task_list: List[str],
        objective: str,
    ) -> List[Dict]:
        """Get the next task."""
        incomplete_tasks = ", ".join(task_list)
        response = task_creation_chain.run(
            result=result,
            task_description=task_description,
            incomplete_tasks=incomplete_tasks,
            objective=objective,
        )
        new_tasks = response.split("\n")
        return [{"task_name": task_name} for task_name in new_tasks if task_name.strip()]
    
  • 任务执行与反馈:每当一个任务完成时,系统会将任务的执行结果进行存储,并依据这些结果生成新任务。同时,系统会通过向量存储(如 FAISS)检索相似的历史任务,为当前任务提供上下文。

    def execute_task(
        vectorstore, execution_chain: LLMChain, objective: str, task: str, k: int = 5
    ) -> str:
        """Execute a task."""
        context = _get_top_tasks(vectorstore, query=objective, k=k)
        return execution_chain.run(objective=objective, context=context, task=task)
    
  • 任务优先级排序:在任务执行完毕后,系统会根据任务的优先级进行重新排序,确保最关键的任务始终优先执行。这一过程确保了 BabyAGI 在执行过程中始终聚焦于最重要的任务。

    def prioritize_tasks(
        task_prioritization_chain: LLMChain,
        this_task_id: int,
        task_list: List[Dict],
        objective: str,
    ) -> List[Dict]:
        """Prioritize tasks."""
        task_names = [t["task_name"] for t in task_list]
        next_task_id = int(this_task_id) + 1
        response = task_prioritization_chain.run(
            task_names=task_names, next_task_id=next_task_id, objective=objective
        )
        new_tasks = response.split("\n")
        prioritized_task_list = []
        for task_string in new_tasks:
            if not task_string.strip():
                continue
            task_parts = task_string.strip().split(".", 1)
            if len(task_parts) == 2:
                task_id = task_parts[0].strip()
                task_name = task_parts[1].strip()
                prioritized_task_list.append({"task_id": task_id, "task_name": task_name})
        return prioritized_task_list
    
  • 反馈循环与任务更新:随着任务的不断执行和反馈,系统会动态调整任务列表。这些调整可能包括重新排序任务、添加新任务或删除无关任务。该循环继续进行,直到满足最大迭代次数或目标完成。

3. 向量存储与任务相似性检索

在 BabyAGI 中,任务执行的上下文和任务结果是通过向量存储(VectorStore)进行管理和查询的。向量存储利用嵌入模型(如 DoubaoEmbeddings)将文本数据转化为数值向量,以便进行相似性搜索。

  • 任务的向量化:每个任务的执行结果会通过嵌入模型转换为向量,并存储在向量数据库中。这样,当执行新的任务时,系统可以通过查询相似的任务结果来为当前任务提供上下文。
  • 任务相似性检索:在任务执行过程中,系统会通过相似性搜索(similarity_search_with_score)获取与当前任务相关的上下文。这确保了任务执行时能够依据历史信息进行推理,而不是从头开始。
def _get_top_tasks(vectorstore, query: str, k: int) -> List[str]:
    """Get the top k tasks based on the query."""
    results = vectorstore.similarity_search_with_score(query, k=k)
    if not results:
        return []
    sorted_results, _ = zip(*sorted(results, key=lambda x: x[1], reverse=True))
    return [str(item.metadata["task"]) for item in sorted_results]

4. BabyAGI 的应用与迭代

BabyAGI 系统的强大之处在于其自适应性和迭代性。系统不仅能根据初始目标开始执行任务,还能在任务执行的过程中根据结果生成新的任务,并不断调整任务的优先级。这使得 BabyAGI 可以在没有外部干预的情况下持续执行和优化任务,直至目标达成。

# BabyAGI 主类控制器
class BabyAGI(Chain, BaseModel):
    """BabyAGI代理的控制器模型"""

    task_list: deque = deque()
    task_creation_chain: TaskCreationChain = Field(...)
    task_prioritization_chain: TaskPrioritizationChain = Field(...)
    execution_chain: ExecutionChain = Field(...)
    task_id_counter: int = Field(1)
    vectorstore: VectorStore = Field(init=False)
    max_iterations: Optional[int] = None

    # 其他方法包括任务管理、任务列表打印和执行

5. BabyAGI 的应用场景

BabyAGI 作为一种智能任务管理和执行系统,可以应用于多个领域,包括但不限于:

  • 自动化内容生成:如自动编写文章、生成报告等。
  • 信息抽取与处理:从大量文档中提取有用的信息,并根据需求生成新的任务进行分析或报告。
  • 自动化决策支持:在复杂的决策场景中,BabyAGI 可以根据历史决策和结果生成新的决策任务,并根据目标调整执行策略。

通过这种方式,BabyAGI 不仅能够自动化执行任务,还能基于反馈不断优化其行为,逐步完成更加复杂的任务。

6. 总结

LangChain 的 BabyAGI 系统展示了基于自适应任务管理和执行的智能代理模型。通过任务链的设计,BabyAGI 能够根据设定目标动态生成、执行和优化任务,持续推动目标的完成。向量存储的引入使得任务之间的依赖和历史信息得以高效存储和查询,进一步提升了系统的灵活性和智能化水平。