
Agentic Ai Revolution:构建为你工作的自主系统!
- Rifx.Online
- Generative AI , Large Language Models , AI Applications
- 05 Mar, 2025
介绍
生成式人工智能的兴起是数字时代的新平台转变。它解决了从大型企业的自动化到各种类型的研发和创造力的问题。预计到2024年,全球市场将超过650亿美元,86%的IT领导者预见到大型组织变革[1]。到目前为止,最大的回报来自于聊天机器人(更通用和丰富的用例)、代码助手和企业搜索。
投资持续流入人工智能,2024年投资达到138亿美元(比2023年增长六倍)[1]。此外,企业正在将人工智能嵌入到其核心战略和系统中。检索增强生成(RAG)、微调和针对垂直应用(例如,医疗、法律)的专用模型等技术正变得主流。
大语言模型(LLMs)引起了人们对人工智能的关注(以多种方式),并为解决旧问题开辟了新方法。这种新方法是通过代理人工智能——一个自主代理协作执行复杂的多步骤工作流程的框架。
我们的演示展示了如何工作和开发一个多代理系统。它集成了三个专用代理:
- 一个网页研究代理,用于获取和分析互联网数据。
- 一个转录和摘要代理,用于检索和浓缩视频或文本数据为可操作的摘要。
- 一个博客写作代理,将这些信息综合成一个连贯的结构。
这些代理在一个结构化的工作流程中操作。它们利用基础的大语言模型和日常企业堆栈中的现有工具。我们展示了组织如何简化任务、减少人力投入,并提高输出质量——同时保持对复杂场景的适应能力。
图1:多代理系统(作者与DALL-E提供的图像)
如往常一样,代码可在我们的GitHub上获取。
AI Agents: 它们是什么?
AI代理通常由大语言模型驱动,是旨在自主行动以实现特定目标的系统。它们接收输入提示并可以访问完成某些任务所需的工具集。
输入提示可以采取多种形式。它可以是人类给出的简单文本提示,并附有指示,例如 “写一篇关于AI代理的博客文章。” 在多代理系统(MAS)中,它可以是前一个代理的输出,这也可以是文本或更结构化的数据,如JSON。
代理可以访问的工具对于其成功至关重要(类似于人类)。例如,如果厨师没有工作中的烤箱,他们就无法烹饪出美味的烤肉。在AI代理的情况下,这些工具通常是允许它们连接到其他系统以执行任务的应用程序接口。例如,连接到搜索引擎以查找信息或连接到数据库以运行查询。
在构建这些类型的代理时,需要定义两个主要类别 [2]:
-
代理(具有四个主要组件):
- 代理使用的大语言模型可以是封闭源代码的,如GPT-4或Claude Sonnet,或是开源的,如LLaMA 3.3或Mixtral 8x22。大语言模型接收我们也应该相应设置的参数,例如温度或生成的最大令牌数。选择大语言模型将取决于代理需要执行的任务。例如,虽然GPT-4具有良好的推理能力,但Claude Sonnet在编码方面表现更好,而GPT-4o-mini是最快的。另一方面,如果处理的是敏感信息,可能会选择开源模型以避免与第三方公司共享信息。
- 代理的角色定义了其职责,提供目的并指导代理完成预期的任务和行为。例如,代理的角色可以是处理和分析信息、从数据库中检索数据或协调其他代理之间的互动。
- 背景故事定义了代理对其环境、职责和与其他代理或工具的互动的当前知识。它还定义了代理的当前意图,即代理根据其对环境的知识和目标计划要做的事情。
- 目标是代理预期实现的内容,通常转化为代理的输出。例如,如果代理负责从数据库中检索数据并回答用户的问题,则其目标是获得答案,输出就是答案。
-
任务(具有三个主要组件):
- 描述提供了对需要完成的任务的详细解释,清晰地定义了任务的性质和结果。它还提供了代理可能面临的具体指示和限制。例如,如果任务是从数据库中检索数据,则描述必须指定检索参数和任何格式要求。
- 输出描述了任务结果应如何呈现,通过设定对输出的明确期望。它可以指示输出应为文本、JSON、列表、HTML、SQL或来自应用程序接口的响应。
- 最后,代理负责执行任务。
虽然一个AI代理可以有效地执行特定任务,但只有在利用一组代理时,我们才能发挥其全部潜力。通过相互互动和协作,它们提供了扩展性和专业化,以解决复杂问题。下一部分将讨论这些多代理系统。
图2:代理和任务定义(作者提供的图片)
多代理协作系统 (MAS)
MAS 是由一组代理定义的,也称为 Crew。每个代理都具有独特的技能和专业能力。这些代理协作解决简单任务,以实现更大和更复杂的共同目标 [3]。
在 Crew 内部,每个代理都是一个具有独特特征、角色和特定工具的个体 LLM。与人类类似,这些代理通过将其任务的输出发送给后续代理进行沟通,以便进一步构建。
Crew 的结构可以根据代理之间的互动分为三种主要类型:
- 顺序型: 代理以链式方式工作,一个代理的输出是下一个代理的输入。通过解决较小的任务,他们可以解决为 Crew 设计的更大和更复杂的目标。
- 层级型: 通常由一个经理和多个下属组成,领导者的角色是委派、规划和管理任务的完成。下属执行领导者的指令。在这种情况下,我们可以让代理同时执行任务,因为并不是每个代理都有顺序依赖关系。
- 混合型: 这种结构在同一个 Crew 内部同时具有顺序和层级环境。通常发生在一些代理面对复杂任务时,将其拆分为较小的任务,并组建一个新的子 Crew。他们成为该子 Crew 的领导者,同时也是原 Crew 的下属。
图 3:多代理系统/Crew 可能的结构(图片由作者提供)
CrewAI: 创建一个多代理系统以撰写博客文章
在本节中,我们将创建一个多代理系统(MAS),以撰写关于人工智能代理的博客文章(我们知道让人工智能代理撰写关于人工智能代理的文章听起来有些令人困惑,但请耐心等待),使用该领域中最流行的包之一,CrewAI。图4展示了我们方法的完整架构:
图4:代理架构(作者提供的图片)
我们的团队由三个具有不同任务的代理组成,它们协作生成HTML格式的博客文章。这些代理是:
网页研究代理
负责连接到一个名为 SearXNG 的搜索引擎,并检索有关 AI Agents 的有用且最新的YouTube URL。代理及其任务定义如下:
researcher:
role: >
{topic} 高级数据研究员
goal: >
发现 {topic} 的前沿发展
backstory: >
你是一位经验丰富的研究员,擅长发现 {topic} 的最新发展。
以找到最相关的信息并以清晰简明的方式呈现而闻名。
research_task:
description: >
对 {topic} 进行彻底研究
确保找到任何有趣且相关的YouTube链接,当前年份为2024年。
expected_output: >
一个包含关于 {topic} 的YouTube URL列表及其相关描述
其中包含关于 {topic} 的最相关信息。忽略任何不以 "https://www.youtube.com" 开头的链接。
agent: researcher
转录和摘要代理
连接到 YouTube API 以从 网页研究代理 提供的URL检索转录。它总结转录内容,提取主要见解和参考,并根据视频内容提出建议。如下所示,代理及其任务定义如下:
summarizer:
role: >
{topic} 摘要生成器
goal: >
从 {topic} 中总结和提取知识及其他有见地和有趣的信息
backstory: >
你是一位分析信息的专家,能够以简洁的方式提取最重要和有见地的信息。
你以总结和检索事实、参考、引用而闻名,并推荐关于 {topic} 的最有用和令人惊讶的信息。
summarize_task:
description: >
彻底分析关于 {topic} 的信息,以提取最有价值的见解、事实和建议。
在从输入内容中提取信息时严格遵循提供的模式。
确保输出与字段描述、类型和约束完全匹配。忽略任何不以 "https://www.youtube.com" 开头的链接。
expected_output: >
一个包含 {topic} 摘要的JSON,以及最有价值的见解、事实和建议。还要将
YouTube链接作为参考添加。
agent: summarizer
博客写作代理
是我们团队的第三个也是最后一个代理。它利用 转录和摘要 生成的摘要来创建关于该主题的HTML格式博客文章。此HTML必须具有专业外观,包括导航栏,以帮助读者浏览文章。代理及其任务定义如下:
blog_writer:
role: >
{topic} 博客写作员
goal: >
根据 {topic} 研究结果创建详细的博客文章
backstory: >
你是一位细致入微的作家,善于关注细节。
你以将复杂主题转化为清晰简明的博客文章而闻名,
使他人能够轻松理解并采取行动。
write_task:
description: >
审查你获得的上下文,并将每个主题扩展为博客文章的完整部分。
确保博客文章详细且包含所有相关信息。
博客文章必须包含引言、主体、代码示例和结论部分。
expected_output: >
一篇完整的博客文章,主要主题每个都作为完整的信息部分呈现。
将其格式化为HTML,不使用 '\`\`\`'。使其看起来像一个专业的技术博客网站,
包括导航栏、菜单和样式。将YouTube链接作为可点击的参考整合到文本中,并放在最后。
agent: blog_writer
上述定义必须在两个不同的YAML文件中定义,一个用于代理(agents.yaml),另一个用于任务(tasks.yaml)。完成此过程后,便可以创建代理执行其任务所需的工具。
在我们的案例中,只有 博客写作代理 不需要任何工具,研究员 需要搜索引擎,而 转录和摘要 代理需要连接到YouTube API。
搜索引擎(SearXNG)
- 在定义工具时,定义输入模式是一种良好的实践。如下面的代码片段所示,我们的搜索引擎工具期望接收搜索查询和要检索的结果数量。
- 然后,我们必须定义工具本身。
__init__
函数设置要使用的搜索引擎,而_run
函数指定代理将如何使用该工具。它基本上搜索用户请求的主题的YouTube视频,在本例中为 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
- 此工具遵循相同的原则,首先定义输入模式,包括YouTube URL和我们希望转录的语言。
- 我们还定义了一个输出模式,其中不仅返回转录,还返回视频的时长。
- 最后,工具本身由从URL中提取视频ID并连接到YouTube API以检索转录组成,如
_run
函数所示。
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视频转录的工具。
属性:
input_schema (YouTubeTranscriptToolInputSchema): 输入数据的模式。
output_schema (You
```python
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]
定义了代理、任务和工具后,我们现在可以构建我们的 Crew 并设置它们的依赖关系。
如下所示,我们通过使用 `@agent` 装饰器声明代理,以及各自的工具和它们的组件(角色、目标和背景故事)。对于任务,我们使用 `@task` 装饰器并定义它们的组件(描述、输出和代理)。最后,我们定义它们如何协作,即它们以顺序方式工作 `Process.sequential`。
```python
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 团队"""
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,
)
最后一步是让我们的代理合作撰写博客文章,通过启动我们的 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)
默认使用的 LLM 是来自 OpenAI 的 GPT-4o-mini;因此,必须将 OpenAI API 密钥设置为环境变量。我们还需要为 YouTube 设置 API 密钥(请查看此 链接 来创建您的密钥)和搜索引擎的 URL。我们的 .env
文件必须包含以下变量:
YOUTUBE_API_KEY=<YOUR KEY>
OPENAI_API_KEY=<YOUR KEY>
SEARXNG_BASE_URL=https://search.zaai.ai
运行脚本后,我们团队的输出将存储在名为 assets/
的文件夹中,下面可以看到它的截图:
图 5: 关于 AI Agents 的博客文章(作者提供的图片)
## 结论
在本文中,我们探讨了当前的热点话题:代理人工智能。
代理人工智能是行业向更自主和协作的工作流程转变的一种表现,无需人类干预。它承诺让人类摆脱无聊和简单的任务,使他们能够专注于更具增值的工作。
我们展示了一个简单的用例,其中一个多代理系统在没有人类干预的情况下生成了一篇博客文章。代理们在网上搜索内容,从最近的YouTube视频获取转录,构建想法,并生成了一个包含输出的HTML页面。我们现在可以使用这些代理来处理新的和更复杂的用例。例如,我们可以帮助客户使用文本和图像在网站上搜索产品,利用多模态能力。我们还可以为课程(教育)创建个性化的课程表,或审查文档并评估其合规性(法律)。
通过正确的投资和策略,人工智能将继续为生产力和创造力设定新的标准。可能性是无穷无尽的,现在正是探索它们的时机。
## 关于我
连续创业者和人工智能领域的领导者。我为企业开发人工智能产品,并投资于专注于人工智能的初创公司。
[创始人 @ ZAAI](http://zaai.ai/) | [LinkedIn](https://www.linkedin.com/in/luisbrasroque/)
## 参考文献
[1] Menlo Ventures. (2024). _企业中的生成式人工智能现状_. Retrieved from [https://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). _多代理协作:利用智能大语言模型代理的力量_. arXiv:2306.03314.
[3] Han, S., Zhang, Q., Yao, Y., Jin, W., Xu, Z., & He, C. (2024). _大语言模型多代理系统:挑战与开放问题_. arXiv:2402.03578.