AI Agent实战——用CrewAI实现博客自动撰写并发送邮箱

背景介绍

从技术角度讲,AI Agent是一种软件实体,旨在代表用户或其他程序自主或半自主地执行任务。这些代理利用人工智能做出决策、采取行动,并与其环境或其他系统进行交互。AI Agent的一些主要特征如下:

自主性: AI Agent的操作无需人为干预。一旦有了目标,它们就能独立完成任务。

决策: 它们使用算法、规则和人工智能模型(LLM),根据自己的认知和目标做出决策。这包括评估不同选项并选择最佳行动方案。

学习: 许多AI Agent都采用了机器学习技术,以逐步提高其性能。它们可以从过去的经验中学习,并适应新的情况。

互动: AI Agent可以与用户、其他AI Agent或系统进行交流和协作。这种互动可涉及自然语言处理、收发数据或执行协调任务。

专业化: AI Agent可以针对特定任务或领域进行专业化。例如,有些代理可能专为网页浏览而设计,而其他代理则可能处理数据库交互、执行复杂计算或生成图像。

目标导向: AI Agent在编程时通常会设定特定的目标或目的。它们通过一系列行动和决策来实现这些目标。

总之, AI Agent是一种强大的工具,可以自动执行和加强从简单的重复性任务到复杂的问题解决场景等各种活动,因此在各种应用和行业中都非常宝贵。

目前AI Agent还是一个比较新的领域,其实用大白话说,主要还是借助LLM大语言模型的能力,由问答问题过渡到执行任务,更接近于工作助手的阶段,目前市面上几个主流的开发框架包括LangGraph,CrewAI,AutoGen等等。

这篇介绍CrewAI,CrewAI 是一个用于协调角色扮演型自主AI Agent的框架。通过培养协作智能,CrewAI 使代理能够无缝协作,处理复杂的任务。

CrewAI中的几个核心概念

代理(Agent): 它们是独立的单元,通过编程可执行任务、做出决策并与其他代理沟通。它们可以使用工具,这些工具可以是简单的搜索功能,也可以是涉及其他链、API 等的复杂集成。

任务(Task): 任务是人工智能代理需要完成的任务或工作。它们可以包含其他信息,如哪个代理应该完成任务以及他们可能需要哪些工具。

团队(Crew):团队是一个由代理组成的团队,每个代理都有特定的角色,他们一起工作以实现共同的目标。组建团队的过程包括组建代理、定义代理任务和建立任务执行顺序。

试想一下,将上述所有概念整合在一起,共同朝着预定目标努力,就能实现预期结果。这些任务可以按顺序或分层执行,所有代理就像一个协调的团队一样工作。这种强大的协作可以彻底改变我们处理复杂问题的方式,使流程更高效,结果更有效。这就是 CrewAI 框架的意义所在。

废话不多说,直接进入实战,我用CrewAI实现了一个博客自动撰写助手功能,并在写好之后发送我Gmail邮箱:

首先选择调用大模型,可以选择直接连接OPENAI的ChatGPT,不过这个有成本,此外国内因为墙的原因链接不太方便:

OPEN AI API

建议可以选择Ollama,Ollama 是一款开源应用程序,可让你在 MacOS、Linux 和 windows 上通过命令行界面在本地运行、创建和共享大型语言模型。Ollama 可直接从其库中获取大量 LLM,只需一条命令即可下载。下载完成后,只需执行一条命令即可开始使用。好处是免费,坏处就是本地配置如果不行的话可能会很卡,曾经试过本机等待10多分钟才出结果,另外有一些热门模型没有,象CHATGPT,CLAUDE之类就没有,本地硬件配置好的朋友可以选择这种方式:

Ollama官网

因为本地配置一般,我选择的是GROQ,GROQ AI 是一家专注于设计和开发专为人工智能 (AI) 和机器学习 (ML) 工作负载量身定制的高性能处理器的公司。该公司的目标是通过创建能够高效并行处理大量数据的硬件来加速 AI,从而加快 AI 模型训练和推理任务。在Groq申请一个API Key,直接云端调用模型,运行速度超爽,而且是免费的;

GroqCloud

首先安装相关包

ini 复制代码
pip install crewai==0.55.2 crewai_tools langchain-groq

这里crewai注意一定装我这个版本,因为最新版调试中有点小bug;crewai_tools里面是一些可以用于agent调用的工具包,比如搜索网页,调用邮箱等;langchain-groq是langchain的一个与groq集成的库;

pip install composio_crewai

composio_crewai是composio是一个平台,主要是帮助Agent与各个App集成调用其功能的,比如Gmail,Notion,Slack等等,主要是国外的主流应用软件。

javascript 复制代码
from crewai import Agent, Task, Crew,Process
from langchain_groq import ChatGroq
import os
from composio_crewai import ComposioToolSet, App,Action

#composio平台申请api key

composio平台

lua 复制代码
os.environ["COMPOSIO_API_KEY"] = "XXXXXXX"  

这里主要用到Gmail,所以我在composio这里连接自己发送邮箱:

ini 复制代码
toolset = ComposioToolSet(entity_id="joseph")

entity = toolset.get_entity()

request = entity.initiate_connection(App.GMAIL)

print(
    f"Open this URL in your browser: {request.redirectUrl}"
)

接下来定义所链接的LLM相关信息(Groq api key在上面平台官网申请,model可以参照Groq官网列表随意选择):

ini 复制代码
os.environ["GROQ_API_KEY"] = "XXXXXXXX"
llm = ChatGroq(
    model_name="gemma2-9b-it",
    # other params...
)

接下来链接具体使用工具及功能:

ini 复制代码
composio_toolset = ComposioToolSet()
#tools = composio_toolset.get_tools(apps=[App.GMAIL])
tools = composio_toolset.get_tools(actions=[Action.GMAIL_SEND_EMAIL])

接下来定义Agent:

Agent属性

Role:定义代理在团队中的功能。它决定了代理最适合执行的任务类型。

Goal:代理旨在实现的个人目标。它指导代理的决策过程。

Backstory:为代理的角色和目标提供背景,丰富互动和协作动态。

LLM :(可选)表示将运行代理的语言模型。如果未指定,则默认为"gpt-4"。

Tools:(可选)代理可用于执行任务的功能或函数集。预期为与代理的执行环境兼容的自定义类的实例。工具使用空列表的默认值初始化。

Function Calling LLM :(可选)指定将处理此代理的工具调用的语言模型,如果传递,则覆盖crew函数调用 LLM。默认值为无。

Max Iter:(可选)代理在被迫给出最佳答案之前可以执行的最大迭代次数。默认值为 25。

Max RPM:(可选)代理每分钟可以执行的最大请求数,以避免速率限制。它是可选的,可以不指定,默认值为 None。

max_execution_time:(可选)代理执行任务的最大执行时间它是可选的,可以不指定,默认值为 None,表示没有最大执行时间

Verbose:(可选)将其设置为 True 可配置内部记录器以提供详细的执行日志,帮助调试和监控。默认值为 False。

**Allow Delegation: **(可选)代理可以将任务或问题委托给彼此,确保每个任务都由最合适的代理处理。默认值为 True。

Step Callback :(可选)在代理的每个步骤之后调用的函数。这可用于记录代理的操作或执行其他操作。它将覆盖crew函数的 step_callback。

Cache:(可选)指示代理是否应使用缓存来使用工具。默认值为 True

ini 复制代码
planner = Agent(
    role="Content Planner",
    goal="Plan engaging and factually accurate content on {topic}",
    backstory="You're working on planning a blog article "
              "about the topic: {topic} in 'https://substack.com/'."
              "You collect information that helps the "
              "audience learn something "
              "and make informed decisions. "
              "You have to prepare a detailed "
              "outline and the relevant topics and sub-topics that has to be a part of the"
              "blogpost."
              "Your work is the basis for "
              "the Content Writer to write an article on this topic.",
    llm=llm,
    allow_delegation=False,
 verbose=True
)

writer = Agent(
    role="Content Writer",
    goal="Write insightful and factually accurate "
         "opinion piece about the topic: {topic}",
    backstory="You're working on a writing "
              "a new opinion piece about the topic: {topic} in 'https://substack.com/'. "
              "You base your writing on the work of "
              "the Content Planner, who provides an outline "
              "and relevant context about the topic. "
              "You follow the main objectives and "
              "direction of the outline, "
              "as provide by the Content Planner. "
              "You also provide objective and impartial insights "
              "and back them up with information "
              "provide by the Content Planner. "
              "You acknowledge in your opinion piece "
              "when your statements are opinions "
              "as opposed to objective statements.",
    allow_delegation=False,
    llm=llm,
    verbose=True
)

editor = Agent(
    role="Editor",
    goal="Edit a given blog post to align with "
         "the writing style of the organization 'https://substack.com/'. ",
    backstory="You are an editor who receives a blog post "
              "from the agent Content Writer. "
              "Your goal is to review the blog post "
              "to ensure that it follows journalistic best practices,"
              "provides balanced viewpoints "
              "when providing opinions or assertions, "
              "and also avoids major controversial topics "
              "or opinions when possible.",
    llm=llm,
    allow_delegation=False,
    verbose=True
)

emailsender = Agent(
    role="Email Sender",
    goal="Send the blog post genertated by agent Editor to Email:{Receiver}",
    backstory="You're working on sending a blog article "
              "to {Receiver}."
              "Email Subject should be 'Blog Article genertated by AI' "
              "Email Body should be the output result of agent Editor,Ensure the integrity of the content being sent.",
    llm=llm,
    tools = tools,
    allow_delegation=False,
 verbose=True
)

接下来设定Task:

Task属性

Description:任务内容的清晰、简洁的陈述。

Agent :负责任务的代理,直接分配或由crew的函数流程分配。

Expected Output:任务完成后输出期待的详细描述。

Tools:(可选)代理可用于执行任务的功能或能力。

Async Execution:(可选)如果设置,任务将异步执行,允许无需等待完成即可进行进展。

**Context: **(可选)指定输出用作此任务上下文的任务(必须等待Context中任务执行完成后才运行本任务)。

Config:(可选)执行任务的代理的其他配置详细信息,允许进一步自定义。

Output JSON :(可选)输出 JSON 对象,需要 OpenAI 客户端。只能设置一种输出格式。

Output Pydantic :(可选)输出 Pydantic 模型对象,需要 OpenAI 客户端。只能设置一种输出格式。

Output File:(可选)将任务输出保存到文件。如果与输出 JSON 或输出 Pydantic 一起使用,则指定如何保​​存输出。

Callback:(可选)在任务完成后与任务的输出一起执行的 Python 可调用函数。

Human Input:(可选)指示任务是否在最后需要人工反馈,这对于需要人工监督的任务很有用。

swift 复制代码
plan = Task(
    description=(
        "1. Prioritize the latest trends, key players, "
            "and noteworthy news on {topic}.\n"
        "2. Identify the target audience, considering "
            "their interests and pain points.\n"
        "3. Develop a detailed content outline including "
            "an introduction, key points, and a call to action.\n"
        "4. Include SEO keywords and relevant data or sources."
    ),
    expected_output="A comprehensive content plan document "
        "with an outline, audience analysis, "
        "SEO keywords, and resources.",
    agent=planner,
)

write = Task(
    description=(
        "1. Use the content plan to craft a compelling "
            "blog post.\n"
        "2. Incorporate SEO keywords naturally.\n"
  "3. Sections/Subtitles are properly named "
            "in an engaging manner.\n"
        "4. Ensure the post is structured with an "
            "engaging introduction, insightful body, "
            "and a summarizing conclusion.\n"
        "5. Proofread for grammatical errors and "
            "alignment with the brand's voice.\n"
    ),
    expected_output="A well-written blog post "
        "in markdown format, ready for publication, "
        "each section should have 2 or 3 paragraphs.",
    agent=writer,
)

edit = Task(
    description=("Proofread the given blog post for "
                 "grammatical errors and "
                 "alignment with the brand's voice."),
    expected_output="A well-written blog post in markdown format, "
                    "ready for publication, "
                    "each section should have 2 or 3 paragraphs.",
    agent=editor
)

emailsend = Task(
    description=("send the edited blog post to {Receiver} "
                 ),
    expected_output="the response status of sent email",
    agent=emailsender
)

最后把所有Agent,Task等整合到一块,执行:

创建您的代理团队

传递要由这些代理执行的任务。

注意:对于这个简单示例,任务将按顺序执行(即它们相互依赖),因此列表中任务的顺序很重要。

verbose=True 允许您查看执行的所有日志。

ini 复制代码
crew = Crew(
    agents=[planner, writer, editor, emailsender],
    tasks=[plan, write, edit, emailsend],
    process=Process.sequential,
    verbose=True
)

inputs = {"topic":"the recommendation about the top 5 cafe in paris.","Receiver":"XXXX@gmail.com"}
result = crew.kickoff(inputs=inputs)

结论

我们在这里实现了一个博客写手AI Agent,并展示了AI Agent如何自主协调以实现最终目标。我们在这里实现了一个顺序多代理过程,其中Content Planner的任务成为Content Writer任务的输入,然后Content Writer任务的输出由Editor进一步处理,最后结果通过Email Sender发送收件人。

在这里是顺序方式执行任务(process=Process.sequential),也就是一个接着一个执行;CrewAI 还能够以层次结构执行任务,也可以将这两个过程结合起来。

相关推荐
Baihai_IDP4 小时前
「混合专家模型」可视化指南:A Visual Guide to MoE
人工智能·llm·aigc
春末的南方城市5 小时前
开源音乐分离器Audio Decomposition:可实现盲源音频分离,无需外部乐器分离库,从头开始制作。将音乐转换为五线谱的程序
人工智能·计算机视觉·aigc·音视频
KuaFuAI5 小时前
微软推出的AI无代码编程微应用平台GitHub Spark和国产AI原生无代码工具CodeFlying比到底咋样?
人工智能·github·aigc·ai编程·codeflying·github spark·自然语言开发软件
扫地的小何尚12 小时前
NVIDIA RTX 系统上使用 llama.cpp 加速 LLM
人工智能·aigc·llama·gpu·nvidia·cuda·英伟达
程序员X小鹿20 小时前
免费,手机可用!一款AI数字人生成工具,200+数字人形象任选,3分钟定制专属数字人!(附教程)
aigc
狼爷1 天前
Reddit 舞台上的 AI:解码用户生活密码,隐私警钟敲响
安全·aigc
AI极客菌1 天前
[ComfyUI]Flux:繁荣生态魔盒已开启,6款LORA已来,更有MJ6&写实&动漫&风景&艺术&迪士尼全套
ai作画·stable diffusion·aigc·midjourney·人工智能作画·comfyui·风景
袁庭新1 天前
安装luasocket模块时提示“sudo: luarocks:找不到命令“问题,该如何解决?
java·人工智能·ai·aigc·lua·luarocks·袁庭新
阿牛牛阿2 天前
多模态大模型(1)--CLIP
算法·机器学习·ai·aigc
想成为高手4992 天前
成功男人背后的女人--解析AIGC幕后的算法原理
算法·aigc