代理式 AI:从头开始构建自主系统
2026/5/14 17:20:43 网站建设 项目流程

原文:towardsdatascience.com/the-anatomy-of-an-autonomous-agent-499b42b73124

本文与 Rafael Guedes 共同撰写。

简介

生成式 AI 的兴起是数字时代的新平台变革。它解决了从大型企业自动化到各种类型的研发和创造力的问题。预计到 2024 年,全球市场将超过 650 亿美元,86%的 IT 领导者预计将出现大规模的组织变革[1]。迄今为止,最大的回报来自聊天机器人(更通用和丰富的用例)、代码协同飞行员和企业搜索。

投资持续流入 AI,2024 年投资了 138 亿美元(比 2023 年增长了六倍)[1]。此外,企业正在将 AI 嵌入到其核心战略和系统中。检索增强生成(RAG)、微调和针对垂直应用(例如医疗保健、法律)的专用模型等技术正在成为主流。

大型语言模型(LLMs)在多个方面引起了人们对 AI 的关注,并开启了以新方式解决旧问题的途径。这种新方式是通过代理式 AI——一个自主智能体协作执行复杂、多步骤工作流程的框架。

我们的演示展示了您如何工作和发展一个多智能体系统。它集成了三个专用智能体:

  • 一个网络研究员智能体,它摄取并分析互联网数据。

  • 一个转录和摘要智能体,它检索并浓缩视频或文本数据为可操作的摘要。

  • 一个博客撰写智能体,它将这些信息综合成一个连贯的结构。

这些智能体在结构化的工作流程中运行。它们利用基础 LLMs 和日常企业堆栈中的现有工具。我们展示了组织如何简化任务,减少人力,并提高输出质量——同时保持对复杂场景的适应性。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/bfb5f9f6f59e097f7d2348a52ccd780a.png

图 1:多智能体系统(作者与 DALL-E 共同创作)

如往常一样,代码可在我们的GitHub上找到。

AI 代理:它们是什么?

AI 代理,通常由 LLM 驱动,是设计为自主行动以实现特定目标的系统。它们接收一个输入提示,并有权访问完成某些任务所需的一组工具。

输入提示可以采取多种形式。它可以是一个人类给出的简单文本提示,包含要遵循的指令,例如“写一篇关于 AI 代理的博客文章。”在一个多智能体系统(MAS)中,它可以是前一个智能体的输出,这也可以是文本或更结构化的数据,如 JSON。

代理可以访问以执行任务的工具对于其成功至关重要(类似于人类)。例如,如果厨师没有正常工作的烤箱,他们就无法烹饪美味的烤肉。在 AI 代理的情况下,这些工具通常是 API,允许它们连接到其他系统以执行任务。例如,连接到搜索引擎以查找信息或数据库以运行查询。

当构建这类代理时,需要定义两个主要类 [2]:

  1. 代理(包含四个主要组件):
  • 代理使用的LLM可以是闭源如 GPT-4 或 Claude Sonnet,或开源如 LLaMA 3.3 或 Mixtral 8×22。LLM 接收我们应相应设置的参数,例如温度或产生的最大令牌数。LLM 的选择将取决于代理必须执行的任务。例如,虽然 GPT-4 具有良好的推理能力,但 Claude Sonnet 在编码方面表现更好,而 GPT-4o-mini 是最快的。另一方面,如果处理关键信息,可能会选择开源模型以避免与第三方公司共享信息。

  • 代理的角色定义了其责任,提供目的并指导代理通过其期望的任务和行为。例如,代理的角色可以是处理和分析信息,从数据库中检索数据,或协调其他代理之间的交互。

  • 背景故事定义了代理对其环境、责任以及与其他代理或工具的交互的当前知识。它还定义了代理的当前意图,即代理根据其对环境的了解和目标计划做什么。

  • 目标是代理预期要实现的内容,通常转化为代理的输出。例如,如果代理负责从数据库中检索数据并回答用户的问题,其目标是得到答案,输出就是答案。

  1. 任务(包含三个主要组件):
  • 描述提供了对任务性质和结果的详细解释,通过明确定义任务的性质和结果。它还提供了代理可能面临的特定指令和约束。例如,如果任务是检索数据库中的数据,则描述必须指定检索参数和任何格式要求。

  • 输出描述了任务结果应该如何呈现,通过设定对输出的明确期望。它可以指示结果应该是文本、JSON、列表、HTML、SQL 或 API 的响应。

  • 最后,代理负责执行任务。

虽然一个 AI 智能体可以有效地执行特定任务,但我们只能通过利用一组智能体来提取其全部潜力。通过相互交互和协作,它们提供了可扩展性和专业化来解决复杂问题。下一节将讨论这些 MAS。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/bd22f5391cf5a47c3dbcfd6bb7e7c0da.png

图 2:智能体和任务定义(作者提供)

多智能体协作系统(MAS)

MAS 由一组智能体定义,也称为 Crew。每个智能体都拥有独特的技能和专门的能力。这些智能体合作解决简单任务,以实现更大、更复杂的共同目标 [3]。

在 Crew 中,每个智能体都是一个具有独特特征、角色和特定工具的独立 LLM。类似于人类,这些智能体通过将任务输出发送给后续智能体以构建在它们之上来相互沟通。

根据智能体之间的交互,Crew 的结构可以根据三种主要类型进行分类:

  • 顺序型:智能体以链的形式工作,一个智能体的输出是下一个智能体的输入。通过解决较小的任务,它们可以解决 Crew 被设计来解决的更大、更复杂的任务。

  • 分层型:通常由一个经理和多个下属组成,领导者的角色是委派、计划和管理工作完成。下属执行领导者的指令。在这种情况下,我们可以有智能体同时执行任务,因为并非每个智能体都有顺序依赖性。

  • 混合型:这种结构在同一 Crew 中包含顺序和分层环境。通常发生在一些智能体手头有复杂任务时,将它们分解成更小的任务,并组建一个新的子 Crew,新的智能体成为该子 Crew 的领导者,同时又是原始 Crew 的下属。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/f42f195c5c8dc5f2f227c1c4cc93fc67.png

图 3:多智能体系统/Crew 可能的结构(作者提供)

CrewAI:创建一个 MAS 来撰写博客文章

在本节中,我们将创建一个多智能体系统(MAS)来撰写一篇关于 AI 智能体的博客文章(我们知道 AI 智能体撰写关于 AI 智能体的内容可能听起来有些令人困惑,但请耐心等待)使用这个领域中最受欢迎的包之一,CrewAI。图 4 展示了我们方法的完整架构:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/201301ca12b539b87050e68bfc2b0bbe.png

图 4:智能体架构(作者提供)

我们的 Crew 由三个具有不同任务的智能体组成,它们协作生成 HTML 格式的博客文章。这些智能体包括:

  • Web Researcher Agent负责连接到一个名为SearXNG的搜索引擎,并检索关于AI Agents的有用且最新的 YouTube 网址。该代理及其任务定义如下:
researcher:role:>{topic}Senior Data Researcher goal:>Uncover cutting-edge developmentsin{topic}backstory:>You're a seasoned researcherwitha knackforuncovering the latest developmentsin{topic}.Knownforyour ability to find the most relevant informationandpresent itina clearandconcise manner.research_task:description:>Conduct a thorough research about{topic}Make sure you findanyinterestingandrelevant youtube links given the current yearis2024.expected_output:>Alistwithyoutube URLs that cover{topic}andthe respective descriptionwiththe most relevant information about{topic}.Ignoreanylinks that don't startwith"https://www.youtube.com".agent:researcher
  • Transcriptor & Summarizer Agent连接到YouTube API,从Web Search Agent提供的 URL 中检索转录。它总结转录,提取主要见解和参考文献,并根据视频内容提出建议。如下所示,该代理及其任务定义如下:
summarizer:role:>{topic}Summarizer goal:>Summarizeandextract knowledgeandother insightfulandinteresting informationfrom{topic}backstory:>You're an expert on analyzing informationandextracting the most importantandinsightful informationina concise manner.You're knownforyour ability to summarizeandretrive facts,references,quotesandrecommend the most useful surprising information about the{topic}.summarize_task:description:>Analyse the information about the{topic}thoroughly to extract the most valuable insights,facts,andrecommendations.Adhere strictly to the provided schema when extracting informationfromtheinputcontent.Ensure that the output matches the field descriptions,typesandconstraints exactly.Ignoreanylinks that don't startwith"https://www.youtube.com".expected_output:>A jsonwitha summary of the{topic}andthe most valuable insights,facts,andrecommendations.Also add the youtube linksasreferences.agent:summarizer
  • Blog Writer Agent是我们团队的第三个也是最后一个代理。它利用Transcriptor & Summarizer生成的摘要,以 HTML 格式创建关于主题的博客文章。这个 HTML 必须具有专业的外观,包括一个导航栏,以帮助读者浏览文章。该代理及其任务定义如下:
blog_writer:role:>{topic}Blog Writer goal:>Create detailed blog posts based on{topic}research findings backstory:>You're a meticulous writerwitha keen eyefordetail.You're knownforyour ability to turncomplextopics into clearandconcise blog posts,making it easyforothers to understandandact on the information you provide.write_task:description:>Review the context you gotandexpand each topic into a full sectionfora blog post.Make sure the blog postisdetailedandcontainsanyandallrelevant information.The blog post must contain an introduction,a body,a code exampleanda conclusion section.expected_output:>A fully-fledged blog postwiththe main topics,each presentedasa complete section of information.Format itasHTML without using'```'.使其看起来像专业的技术博客网站, 包括一个导航栏、菜单和样式。将 YouTube 链接作为可点击的参考包含在内 文本,并在最后。 agent:blog_writer ```py The definitions above must be definedintwo different YAML files,oneforagents(*agents.yaml*)andanotherfortasks(*taks.yaml*).Once this process has been done,itistime to create the tools agents use to perform their tasks.In ourcase,only the**Blog Writer**doesnotneedanytool,the**Researcher**needs the search engine,whilethe**TranscriptorandSummarizer**needs the connection to the YouTube API.**Search Engine([SearXNG](https://search.zaai.ai))***Itisgood practice to define theinputschema when defining the tools.As showninthe code snippet below,our search engine tool expects to receive the search queryandthe number of results to retrieve.*Then,we must define the tool itself.The**`__init__`**function sets the search engine to use,whilethe `_run` function specifies how the agent will use the tool.It basically searches YouTube videos about the topic the user requested,inthiscase,*AI Agents*.

from crewai.tools import BaseTool

from typing import Type, Optional, List, Dict

from pydantic import BaseModel, Field, PrivateAttr

from langchain_community.utilities import SearxSearchWrapper

class SearxSearchToolInput(BaseModel):

"""SearxSearchTool 的输入模式。” query: str = Field(..., description="搜索查询。") num_results: int = Field(10, description="要检索的结果数量。")

class SearxSearchTool(BaseTool):

name: str = "searx_search_tool" description: str = ( "一个使用 Searx 元搜索引擎进行搜索的工具。" "指定一个查询,并可选择通过引擎、类别或结果数量进行限制。" ) args_schema: Type[BaseModel] = SearxSearchToolInput _searx_wrapper: SearxSearchWrapper = PrivateAttr() def __init__(self, searx_host: str, unsecure: bool = False): """使用 SearxSearchWrapper 初始化 SearxSearchTool。” super().__init__() self._searx_wrapper = SearxSearchWrapper( searx_host=searx_host, unsecure=unsecure ) def _run( self, query: str, num_results: int = 10, ) -> List[Dict]: """使用 Searx API 进行搜索。” try: results = self._searx_wrapper.results( query=query + " :youtube", num_results=num_results, ) return results except Exception as e: return [{"Error": str(e)}]
**YouTube API***This tool follows the same principle by first defining theinputschema,which consists of the YouTube URLandthe language we want the transcription to bein.*We also define an output schema wherenotonly the transcriptionisreturned but also the duration of the video.*Finally,the tool itself consists of extracting the video IDfromthe URLandconnecting to the Youtube API to retrieve the transcription,asseeninthe `_run` function.

from typing import Type, Optional

from pydantic import Field, BaseModel

from youtube_transcript_api import (

NoTranscriptFound, TranscriptsDisabled, YouTubeTranscriptApi,

)

from crewai.tools import BaseTool

class YouTubeTranscriptToolInputSchema(BaseModel):

""" 使用 YouTube 转录 API 获取 YouTube 视频转录的工具。 返回包含文本、开始时间和持续时间的转录。 """ video_url: str = Field( ..., description="要获取转录的 YouTube 视频的 URL。" ) language: Optional[str] = Field( None, description="转录的语言代码(例如,'en'表示英语)。" )

class YouTubeTranscriptToolOutputSchema(BaseModel):

""" YouTubeTranscriptTool 的输出模式。包含转录文本、持续时间、评论和元数据。 """ transcript: str = Field(..., description="YouTube 视频的转录文本。") duration: float = Field( ..., description="YouTube 视频的持续时间(秒)。" )

class YouTubeTranscriptTool(BaseTool):

""" 工具用于使用 YouTube 转录 API 获取 YouTube 视频的转录文本。 Attributes: input_schema (YouTubeTranscriptToolInputSchema): 输入数据的模式。 output_schema (YouTubeTranscriptToolOutputSchema): 输出数据的模式。 """ name: str = "youtube_transcript_tool" description: str = ( "一个用于执行 YouTube 转录提取的工具。" "指定 YouTube 视频的 URL 和可选的语言代码。" ) args_schema: Type[BaseModel] = YouTubeTranscriptToolInputSchema def __init__(self): """ 初始化 YouTubeTranscriptTool。 """ super().__init__() def _run( self, video_url: str, language: Optional[str] = None ) -> YouTubeTranscriptToolOutputSchema: """ 使用给定的参数运行 YouTubeTranscriptTool。 Args: video_url (list[str]): 要获取转录文本的 YouTube 视频 URL 列表。 language (Optional[str]): 转录的语言代码(例如,'en'表示英语)。 Returns: YouTubeTranscriptToolOutputSchema: 工具的输出,遵循输出模式。 Raises: Exception: 如果获取转录文本失败。 """ video_id = self.extract_video_id(video_url) try: if language: transcripts = YouTubeTranscriptApi.get_transcript( video_id, languages=[language] ) else: transcripts = YouTubeTranscriptApi.get_transcript(video_id) except (NoTranscriptFound, TranscriptsDisabled) as e: raise Exception( f"无法获取视频'{video_id}'的转录文本:{str(e)}" ) transcript_text = " ".join([transcript["text"] for transcript in transcripts]) total_duration = sum([transcript["duration"] for transcript in transcripts]) return YouTubeTranscriptToolOutputSchema( transcript=transcript_text, duration=total_duration, ) @staticmethod def extract_video_id(url: str) -> str: """ 从 YouTube URL 中提取视频 ID。 Args: url (str): YouTube 视频的 URL。 Returns: str: 提取的视频 ID。 """ return url.split("v=")[-1].split("&")[0]
With agents,tasks,andtools defined,we can now build our Crewandsettheir dependencies.As shown below,we declare the agents by using the `@agent` decorator,togetherwiththe respective toolsandtheir components(role,goalandbackstory).For tasks,we use the `@task` decoratoranddefine their components(description,outputandagent).Finally,we define how they should collaborate,i.e.,they workina sequential manner `Process.sequential`.

import os

from crewai import Agent, Crew, Process, Task

from crewai.project import CrewBase, agent, crew, task

from crew_zaai.src.crew_zaai.tools.searx import SearxSearchTool

from crew_zaai.src.crew_zaai.tools.youtube import YouTubeTranscriptTool

@CrewBase

class CrewZaai:

"""CrewZaai crew""" agents_config = "config/agents.yaml" tasks_config = "config/tasks.yaml" @agent def researcher(self) -> Agent: search_tool = SearxSearchTool( searx_host=os.getenv("SEARXNG_BASE_URL"), unsecure=False ) return Agent( config=self.agents_config["researcher"], tools=[search_tool], verbose=True ) @agent def summarizer(self) -> Agent: youtube_tool = YouTubeTranscriptTool() return Agent( config=self.agents_config["summarizer"], tools=[youtube_tool], verbose=True ) @agent def blog_writer(self) -> Agent: return Agent(config=self.agents_config["blog_writer"], verbose=True) @task def research_task(self) -> Task: return Task( config=self.tasks_config["research_task"], ) @task def summarizer_task(self) -> Task: return Task( config=self.tasks_config["summarize_task"], ) @task def write_task(self) -> Task: return Task( config=self.tasks_config["write_task"], output_file="assets/report.html" ) @crew def crew(self) -> Crew: """创建 CrewZaai 团队""" return Crew( agents=self.agents, tasks=self.tasks, process=Process.sequential, verbose=True, )@CrewBase

class CrewZaai:

"""CrewZaai 团队"""
The last stepisto make our agents work together to write the blog post by kicking off our Crew.

import sys

import warnings

from crew_zaai.src.crew_zaai.crew import CrewZaai

from dotenv import load_dotenv

warnings.filterwarnings(“ignore”, category=SyntaxWarning, module=“pysbd”)

load_dotenv()

inputs = {“topic”: “AI Agents”}

CrewZaai().crew().kickoff(inputs=inputs)

By default,the LLM usedisGPT-4o-minifromOpenAI;therefore,the OpenAI API key must besetasan environment variable.We also need tosetthe API keyforYouTube(check this[link](https://developers.google.com/youtube/v3/getting-started)to create your key)andthe URLforthe search engine.Our `.env`filemust contain the following variables:

YOUTUBE_API_KEY=

OPENAI_API_KEY=

SEARXNG_BASE_URL=https://search.zaai.ai

在运行脚本后,我们团队的输出存储在一个名为 `assets/` 的文件夹中,其截图如下: <https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/64b2be1f6cb64066ef34ae464a8fd301.png> 图 5:关于 AI 代理的博客文章(图片由作者提供) ## 结论 在这篇文章中,我们探讨了当前的热门话题:代理式人工智能。 代理式人工智能是行业向更自主和协作的工作流程转变,无需人工干预。它承诺将人类从无聊和简单的任务中解放出来,让他们能够专注于更有价值的任务。 我们展示了一个简单的用例,其中 MAS 在没有人工干预的情况下生成了一篇博客文章。代理在网络上搜索内容,从最近的 YouTube 视频中获取转录,构建想法,并生成一个包含输出的 HTML 页面。我们现在可以使用这些代理来处理新的和更复杂的应用场景。例如,我们可以帮助客户使用文本和图像在网站上搜索产品,利用多模态能力。我们还可以为课程(教育)创建个性化的课程表或审查文件并评估其合规性(法律)。 在正确的投资和策略下,人工智能将继续设定生产力和创造力的新标准。可能性是无限的,探索它们的时间就在现在。 ## 关于我 连续创业者和 AI 领域的领导者。我为商业开发 AI 产品,并对专注于 AI 的初创企业进行投资。 [ZAAI 创始人](http://zaai.ai/) | [LinkedIn](https://www.linkedin.com/in/luisbrasroque/) | [X/Twitter](https://x.com/luisbrasroque) ## 参考文献 [1] Menlo Ventures. (2024). *企业中生成式 AI 的现状*. 从 [`menlovc.com/2024-the-state-of-generative-ai-in-the-enterprise/`](https://menlovc.com/2024-the-state-of-generative-ai-in-the-enterprise/) 获取. [2] Talebirad, Y., & Nadiri, A. (2023). *多智能体协作:利用智能 LLM 代理的力量*. arXiv:2306.03314. [3] 汉斯,张琪,姚毅,金伟,徐振,和陈晨. (2024). *LLM 多智能体系统:挑战与开放问题*. arXiv:2402.03578.

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询