我是支持 LLMs 的 agentic flows 的粉丝。它们不仅能够实现更先进的 Text2Cypher 功能,还为各种语义层实现打开了大门。这是一种极其强大且非常灵活的方法。
在这篇博客文章中,我着手实现一种不同的代理类型。不同于传统的问答模式,这个代理被设计用来为特定行业的某个地区生成详细报告。该实现借助了crewAI,这是一个平台,能够使开发者轻松管理和协调AI代理。
三个成员组成了一个三人组
这个系统让三个代理协同工作,目的是提供一份全面的业务报告。
- 数据研究员专员:专注于为特定城市的组织收集和分析行业数据,提供有关公司数量统计、上市公司、总收入额以及表现最佳的组织的洞察。
- 新闻分析师专员:侧重于提取和总结有关相关公司的最新新闻,提供有关趋势、市场动向以及情绪分析的概要。
- 报告撰写专员:将研究和新闻洞察综合成结构清晰、可操作的Markdown报告,确保报告清晰准确,不添加任何未经证实的信息。
这些代理一起形成了一种方法,用于生成特定地点的行业报告。
代码在Github上找到。
数据集我们将使用Neo4j演示服务器上的_companies_数据库,其中包含了公司和个人以及关于一些组织的最新新闻的详细信息。这些数据是通过Diffbot API抓取的。
图模式
该数据集重点关注如投资者、董事会成员等细节及相关方面,非常适合用来展示生成行业报告,是极佳的资源。
# Neo4j 连接配置
URI = "neo4j+s://demo.neo4jlabs.com"
AUTH = ('companies', 'companies') # (公司名, 密码)
driver = GraphDatabase.driver(URI, auth=AUTH) # 创建与Neo4j数据库连接的驱动
首先,我们需要定义OpenAI密钥,因为在这篇文章里我们将使用GPT-4。
# 设置你的 OpenAI API 密钥
os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API 密钥: ")
# llm = LLM(model='gpt-4o', temperature=0)
知识图谱相关的工具
我们将从实现第一个工具开始,这个工具能使代理或LLM从特定城市内的特定行业中获取公司的关键统计数据。
industry_options = ["软件公司", "专业服务公司", "企业软件公司", "制造公司", "SaaS公司", "计算机硬件公司", "媒体和信息公司", "金融服务公司", "人工智能公司", "广告公司"]
class GetCityInfoInput(BaseModel):
"""MyCustomTool 输入模式说明"""
city: str = Field(..., description="城市名称")
industry: str = Field(..., description=f"行业名称,可选选项为:{industry_options},请从列表中选择。")
class GetCityInfo(BaseTool):
name: str = "查询特定城市的资料"
description: str = "当您需要在一个城市中查找特定行业信息时,可以使用这个工具。"
args_schema: Type[BaseModel] = GetCityInfoInput
def _run(self, city: str, industry: str) -> str:
data, _, _ = driver.execute_query("""MATCH (c:City)<-[:IN_CITY]-(o:Organization)-[:HAS_CATEGORY]->(i:IndustryCategory)
WHERE c.name = $city AND i.name = $industry
WITH o
ORDER BY o.nbrEmployees DESC
RETURN count(o) AS organizationCount,
sum(CASE WHEN o.isPublic THEN 1 ELSE 0 END) AS publicCompanies,
sum(o.revenue) AS combinedRevenue,
collect(CASE WHEN o.nbrEmployees IS NOT NULL THEN o END)[..5] AS topOrganizations""", city=city, industry=industry)
# 前五名的组织
return [el.data() for el in data]
GetCityInfo 工具可以获取特定行业在某个城市中的公司关键统计数据。它提供了诸如组织总数、上市公司的数量、总营业收入以及员工人数最多的前五家公司的详情等信息。此工具可以进一步扩展,但为了简化,我保持它简单。
第二个工具可以帮您获取到关于特定某个公司的最新资讯:
class GetNews(BaseTool):
name: str = "获取特定公司的最新新闻"
description: str = "当你想获取特定公司的最新新闻时,可以使用此工具"
def _run(self, company: str) -> str:
data, _, _ = driver.execute_query("""MATCH (c:Chunk)<-[:HAS_CHUNK]-(a:Article)-[:MENTIONS]->(o:Organization)
WHERE o.name = $company AND a.date IS NOT NULL
WITH c, a
ORDER BY a.date DESC
LIMIT 5
RETURN a.title AS title, a.date AS date, a.sentiment AS 情感, collect(c.text) AS 内容片断""", company=company)
return [el.data() for el in data]
GetNews 工具可以获取有关特定公司的最新新闻。它提供诸如文章标题、发布日期、情感分析结果以及文章的关键摘录等详细信息。此工具非常适合了解与特定组织相关的近期发展和市场趋势,帮助我们生成更详细的总结。
代理正如之前提到的,我们将实现三个代理程序。因此,对于crewAI来说,只需进行最少的提示设计,因为平台会处理其余部分。
这些代理的实现如下所示:
# 定义代理
class ReportAgents:
def __init__(self):
self.researcher = Agent(
role='数据研究员',
goal='收集关于特定城市和行业中具体公司的全面信息',
backstory="""你是一位精通商业生态系统及城市人口统计的数据研究员。你擅长分析复杂的数据关系网。""",
verbose=True,
allow_delegation=False,
tools=[GetCityInfo()],
llm=llm
)
self.news_analyst = Agent(
role='新闻分析师',
goal='查找并分析有关指定行业和城市的相关公司的近期新闻动态',
backstory="""你是一位资深新闻分析师,精通商业新闻和市场研究。你能从新闻文章中识别关键趋势和动态。""",
verbose=True,
allow_delegation=False,
tools=[GetNews()],
llm=llm
)
self.report_writer = Agent(
role='报告撰写人',
goal='结合提供的研究和新闻分析,撰写全面且结构清晰的报告。不要包含任何未明确提供的信息。',
backstory="""你是一位专业报告撰写人,具有商业智能和市场分析经验。你擅长将信息提炼成清晰且可操作的见解。不要包含任何未明确提供的信息。""",
verbose=True,
allow_delegation=False,
llm=llm
)
在 crewAI 里,代理通过定义他们的角色、目标和背景来设定,可以使用可选工具来增强其能力。在这个设定中,有三个代理角色:一个负责使用 GetCityInfo
工具收集特定城市和行业中公司相关的信息的数据研究者;一个使用 GetNews
工具分析近期相关公司新闻的新闻分析员;以及一个将收集到的信息和新闻综合成结构化且具有操作性的报告的报告写手,无需借助外部工具。这种明确的角色和目标定义让这些代理可以更好地合作。
除了定义这些代理之外,我们还需要概述他们将要完成的任务。在这种情况下,我们将定义三个不同的任务如下:
# 定义任务
city_research_task = Task(
description=f"""研究和分析 {city_name} 及其在 {industry_name} 行业中的商业生态系统:
1. 获取城市概述和关键信息
2. 查找指定行业的组织
3. 分析商业关系和经济指标""",
agent=agents.researcher,
expected_output="给定城市和行业中公司的基本统计数据及表现突出者"
)
news_analysis_task = Task(
description=f"""分析城市研究员提供的有关公司的近期新闻""",
agent=agents.news_analyst,
expected_output="公司最近新闻的摘要及其可能对市场的影响",
context=[city_research_task]
)
report_writing_task = Task(
description=f"""根据城市研究和新闻分析任务的结果,编写详细的Markdown报告。
不要包含未提供的信息""",
agent=agents.report_writer,
expected_output="Markdown摘要",
context=[city_research_task, news_analysis_task]
)
这些任务是根据代理人的能力范围设计的。城市研究任务侧重于分析指定城市和行业的商业生态系统,以收集关键统计数据并识别表现最佳的组织,由数据研究员负责。新闻分析任务则关注与这些公司相关的近期发展,总结关键趋势和市场影响,使用城市研究的输出结果,由新闻分析师完成。最后,报告撰写任务将前面任务的发现整合成一份全面的Markdown报告,由报告撰写人完成。
最后,我们就把这些都凑在一起。
# 创建并启动团队
crew = Crew(
members=[agents.researcher, agents.news_analyst, agents.report_writer],
tasks=[city_research_task, news_analysis_task, report_writing_task],
verbose="开启详细输出",
process="流程模式为顺序",
)
试试看!
city = "Seattle"
industry = "硬件行业"
report = 生成报告(city, industry)
print(report)
代理人的一些中间步骤在这里省略了一些细节步骤,无法一一列出,但整个过程大致如下:首先,从收集指定的行业的关键统计数据并识别相关公司开始,接下来是收集这些公司的最新资讯。
结果如下:
# 西雅图计算机硬件行业报告
## 概览
西雅图的计算机硬件公司行业包括24个组织,其中4家为上市公司。这些公司的总收入约为229.14亿美元。本报告将介绍该行业的表现最优秀的公司以及最近影响它们的发展动向。
## 最佳表现者
1. **微软公司**
- **收入**:1982.7亿美元(约238.27亿美元)
- **员工数**:221,000人
- **状态**:上市公司
- **使命**:赋能每一个人和组织,使其成就更大。
2. **英伟达公司**
- **收入**:269.7亿美元
- **员工数**:26,196人
- **状态**:上市公司
- **前身**:迈络思技术和Cumulus Networks
3. **F5 Networks**
- **收入**:26.95亿美元
- **员工数**:7,089人
- **状态**:上市公司
- **专注领域**:多云环境下的网络安全和应用交付
4. **Quest软件公司**
- **收入**:8.57415亿美元(约7.57415亿美元)
- **员工数**:4,055人
- **状态**:上市公司
- **总部位于加利福尼亚**
5. **SonicWall**
- **收入**:3.1亿美元(约2.1亿美元)
- **员工数**:1,600人
- **状态**:私人公司
- **专注领域**:网络安全
在西雅图的经济格局中,这些公司发挥了重要作用,促进了硬件行业的增长和创新。
## 最近的新闻和发展
- **微软公司**:面临其收购动视暴雪的法律挑战,这可能会影响其游戏市场的战略。
- **英伟达公司**:在中国GPU市场上强劲的需求,突显其在AI领域的关键作用,并可能增强其市场地位。
- **F5 Networks**:因其网络安全解决方案获得了认可,提升了其在业内的声誉。
- **Quest软件公司**:发布了一个新的数据智能平台,旨在提升数据的可访问性和AI模型的开发能力。
- **SonicWall**:经历了领导层变更,并发布了一份威胁报告,强调了其在网络安全增长和挑战方面的专注。
这些发展有望影响市场的动态、投资者的看法以及行业内的竞争策略。
请注意,示例数据集已经过时;我们不再定期更新新闻,请理解。
简单总结使用代理流程、Neo4j 和 crewAI 构建自动报告生成管道,展示了一种可能,即 LLMs 如何超越简单的问答互动。通过给多个代理分配专门任务并给他们配备合适的工具,我们可以组织一个动态探索的工作流程,从相关数据中提取信息,处理数据并形成有条理的见解。
通过这种方法,代理们合作来发现一个行业在一个特定城市的的关键数据,收集最新的新闻资讯,并将所有信息整合成一份精美的Markdown报告。这表明LLM可以被应用于创造性的多步骤流程中,从而实现更复杂的应用场景,例如自动化商业智能分析、数据驱动的内容创作等。
代码可在 GitHub 找到。
共同学习,写下你的评论
评论加载中...
作者其他优质文章