Skip to content

探索 AI Agents:从理念到 Python 实际运用

作者:老余捞鱼

原创不易,转载请标明出处及原作者。

写在前面的话:本文主要介绍了如何利用人工智能代理(AI Agents)从概念到Python中的实际应用,以及如何构建一个内容创作工作流程,通过多个代理协作完成从视频分析到博客撰写的复杂任务,完成后也许这会改变你对人工智能及其能力的看法。


一、动机(Motivation)

正如一句谚语所说:单打独斗,我们走得更快。携手,我们走得更远。这也与 “没有人可以成为每个领域的专家 “这一理念有关。团队合作和有效的任务分配对于成就大事至关重要。
类似的原则也适用于大型语言模型(LLM)。我们可以将多个 LLM 或人工智能代理(AI Agents)结合起来,每个代理专门负责一个特定领域,而不是让一个 LLM 来处理复杂的任务。这种策略可以使系统更强大,结果质量更高。在本文中,您将了解到:

  • 什么是人工智能代理 AI Agents
  • 为什么值得考虑用它们来解决现实世界中的使用案例。
  • 如何从零开始创建完整的人工智能代理AI Agents 系统。

二、系统的一般工作流程

在开始进入编码环节之前,让我们先清楚地了解一下本文所构建系统的主要组成部分。

  • 工作流程共有四个代理,每个代理都有专门的技能。首先,向系统提交用户请求。
  • Agent 1Video Analyzer使用 YouTube 频道搜索等外部工具在互联网上进行深入研究,查找与用户请求相关的信息。该代理的结果将被发送到下一个代理进行进一步处理。
  • Agent 2 或博文撰写人blog post writer利用之前的结果撰写一篇全面的博文。
  • Agent 2 类似,Agent 3 和Agent 4 也分别在 LinkedIn 上发布了吸引人的帖子和推文。
  • 来自Agent 2 , Agent 3 , 和 Agent 4 的响应都被保存到不同的标记文件中,可供最终用户使用。


三、我们为什么要关注AI Agents,而不是单一的LLM?

LLM大多时候的任务只有一个目标:数据提取。在处理更复杂的多步骤任务时,这种方法的局限性就显而易见了。下面将对其中一些局限性进行说明:

3.1 任务执行的灵活性

  • 单一提示式 LLM 需要为每项任务仔细编写提示,而且当预期与最初的任务要求发生变化时,可能很难更新。
  • AI Agents可将这些复杂性分解为子任务,调整自己的行为,而不需要进行大量的提示工程。

3.2 任务连续性和情境保持

  • 单次提示的 LLM 可能会丢失以前互动的重要语境。这是因为它们主要是在单一对话回合的限制下运行。
  • AI Agents能够在不同的交互过程中保持上下文,每个代理都可以参考前一个代理的回应来完成他们应该完成的任务。

3.3 专业化与互动

  • 经过大量的微调后,Single prompted LLMs (单一提示式 LLM) 可能会拥有专门的领域知识,这可能会耗费大量的时间和财力。
  • 另一方面,AI Agents 可以设计为一组专业模型,每个模型专注于特定任务,如researcher , blog writer , social media expert 。

3.4 互联网接入

  • Single prompted LLMs(单一提示式 LLM) 依赖于预定义的知识库,而知识库可能不是最新的,从而导致幻觉或访问受限。
  • AI Agents可以访问互联网,提供更多最新信息,从而做出更好的决策。

四、建立内容创作工作流程

在本节中,我们将探讨如何利用代理工作流创建一个系统,在对用户的主题进行广泛研究后,撰写博客文章、LinkedIn 内容和 Twitter 帖子。

代码结构如下:

project
   |
   |---Multi_Agents_For_Content_Creation.ipynb
   |
  data
   |
   |---- blog-post.md
   |---- linkedin-post.md
   |---- tweet.md
  • 项目文件夹是根文件夹,包含数据文件夹和笔记本文件夹。
  • 数据文件夹目前是空的,但在执行整个工作流程后应包含以下三个标记符文件:blog-post.md、linkedin-post.md 和 tweet.md
  • 每个标记文件都包含相应代理执行任务的结果


五、代理创建角色和任务

既然我们已经在前面的章节中探讨了每个代理的角色,那么让我们来看看如何实际创建他们以及他们的角色和任务。

在此之前,让我们为更好地执行这些角色和任务设定先决条件。

5.1 先决条件

代码通过 Google Colab 笔记本运行,我们的使用案例只需要两个库:openai 和 crewai[工具],安装方法如下。

%%bash
pip -qqq install 'crewai[tools]'
pip -qqq install youtube-transcript-api
pip -qqq install yt_dlp

成功安装库后,下一步是导入以下必要模块:

import os
from crewai import Agent
from google.colab import userdata
from crewai import Crew, Process
from crewai_tools import YoutubeChannelSearchTool
from crewai import Task

每个代理都利用 OpenAI gpt-4o 模型,我们需要通过我们的 OPENAI API KEY 设置对模型的访问,如下所示:

OPENAI_API_KEY = userdata.get('OPEN_AI_KEY')
model_ID = userdata.get('GPT_MODEL')
os.environ["OPENAI_API_KEY"] = OPENAI_API_KEY
os.environ["OPENAI_MODEL_NAME"] = model_ID
  • 首先,我们使用内置的 userdata.get 函数从 Google colab secrets 中访问 OPEN_AI_KEY 和 GPT_MODEL。
  • 然后,我们使用 os.environ 函数设置了 OPEN AI KEY 和 gpt-4o 模型。
  • 完成以上两个步骤后,使用模型创建代理应该不会有任何问题。

5.2 代理及其作用

通过代理类,我们可以创建一个代理,主要提供以下属性:角色、目标、背景故事和记忆。

只有Agent 1 或者 Video Analyzer具有这些附加性:tools 和 allow_delegation 。

这些属性大多不言自明,但让我们来了解一下它们的含义。

  • role 角色就像职位名称,定义了代理的确切角色。例如:Agent 1 的角色 Topic Researcher(主题研究员)
  • 目标告诉代理它在角色中扮演什么角色
  • 背景故事更详细地阐述了代理人的角色,使其具体化
  • 记忆属性是一个布尔值。当设置为 “True“时,它允许代理记忆、推理并从过去的互动中学习。
  • 工具是代理执行任务时使用的工具列表
  • allow_delegation 是一个布尔值,表示是否必须将代理的结果委托给其他代理进一步处理。

现在,让我们创建每一个代理。但是在此之前,我们先设置好第一位代理需要使用的工具。

这是通过提供 @techwithzoum 句柄,使用 YouTubeChannelSearchTool 类实现的。

# The tool used by the topic researcher
youtube_tool = YoutubeChannelSearchTool(youtube_channel_handle='@techwithzoum')
  1. Agent 1 — Topic Researcher
topic_researcher = Agent(
    role='Topic Researcher',
    goal='Search for relevant videos on the topic {topic} from the provided YouTube channel',
    verbose=True,
    memory=True,
    backstory='Expert in finding and analyzing relevant content from YouTube channels, specializing in AI, Data Science, Machine Learning, and Generative AI topics.',
    tools=[youtube_tool],
    allow_delegation=True
)
  • 我们首先将代理的角色定义为Topic Researcher(主题研究员)
  • 然后,我们要求代理使用提供的 {topic} 查找提及该主题的相关视频。
  • 最后,我们的第一个代理被定义为使用 YouTube 搜索工具查找和分析人工智能、数据科学、机器学习和生成式人工智能主题相关内容的专家。

当前代理定义中的重要内容完全相同,只是属性值略有变化。一旦理解了这一点,下一个代理的定义就不需要解释了。

2. Agent 2 — Blog Writer

blog_writer = Agent(
    role='Blog Writer',
    goal='Write a comprehensive blog post from the transcription provided by the Topic Researcher, covering all necessary sections',
    verbose=True,
    memory=True,
    backstory='Experienced in creating in-depth, well-structured blog posts that explain technical concepts clearly and engage readers from introduction to conclusion.',
    allow_delegation=False
)

3. Agent 3 — LinkedIn Post Creator

# LinkedIn Post Agent
linkedin_post_agent = Agent(
    role='LinkedIn Post Creator',
    goal='Create a concise LinkedIn post summary from the transcription provided by the Topic Researcher.',
    verbose=True,
    memory=True,
    backstory='Expert in crafting engaging LinkedIn posts that summarize complex topics and include trending hashtags for maximum visibility.',
    allow_delegation=False
)

4. Agent 4 — Twitter Post Creator

twitter_agent = Agent(
    role='Twitter Content Creator',
    goal='Create a short tweet from the transcription provided by the Topic Researcher that capture key points and insights',
    verbose=True,
    memory=True,
    backstory='Specializes in distilling complex information into concise, impactful tweets that resonate with a tech-savvy audience.',
    allow_delegation=False
)

我们注意到,后三个代理都没有委托任务。这是因为其他代理没有处理它们的结果。现在,我们的代理已经准备好了解我们对他们的期望,这可以通过任务类来实现。

5.3 任务

人类在收到执行任务的指令后,就会执行任务,交付东西。代理也是如此,成功执行这些任务并取得成果所需的属性如下:

  • description 描述是对代理需要执行的任务的清晰描述。描述越清晰,模型的输出就越好;
  • expected_output 是对代理预期结果的文字描述;
  • agent代理是负责执行该特定任务的代理的占位符;
  • tools 工具的定义与角色部分的定义类似,并非每个代理都使用工具。在我们的案例中,只有主题研究员使用工具;
  • output_file 是文件名及其格式。只有需要将任务结果以文件形式(如 markdown)输出的代理才需要指定输出文件,在这种情况下,文件名可以是 Blog Writer 的 blog-post.md。

让我们深入了解每个代理的这些任务的 Python 实现。

  1. Agent 1 — Topic Researcher
research_task = Task(
    description="Identify and analyze videos on the topic {topic} from the specified YouTube channel.",
    expected_output="A complete word by word report on the most relevant video found on the topic {topic}.",
    agent=topic_researcher,
    tools=[youtube_tool]
)

2. Agent 2 — Blog Writer

blog_writing_task = Task(
    description=""" Write a comprehensive blog post based on the transcription provided by the Topic Researcher.
                    The article must include an introduction , step-by-step guides, and conclusion.
                    The overall content must be about 1200 words long.""",
    expected_output="A markdown-formatted of the blog",
    agent=blog_writer,
    output_file='./data/blog-post.md'
)

3. Agent 3 — LinkedIn Post Creator

linkedin_post_task = Task(
    description="Create a LinkedIn post summarizing the key points from the transcription provided by the Topic Researcher, including relevant hashtags.",
    expected_output="A markdown-formatted of the LinkedIn post",
    agent=linkedin_post_agent,
    output_file='./data/linkedin-post.md'
)

4. Agent 4 — Twitter Post Creator

twitter_task = Task(
    description="Create a tweet from the transcription provided by the Topic Researcher, including relevant hastags.",
    expected_output="A markdown-formatted of the Twitter post",
    agent=twitter_agent,
    output_file='./data/tweets.md'
)

对于每个代理,属性是不言自明的。

  • 第一个代理是后三个代理使用的原始文本数据;
  • 第二个代理是名为 blog-post.md 的标记文件;
  • 第三个代理也是一个名为 linked-post.md 的标记符文件;
  • 最后一个代理的名称与 tweets.md 相同。


六、运行代理

最后一个步骤将我们的代理作为一个团队进行协调,以正确执行其任务,具体如下:

my_crew = Crew(
    agents=[topic_researcher, linkedin_post_agent, twitter_agent, blog_writer],
    tasks=[research_task, linkedin_post_task, twitter_task, blog_writing_task],
    verbose=True,
    process=Process.sequential,
    memory=True,
    cache=True,
    max_rpm=100,
    share_crew=True
)
  • agents 代理对应于我们所有代理的列表;
  • tasks任务是每个代理要执行的任务列表;
  • 我们将 “verbose “设置为 “True”,以获得完整的执行轨迹;
  • max_rpm 是为避免速率限制,机组人员每分钟可执行的最大请求数;
  • 最后,share_crew 表示代理共享资源来执行任务。这相当于第一个代理与其他代理共享其响应。

在对代理进行协调后,就可以使用 kickoff 函数触发代理了,该函数的参数是输入字典。在此,我们将搜索我录制的关于 GPT3.5 图形微调的视频

topic_of_interest = 'GPT3.5 Turbo Fine-tuning and Graphical Interface'
result = my_crew.kickoff(inputs={'topic': topic_of_interest})

成功执行上述代码后,就会生成上述指定的三个标记符文件。以下是显示每个文件内容的结果。作为录制视频的人,这与教程中的内容完全一致。

博客代理并没有为用户提供百分之百的分步指导,让用户在不遇到问题的情况下执行代码,但它提供了对教程范围的一个很好的理解。在 LinkedIn 和 Twitter 上发布的帖子,效果非常好!您可以检查ai_agents_outputs 文件夹中所有文件的内容。


七、审慎评估代理策略

我对代理的上述评估是基于我个人对内容的熟悉程度。不过,在部署到生产中之前,需要一种更加客观和可扩展的评估方法,这一点至关重要。下面是一些有效评估这些AI agents(人工智能代理)的策略。

  • 基准测试可使用 GLUE 和 FLASK 等成熟数据集,评估每个代理在不同任务中的性能,以便与不同的先进模型进行标准化比较。
  • 事实准确性测量可评估代理对多个领域的各种问题做出事实性回答的能力。
  • 情境感知相关性评分可用于衡量代理响应与给定提示的吻合程度。

可以利用多种框架来执行这些评估,其中一些框架包括:

  • DeepEval 是一个开源工具,用于量化 LLM 在各种指标方面的性能。
  • MMLU(大规模多任务语言理解)是一个框架,可在零点击和单点击设置下对各种主题的模型进行测试。
  • OpenAI evals 也是一个评估 LLM 或任何使用 LLM 构建的系统的框架。


八、结论

本文简要介绍了如何利用人工智能代理来有效完成高级任务,而不是促使单个大型语言模型来执行相同的任务。

  1. 多代理协作的优势:相比于单一的LLM,多个AI代理可以更有效地处理复杂的多步骤任务,提供更灵活、连续性更强、专业化更高且更新的信息。
  2. AI代理的创建和角色定义:通过定义代理的角色、目标、背景故事和记忆等属性,可以创建出具有特定功能的AI代理。
  3. 任务的执行和输出:每个AI代理执行特定的任务,并将结果输出到不同的标记文件中,如博客文章、LinkedIn帖子和Twitter推文。
  4. AI代理的评估方法:为了确保AI代理的性能和准确性,需要采用基准测试、事实准确性测量和情境感知相关性评分等方法进行评估。
  5. 实践案例和代码示例:文章提供了具体的Python实现代码,展示了如何利用AI代理创建内容并实现自动化的内容创作工作流程。
  6. 对AI代理未来发展的展望:AI代理的应用有望改变人工智能及其能力的认知,并在未来的内容创作和自动化任务中扮演重要角色。


本文内容仅仅是技术探讨和学习,并不构成任何投资建议。
转发请注明原作者

Published inAI&Invest专栏

Be First to Comment

    发表回复