基于 LangChain 和 ReAct 模式的智能舆情分析 Agent,支持从用户自然语言查询到生成完整 HTML 报告的端到端流程。
- 🤖 ReAct Agent:采用 Reasoning + Acting 模式,智能决策和执行工具调用
- 🔍 智能搜索词提取:从自然语言查询中提取检索关键词和配置
- 📊 多维度数据分析:支持时间线分析、情感倾向分析、数据统计
- 📄 HTML 报告生成:自动生成美观、交互式的舆情分析报告
- 💾 会话管理:支持会话保存、恢复和消息历史管理
- 📈 Token 追踪:实时追踪和统计 Token 使用情况
- 🎨 美观的 CLI 界面:基于 Rich 的现代化命令行界面,支持流式输出
- OpenAI:GPT-4o、GPT-4o-mini、GPT-4-turbo、o1-preview、o1-mini
- Google Gemini:Gemini Pro 系列
- 通义千问(Qwen):qwen-max、qwen-plus、qwen-turbo、qwen-coder
- DeepSeek:deepseek-chat、deepseek-reasoner
- Kimi(Moonshot):moonshot-v1-8k、moonshot-v1-32k、moonshot-v1-128k
用户查询
↓
搜索词提取 (extract_search_terms)
↓
数据采集 (data_collect)
↓
数据分析 (analysis_timeline / analysis_sentiment)
↓
报告生成 (report_html)
↓
HTML 报告输出
项目采用多模型架构,不同场景使用不同的模型:
- main(主流程):ReAct Agent 的底座,负责推理和工具调用决策
- tools(工具模型):用于搜索词提取、数据分析等工具调用
- report(报告模型):专门用于生成 HTML 报告
这种架构设计可以:
- 优化成本:主流程使用高性能模型,工具调用使用性价比更高的模型
- 提升性能:不同场景使用最适合的模型
- 灵活配置:可以根据需求为不同场景配置不同的模型
- Python >= 3.10
- 虚拟环境(推荐使用
venv)
# 创建虚拟环境(推荐)
python -m venv venv
# 激活虚拟环境
# Windows:
venv\Scripts\activate
# Linux/Mac:
source venv/bin/activate
# 安装依赖
pip install -r requirements.txtpip install -e .重要:使用 data_collect 工具需要安装 Playwright 浏览器驱动。
# 安装 Playwright 浏览器驱动(Chromium)
playwright install chromium
# 或者安装所有浏览器(可选)
playwright install注意:
- 首次安装需要下载浏览器驱动,可能需要几分钟时间
- 如果网络较慢,可以使用国内镜像:
# 设置环境变量使用国内镜像 export PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright playwright install chromium
# 运行工具列表脚本,查看已注册的工具
python scripts/list_tools.py
# 测试搜索词提取工具
python scripts/run_extract_search_terms.py
# 测试数据采集工具(需要先配置 NETINSIGHT_USER 和 NETINSIGHT_PASS)
python scripts/run_data_collect.py创建 .env 文件(在项目根目录),配置必要的 API Key 和账号信息:
# =============================================================================
# 模型 API Key(至少配置一个,根据 config/model.yaml 中的配置选择)
# 统一使用 APIKEY 命名(按 openai / gemini / qwen / deepseek 顺序)
# =============================================================================
# OpenAI(推荐用于主流程)
# 获取地址:https://platform.openai.com/api-keys
OPENAI_APIKEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Google Gemini
# 获取地址:https://makersuite.google.com/app/apikey
GEMINI_APIKEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# 通义千问(Qwen)- 使用 DashScope API Key
# 获取地址:https://dashscope.console.aliyun.com/apiKey
QWEN_APIKEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# 或者使用旧的 DASHSCOPE_APIKEY(兼容)
DASHSCOPE_APIKEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# DeepSeek
# 获取地址:https://platform.deepseek.com/api_keys
DEEPSEEK_APIKEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Kimi(Moonshot)
# 获取地址:https://platform.moonshot.cn/console/api-keys
KIMI_APIKEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# =============================================================================
# 网页搜索 API Key(可选,用于 extract_search_terms 工具)
# =============================================================================
# BoCha AI Search(中文场景推荐)
# 获取地址:https://www.bocha.cn/
BOCHA_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# =============================================================================
# NetInsight 登录信息(可选,用于 data_collect 工具)
# =============================================================================
# NetInsight 账号(用于数据采集)
NETINSIGHT_USER=your_username
NETINSIGHT_PASS=your_password
# =============================================================================
# Playwright 浏览器配置(可选)
# =============================================================================
# 控制 Playwright 是否显示浏览器窗口
# true = 无头模式(不显示浏览器,默认,适合生产环境)
# false = 显示浏览器窗口(便于调试和观察登录过程)
NETINSIGHT_HEADLESS=true配置说明:
-
模型 API Key:
- 至少需要配置一个模型 API Key,根据
config/model.yaml中的配置选择 - 默认配置使用
DEEPSEEK_APIKEY(main profile)和QWEN_APIKEY(tools/report) - 可以根据需要配置多个,然后在
model.yaml中选择使用
- 至少需要配置一个模型 API Key,根据
-
网页搜索:
BOCHA_API_KEY用于extract_search_terms工具进行网页搜索- 如果不使用该工具,可以不配置
-
NetInsight:
NETINSIGHT_USER和NETINSIGHT_PASS用于data_collect工具登录- 如果不使用数据采集功能,可以不配置
NETINSIGHT_HEADLESS控制浏览器是否显示,调试时可设为false
-
安全提示:
- 请妥善保管 API Key,不要泄露给他人
.env文件已添加到.gitignore,不会被提交到版本控制- 如果 API Key 泄露,请立即在对应平台重新生成
项目使用 config/model.yaml 配置文件来管理不同场景下的模型选择:
# 主流程模型:作为 ReAct Agent 的底座
main:
provider: deepseek
model: deepseek-chat
api_key_env: DEEPSEEK_APIKEY
# 工具模型:用于各种工具调用(搜索词提取、时间线分析、情感分析等)
tools:
provider: qwen
model: qwen-plus
api_key_env: QWEN_APIKEY
# HTML报告生成模型:生成舆情分析HTML报告
report:
provider: qwen
model: qwen-plus
api_key_env: QWEN_APIKEY- 主流程模型(main)不建议使用 Qwen:LangChain 包装的 Qwen 模型在处理会话恢复时可能存在消息序列问题,导致无法正确加载之前的对话历史。建议主流程模型使用 OpenAI(如
gpt-4o-mini)或 DeepSeek,其他场景(tools、report)可以使用 Qwen。 - 如果必须使用 Qwen 作为主流程模型,请确保会话恢复功能正常工作,或考虑使用 OpenAI/DeepSeek 作为替代方案。
项目使用 config/prompt.yaml 配置文件来管理提示词模板:
# Agent 底座 system prompt
system_prompt: system_prompt.txt
# 意图/搜索词提取:供 extract 模型使用
extract_search_terms_prompt: extract_search_terms.txt
# 事件时间线分析:供 analysis 模型使用
analysis_timeline_prompt: analysis_timeline.txt
# 情感倾向分析:供 analysis 模型使用
analysis_sentiment_prompt: analysis_sentiment.txt
# HTML报告生成:供 report 模型使用
report_html_prompt: report_html.txt提示词模板文件位于 prompt/ 目录下,可以根据需要进行修改。
# 启动交互式 CLI(推荐)
sona
# 或
sona interactive
# 查看帮助
sona --help在交互式界面中,可以使用以下命令:
/new- 开启新的分析会话/memory- 查看并恢复之前的会话/models- 查看所有模型配置/tools- 查看所有可用工具/clear- 清除 memory 和 sandbox/exit- 退出程序
-
启动程序:
sona
-
创建新会话:
user: /new -
输入查询:
user: 分析最近一周小米汽车的舆情 -
Agent 自动执行:
- 提取搜索词
- 采集数据
- 分析时间线和情感
- 生成 HTML 报告
-
查看结果:
- 工具执行结果会实时显示
- HTML 报告路径会在工具结果中显示
from agent.reactagent import stream
# 流式运行 Agent
for chunk in stream("分析最近一周小米汽车的舆情", task_id="task-001"):
# 处理每个状态更新
if isinstance(chunk, dict):
chunk_type = chunk.get("type")
if chunk_type == "token":
# Token 级别的流式输出
print(chunk.get("content"), end="", flush=True)
elif chunk_type == "tool_call":
# 工具调用
print(f"\n调用工具: {chunk.get('tool_name')}")
elif chunk_type == "tool_result":
# 工具结果
print(f"\n工具结果: {chunk.get('result')}")项目包含 6 个核心工具,Agent 会根据需要自动调用:
功能:从用户自然语言查询中提取用于舆情检索的搜索关键词和配置。
输入:
query:用户自然语言查询
输出:
eventIntroduction:事件基础介绍searchWords:搜索关键词列表timeRange:时间范围(开始时间、结束时间)
使用时机:Agent 首先调用此工具,从用户查询中提取检索配置。
功能:根据搜索矩阵和时间范围循环抓取微博渠道的舆情数据。
输入:
searchMatrix:搜索矩阵(包含多个搜索词及其对应的数量)timeRange:时间范围(开始时间、结束时间)
输出:
result_file_path:采集结果 CSV 文件路径total_count:采集的数据总数
使用时机:在提取搜索词后,Agent 调用此工具采集舆情数据。
依赖:
- 需要配置
NETINSIGHT_USER和NETINSIGHT_PASS - 需要安装 Playwright 浏览器驱动
功能:查询不同搜索词在微博渠道的数据数量,并智能分配数量。
输入:
searchWords:搜索词列表timeRange:时间范围
输出:
search_matrix:包含每个搜索词及其分配数量的搜索矩阵
使用时机:在采集数据前,Agent 可能调用此工具查询数据数量并分配搜索词权重。
功能:从舆情数据中提取时间相关信息,生成事件时间线。
输入:
eventIntroduction:事件基础介绍dataFile:数据文件路径(CSV 格式)
输出:
result_file_path:时间线分析结果 JSON 文件路径timeline:事件时间线数据
使用时机:当热点事件可能包含时间线(跨度比较长)时,Agent 调用此工具分析时间线。
功能:从舆情数据中分析情感倾向,统计占比并总结主要观点。
输入:
eventIntroduction:事件基础介绍dataFile:数据文件路径(CSV 格式)
输出:
result_file_path:情感分析结果 JSON 文件路径sentiment_statistics:情感统计信息content_by_sentiment:按情感分类的内容
使用时机:一般均可使用本工具,Agent 会调用此工具分析情感倾向。
功能:根据分析结果生成美观、交互式的 HTML 舆情分析报告。
输入:
eventIntroduction:事件基础介绍analysisResultsDir:分析结果文件夹路径(包含所有分析结果的 JSON 文件)
输出:
html_file_path:生成的 HTML 文件路径file_url:本地文件访问地址(file:// 协议)
使用时机:当需要生成最终的 HTML 报告时,Agent 调用本工具。
特性:
- 使用 ECharts 进行数据可视化
- 响应式设计,适配不同屏幕尺寸
- 所有样式和脚本内嵌在 HTML 中,可直接在浏览器中打开
sona/
├── agent/ # ReAct Agent 实现
│ └── reactagent.py # Agent 核心逻辑,支持流式输出和会话管理
├── tools/ # 工具定义
│ ├── extract_search_terms.py # 搜索词提取
│ ├── data_collect.py # 数据采集(NetInsight)
│ ├── data_num.py # 数据数量查询
│ ├── analysis_timeline.py # 时间线分析
│ ├── analysis_sentiment.py # 情感倾向分析
│ └── report_html.py # HTML 报告生成
├── model/ # 模型管理
│ └── factory.py # 模型工厂,支持多模型配置
├── config/ # 配置文件
│ ├── model.yaml # 模型配置(main/tools/report)
│ └── prompt.yaml # 提示词配置
├── prompt/ # 提示词模板
│ ├── system_prompt.txt # Agent 系统提示词
│ ├── extract_search_terms.txt
│ ├── analysis_timeline.txt
│ ├── analysis_sentiment.txt
│ └── report_html.txt
├── cli/ # 命令行界面
│ ├── main.py # CLI 主入口
│ ├── interactive.py # 交互式会话管理
│ ├── display.py # 显示辅助函数(Rich)
│ ├── session_ui.py # 会话选择 UI
│ ├── models_ui.py # 模型配置 UI
│ └── tools_ui.py # 工具列表 UI
├── utils/ # 工具函数
│ ├── session_manager.py # 会话管理
│ ├── token_tracker.py # Token 追踪
│ ├── message_utils.py # 消息工具(格式转换、会话恢复、消息压缩)
│ ├── prompt_loader.py # 提示词加载
│ ├── path.py # 路径管理
│ └── env_loader.py # 环境变量加载
├── mcps/ # MCP 集成
│ └── web_search.py # 网页搜索 MCP
├── scripts/ # 脚本工具
│ ├── list_tools.py # 列出所有工具
│ ├── run_extract_search_terms.py
│ ├── run_data_collect.py
│ └── run_report_html.py
├── memory/ # 会话存储目录(自动创建)
├── sandbox/ # 任务工作目录(自动创建)
├── pyproject.toml # 项目配置
├── requirements.txt # 依赖列表
└── README.md # 本文档
A:
- 检查网络连接,确保能访问 Playwright 下载服务器
- 使用国内镜像(见上方安装指引)
- 手动下载:访问 Playwright 下载页面 查看详细说明
A: 请在 .env 文件中配置 NETINSIGHT_USER 和 NETINSIGHT_PASS 环境变量。
A: Playwright 会将浏览器驱动安装到用户目录:
- Windows:
%USERPROFILE%\AppData\Local\ms-playwright\ - Linux/Mac:
~/.cache/ms-playwright/
A: 设置环境变量 NETINSIGHT_HEADLESS=false,这样会显示浏览器窗口,便于观察登录过程。
A: 不建议。LangChain 包装的 Qwen 模型在处理会话恢复时可能存在消息序列问题,导致无法正确加载之前的对话历史。具体表现为:
- 恢复会话时出现
messages with role "tool" must be a response to a preceeding message with "tool_calls"错误 - 消息序列验证失败,导致会话无法正常恢复
建议配置:
- main(主流程):使用 OpenAI(如
gpt-4o-mini)或 DeepSeek(如deepseek-chat) - tools、report:可以使用 Qwen(如
qwen-plus)
如果必须使用 Qwen 作为主流程模型,请确保会话恢复功能正常工作,或考虑使用 OpenAI/DeepSeek 作为替代方案。
A: 在交互式界面中,每次工具执行完成后会自动显示 Token 使用情况。也可以在会话完成后查看总计 Token 使用量。
A: 会话数据存储在 memory/ 目录下,每个会话对应一个 JSON 文件。任务工作文件存储在 sandbox/{task_id}/ 目录下。
A: 在交互式界面中使用 /clear 命令,会清除 memory/ 和 sandbox/ 目录下的所有数据。
A: HTML 报告保存在 sandbox/{task_id}/结果文件/report_*.html,工具结果中会显示完整的文件路径和 file:// URL。
pytest tests/项目遵循 PEP 8 风格指南,使用类型注解增强代码可读性和类型安全性。
- 在
tools/目录下创建新的工具文件 - 使用
@tool装饰器定义工具函数 - 在
tools/__init__.py中导入并导出工具 - 在
agent/reactagent.py中注册工具到AGENT_TOOLS
- 在
model/factory.py中添加创建函数(如_create_xxx) - 在
_PROVIDER_CREATORS字典中注册提供商 - 在
_DEFAULT_API_KEY_ENV_BY_PROVIDER中添加默认环境变量名 - 更新
config/model.yaml配置示例
项目实现了自动消息压缩机制,当上下文 Token 数超过 max_context_tokens(默认 20000)时,会自动压缩旧消息,保留最新的对话内容。压缩后的摘要会显示给用户。
项目实现了细粒度的 Token 追踪机制:
- 按步骤追踪 Token 使用(agent_processing、tool_xxx 等)
- 实时显示每个步骤的 Token 消耗
- 累计统计总 Token 使用量
- 会话级别的 Token 使用记录
[添加许可证信息]
- LangChain - LLM 应用开发框架
- Rich - 美观的终端输出
- Playwright - 浏览器自动化
- ECharts - 数据可视化
Sona - 让舆情分析更智能、更简单 🚀