基于多智能体(Multi-Agent)的舆论危机模拟与决策支持系统
利用大语言模型驱动多个 AI 角色,在虚拟沙盘中模拟品牌危机事件中不同利益相关方(受害者、KOL、支持者)的舆论反应。系统支持多轮策略推演、实时情绪分析和立场演化追踪,帮助危机公关团队在决策前预演不同应对方案的效果。
| 功能 | 说明 |
|---|---|
| 多智能体仿真 | 受害者、KOL、品牌支持者等角色由 LLM 独立驱动,每个 Agent 拥有独立记忆、立场演化曲线和信任体系,角色间可引用和回应彼此发言 |
| RAG 知识增强 | ChromaDB 向量检索(余弦相似度)+ 搜狗/必应网络搜索,为智能体注入品牌背景、行业法规、历史案例和实时舆情数据 |
| 策略推演与对比 | AI 公关顾问自动生成 2 套候选策略及官方声明草稿(含策略理由),用户也可手写自定义声明,支持多轮推演观察策略长期效果 |
| 实时数据仪表盘 | 情绪分布(正面/负面/中立占比)、情绪趋势折线图、Agent 立场演化折线图,每轮结束后实时更新 |
| 5 大预设场景 | 涵盖食品安全、数据泄露、汽车召回、代言人塌房、大数据杀熟,共 33 个预设 Agent 角色 |
| 灵活角色编辑 | 支持运行时修改 Agent 的姓名、立场、影响力、发言风格和角色描述,也可添加自定义 Agent |
| 流式策略输出 | 策略生成过程通过 SSE 实时显示,无需等待完整响应 |
| 多 LLM 后端 | 工厂模式可插拔,支持 OpenAI 兼容接口 / Anthropic Claude / Ollama 本地部署,切换仅需修改 .env |
┌─────────────────────────────────────────────────────────────────────┐
│ 前端层 (Flask SPA) │
│ 暗色主题 UI · Chart.js 实时图表 · SSE 流式接收 · 轮询进度 │
└────────────────────────────┬────────────────────────────────────────┘
│ REST API + SSE
┌────────────────────────────▼────────────────────────────────────────┐
│ SimulationEngine 仿真引擎 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ asyncio.gather 并行驱动所有 PersonaAgent 反应 │ │
│ │ KOL 追加讨论轮 · 立场演化计算 · 记忆写入 · 统计汇总 │ │
│ └─────────────────────────────────────────────────────────────┘ │
├────────────────┬─────────────────────┬──────────────────────────────┤
│ DecisionAgent │ PersonaAgent × N │ SentimentAnalyzer │
│ 策略生成(SSE) │ 角色反应+立场更新 │ LLM分类 → 关键词回退 │
│ 策略反思 │ 记忆管理+信任计算 │ jieba 关键词提取 │
└────────┬───────┴──────────┬──────────┴──────────────────────────────┘
│ │
┌────────▼──────────┐ ┌───▼─────────────────────────────────────────┐
│ LLM Provider │ │ RAG Layer 知识增强层 │
│ ┌──────────────┐ │ │ ┌────────────────┐ ┌──────────────────┐ │
│ │ OpenAI Compat│ │ │ │ VectorStore │ │ DocumentProc │ │
│ │ Claude │ │ │ │ ChromaDB │ │ PDF/DOCX/TXT │ │
│ │ Ollama │ │ │ │ (cosine距离) │ │ 500字/80字重叠 │ │
│ └──────────────┘ │ │ └────────────────┘ └──────────────────┘ │
│ Semaphore(3) │ │ ┌────────────────┐ ┌──────────────────┐ │
│ 指数退避重试 │ │ │ WebSearcher │ │ knowledge_data │ │
│ max_tokens=1024 │ │ │ 搜狗+必应搜索 │ │ 预置知识库+舆情 │ │
└───────────────────┘ │ └────────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────┘
CrisisSim/
├── app.py # Flask 入口 + 完整前端 SPA (Jinja2 内嵌)
├── requirements.txt # Python 依赖
├── .env.example # 环境变量模板
├── run_streamlit.py # Streamlit 启动脚本 (备用)
│
└── crisis_sim/ # 核心 Python 包
├── __init__.py
├── config.py # 统一配置加载 (dotenv)
│
├── models/
│ └── schemas.py # Pydantic 数据模型定义
│
├── agents/
│ ├── base.py # Agent 基类: 记忆管理、立场追踪、信任体系
│ ├── persona.py # 角色 Agent: 角色扮演反应生成、立场更新算法
│ └── decision.py # 决策 Agent: 策略生成、声明草稿、效果反思
│
├── llm/
│ ├── provider.py # BaseProvider 抽象基类 (generate / generate_stream)
│ ├── factory.py # create_provider() 工厂函数
│ ├── openai_provider.py # OpenAI 兼容实现 (Semaphore + 重试)
│ ├── claude_provider.py # Anthropic Claude 实现
│ └── ollama_provider.py # Ollama 本地部署实现
│
├── engine/
│ └── simulation.py # 仿真引擎主循环 (初始化 → 轮次 → 汇总)
│
├── analysis/
│ └── sentiment.py # 情绪分析 (LLM + 关键词双路径) + 关键词提取
│
├── rag/
│ ├── document_processor.py # 文档分块与解析 (PDF/DOCX/TXT/MD/CSV)
│ ├── vector_store.py # ChromaDB 向量存储 (knowledge_base + opinions)
│ └── web_searcher.py # 网络搜索 (搜狗 + 必应)
│
└── scenarios/
├── presets.py # 5 大预设危机场景定义
└── knowledge_data.py # 每个场景的知识库 + 舆情种子数据
仿真引擎(SimulationEngine)是系统的核心调度器,负责管理整个仿真生命周期。
系统定义了 4 种角色类型,每种角色有独特的行为模式:
| 角色类型 | 枚举值 | 说明 | 行为特征 | 生成温度 |
|---|---|---|---|---|
| 受害者 | VICTIM |
消费者 / 当事人 / 维权人士 | 聚焦愤怒、焦虑和维权诉求,引用个人经历,遇道歉/赔偿会软化,遇推诿更愤怒 | 0.85 |
| 意见领袖 | KOL |
行业专家 / 媒体人 / 自媒体 | 理性分析,引用行业知识和历史案例,影响力高,拥有追加讨论轮 | 0.85(反应)/ 0.8(讨论) |
| 品牌支持者 | SUPPORTER |
忠实用户 / 行业观察者 | 倾向维护品牌,强调正面历史,从另一角度解读负面信息,语气友善但坚定 | 0.85 |
| 公关顾问 | DECISION |
系统级决策 Agent | 生成策略方案和官方声明,每轮结束后反思策略效果,全局唯一 | 0.7(策略)/ 0.5(反思) |
1. 发布官方声明
└─ DecisionAgent 生成官方消息 → 写入所有 Agent 记忆
│
2. 并行反应生成 (asyncio.gather)
├─ 每个 PersonaAgent 独立执行:
│ ├─ 查询 RAG: 知识库(3条) + 舆情(3条)
│ ├─ 构建上下文: 事件背景 + RAG + 记忆 + 近8条消息
│ ├─ LLM 生成反应 (temperature=0.85)
│ └─ 情绪分类 (LLM优先 → 关键词回退)
│
3. KOL 追加讨论
└─ KOL 类型 Agent 互看近4条消息 → 生成1-2句追加评论 (temperature=0.8)
│
4. 立场更新
└─ 所有 Agent 根据本轮消息计算立场偏移
│
5. 记忆写入
└─ 将其他 Agent 的消息写入短期记忆
│
6. 统计汇总
├─ 计算情绪分布 (正面/负面/中立占比)
└─ 记录所有 Agent 立场快照
│
7. 策略反思
└─ DecisionAgent 评估本轮策略效果 (temperature=0.5)
- 信号量限制:
asyncio.Semaphore(3),最多 3 个并发 LLM API 调用 - 重试策略(仅 OpenAI Provider):
RateLimitError:指数退避,等待2^attempt + 1秒(2s → 3s → 5s → 9s → 17s),最多 5 次APIConnectionError:固定等待 2 秒,最多 5 次
- Token 限制:所有 LLM 调用统一
max_tokens=1024
每个 Agent 维护一个滑动窗口短期记忆:
MemoryEntry {
round_number: int # 所属轮次
content: str # 消息内容
source_agent: str # 来源 Agent ID
sentiment: SentimentLabel # 情绪标签 (可选)
}
- 写入:每轮结束后将其他 Agent 的消息写入记忆
- 读取:取最近
MEMORY_WINDOW(默认 5)条记忆作为上下文 - 溢出保护:当记忆条数超过
MEMORY_WINDOW × 10(默认 50)时,截断为最近MEMORY_WINDOW × 5(默认 25)条 - 时间衰减:立场更新后,清除
round_number < 最新轮次 - MEMORY_WINDOW的过期记忆
Agent 立场是一个 [-1.0, +1.0] 的连续浮点值,每轮根据接收到的消息动态更新:
对于官方声明(is_official=True)— 基于关键词匹配:
正面关键词: ["道歉", "赔偿", "负责", "召回", "改进", "深表歉意", "立即"]
负面关键词: ["不存在", "没有证据", "夸大", "恶意", "竞争对手"]
delta = (正面命中数 × 0.15 - 负面命中数 × 0.20) × 权威度
对于其他消息 — 基于情绪值和信任度:
delta = (情绪分数 - 0.5) × 0.1 × 信任度 × 权威度
其中:
情绪分数: POSITIVE=1.0, NEUTRAL=0.5, NEGATIVE=0.0
权威度: 默认=0.5, KOL=0.8, 官方声明=1.0
信任度: KOL发送者=0.5, 其他=0.3 (可缓存)
立场描述映射:
| 立场值范围 | PersonaAgent 描述 | BaseAgent 描述 |
|---|---|---|
| < -0.6 | 强烈反对/愤怒 | — |
| -0.6 ~ -0.2 | 偏向负面/不满 | — |
| < -0.5 | — | 强烈反对 |
| -0.5 ~ -0.1 | — | 轻微反对 |
| -0.2 ~ 0.2 | 中立观望 | 中立 |
| 0.1 ~ 0.5 | — | 轻微支持 |
| 0.2 ~ 0.6 | 偏向正面/理解 | — |
| > 0.5 | — | 强烈支持 |
| >= 0.6 | 强烈支持/维护 | — |
输入:
- 危机场景上下文 (品牌 + 事件摘要)
- 当前轮次舆情统计 (正面/负面/中立消息占比)
- 历史策略与反思 (最近2轮)
Prompt 要求 LLM 返回 JSON 数组:
[
{
"strategy_id": "A",
"title": "策略标题 (5-10字)",
"description": "策略描述 (1-2句)",
"official_statement": "官方声明全文 (50-100字)",
"reasoning": "策略理由 (1-2句)"
},
{ ... }
]
输出: 2 套候选策略,流式输出 (SSE)
当 LLM 返回的 JSON 解析失败时,使用硬编码的降级策略:
- 策略 A:"诚恳道歉并承诺赔偿" — 通用道歉声明
- 策略 B:"技术性澄清与证据展示" — 技术检测报告声明
每轮结束后,公关顾问以 temperature=0.5 生成 3-5 句反思评估:
- 策略整体效果如何
- 哪些方面有效
- 哪些方面可能适得其反
- 下一步建议
反思结果会作为下一轮策略生成的输入,实现策略迭代优化。
系统使用 ChromaDB 内存模式,维护两个独立的向量集合:
| 集合 | 用途 | 距离度量 | 数据来源 |
|---|---|---|---|
knowledge_base |
品牌背景、行业法规、历史案例 | 余弦相似度 (cosine) | 预置知识库 + 用户上传文档 + 网络搜索 |
opinions |
舆情种子、用户评论、手动输入 | 余弦相似度 (cosine) | 预置舆情种子 + 网络搜索 + 手动输入 |
支持的文件格式与解析方式:
| 格式 | 解析器 | 说明 |
|---|---|---|
.pdf |
pypdf | 逐页提取文本,以 \n\n 拼接 |
.docx |
python-docx | 提取段落文本,以 \n\n 拼接 |
.txt / .md / .csv |
直接读取 | UTF-8 编码,忽略解析错误 |
分块策略:滑动窗口分块
CHUNK_SIZE = 500 字符
CHUNK_OVERLAP = 80 字符
步长 = 500 - 80 = 400 字符
示例:
Chunk 1: [0, 500)
Chunk 2: [400, 900)
Chunk 3: [800, 1300)
...
每块附带元数据:{"source": "来源标识", "chunk_id": 序号}
无需 API Key,直接抓取搜索引擎结果页:
| 引擎 | 优先级 | 搜索 URL | 防爬检测 |
|---|---|---|---|
| 搜狗 | 1 | sogou.com/web?query= |
检测 "antispider" 和页面长度 < 5000 |
| 必应 | 2 (回退) | bing.com/search?q=&mkt=zh-CN |
— |
提取数据:每条结果包含 title、snippet、url,HTML 标签通过正则 re.sub(r"<[^>]+>", "") 清除。
高级搜索接口:
search_event_news(keywords)— 搜索事件报道和评论,按前 30 字符去重search_brand_background(brand)— 搜索品牌介绍和争议新闻
每个场景包含 5-15 段专业知识,覆盖:
- 公司/品牌背景信息
- 行业市场规模与竞争格局
- 相关法律法规条款(精确到条文号)
- 历史危机案例及处理结果
- 危机公关最佳实践(如"黄金4小时"原则)
- 技术细节与专业术语解释
每个场景包含 8 条舆情种子数据,模拟真实的社交媒体评论(恐慌、愤怒、理性分析、品牌维护等多种视角)。
输入文本
│
▼
┌───────────────────┐ 成功 ┌─────────────┐
│ LLM 情绪分类 │ ──────────▶│ 返回结果 │
│ temperature=0.1 │ └─────────────┘
│ 截取前200字符 │
└───────┬───────────┘
│ 失败 (任意异常)
▼
┌───────────────────┐
│ 关键词匹配回退 │
│ 负面17词 vs 正面14词│ ──▶ 返回结果
└───────────────────┘
| 类别 | 数量 | 关键词 |
|---|---|---|
| 负面 | 17 | 愤怒、失望、恶心、垃圾、骗子、无良、黑心、维权、赔偿、道歉、抵制、举报、可恶、太过分、无法接受、严重、危害 |
| 正面 | 14 | 支持、理解、加油、相信、负责、改进、不错、赞、诚恳、点赞、看好、专业、靠谱、良心 |
| 中立 | 6 | 观望、等待、看看、关注、持续、了解 |
判定逻辑:负面命中 > 正面命中 → NEGATIVE;正面 > 负面 → POSITIVE;相等 → NEUTRAL
基于 jieba 中文分词,配合 46 个停用词过滤("的"、"了"、"是"、"在" 等),提取词频 Top 10 关键词(仅保留 >= 2 字的词)。
# crisis_sim/llm/factory.py
provider = create_provider() # 读取 config.LLM_PROVIDER
"openai" → OpenAIProvider # OpenAI / DeepSeek / 通义千问 / 小米MiMo 等
"claude" → ClaudeProvider # Anthropic Claude
"ollama" → OllamaProvider # 本地 Ollama 部署| 特性 | OpenAIProvider | ClaudeProvider | OllamaProvider |
|---|---|---|---|
| SDK | openai.AsyncOpenAI |
anthropic.AsyncAnthropic |
httpx.AsyncClient |
| 并发控制 | Semaphore(3) |
无 | 无 |
| 重试机制 | 指数退避 (5次) | 无 | 无 |
| 流式输出 | stream=True + yield |
不支持 | 不支持 |
| Token 限制 | 1024 | 1024 | 1024 |
| 超时 | SDK 默认 | SDK 默认 | 120 秒 |
| Token 估算 | len(text) // 2 |
len(text) // 2 |
len(text) // 2 |
- 单页应用:完整 HTML/CSS/JS 内嵌在
app.py的 Jinja2 模板中,无前端构建步骤 - 暗色主题:基于深海军蓝 (
#0f172a) 的配色方案 - 角色配色:
- 受害者消息:红色边框 (
#ef4444) - KOL 消息:蓝色边框 (
#3b82f6) - 支持者消息:绿色边框 (
#22c55e) - 官方声明:琥珀色高亮 (
#f59e0b)
- 受害者消息:红色边框 (
- 情绪标签色:正面绿色、负面红色、中立灰色
情绪趋势图(折线图):
- 3 条数据线:正面(绿)、负面(红)、中立(灰)
- Y 轴:0-100%,填充区域,曲线张力 0.3
- X 轴:第1轮、第2轮、第3轮...
立场演化图(多线折线图):
- 每个 Agent 一条线,使用 8 色调色板
- Y 轴:-1(反对)到 +1(支持)
- 数据点半径 4,线宽 2
浏览器 → POST /api/strategies_stream
← data: [策略文本流] ...
← data: \n__STRATEGIES_JSON__\n[JSON]
← data: [DONE]
异常处理: SSE 失败时自动降级为非流式 /api/strategies
仿真执行期间,前端每 1.5 秒轮询 /api/progress 获取执行进度。
消费者在喜茶饮品中发现异物,话题冲上微博热搜
传播渠道:微博 · 微信公众号 · 小红书 · 新闻媒体
| Agent | 角色 | 类型 | 立场 | 影响力 | 发言风格 |
|---|---|---|---|---|---|
| 小鱼爱喝奶茶 | 22岁大学生,忠实顾客,组织200+人维权群 | 受害者 | -0.8 | 0.6 | 情绪化、直接,常用感叹号,发图证据 |
| 食品安全卫士张律师 | 35岁维权律师,50万微博粉丝 | 受害者 | -0.7 | 0.7 | 严肃专业,引用《食品安全法》《消费者权益保护法》 |
| 奶茶重度患者小林 | 28岁程序员,年消费5000+元 | 受害者 | -0.6 | 0.4 | 焦虑口语化,常用"天哪""不会吧""细思极恐" |
| 食品科学张教授 | 45岁教授,中国农大博士,200万粉丝 | KOL | 0.0 | 0.9 | 专业数据驱动,引用 GB 国家标准 |
| 吃货测评王阿凯 | 30岁美食博主,80万粉丝 | KOL | 0.1 | 0.7 | 轻松客观,以"家人们"开头 |
| 喜茶五年老粉小周 | 28岁忠实用户,购买过联名周边 | 支持者 | 0.7 | 0.4 | 温和但坚定,"我喝了五年" |
| 茶饮行业观察者李总 | 33岁证券分析师,有财经专栏 | 支持者 | 0.5 | 0.8 | 理性引用行业数据,提及奈雪、霸王茶姬 |
安全研究员在暗网发现星聊用户数据库,涉及5000万条记录(手机号、MD5密码、私信)
传播渠道:微博 · 知乎 · 科技媒体 · 推特
| Agent | 角色 | 类型 | 立场 | 影响力 | 发言风格 |
|---|---|---|---|---|---|
| 惊恐的星聊用户阿明 | 技术向用户 | 受害者 | -0.9 | 0.6 | 愤怒兼技术流,"MD5未加盐?2026年了还用MD5?" |
| 受害者联盟维权群主 | 集体维权组织者 | 受害者 | -0.8 | 0.7 | 组织性语言,"我们XX万受害者" |
| 白帽老王 | 白帽黑客,影响力极高 | KOL | -0.4 | 1.0 | 技术分析,提供数据截图和哈希对比 |
| 科技自媒体大V老赵 | 深度报道风格 | KOL | -0.5 | 0.8 | 叙事性强,使用类比,偶尔标题党 |
| 隐私法专家陈教授 | 法律专家 | KOL | -0.6 | 0.9 | 精确引用法条,偶有立法建议 |
| 星辰科技员工匿名小号 | 内部知情者 | 支持者 | 0.2 | 0.5 | 匿名口吻,"据我所知",模糊爆料 |
| 投资圈明灯刘总 | 投资人视角 | 支持者 | 0.6 | 0.8 | "从行业角度看""长期价值" |
电动汽车高速行驶中突然失去动力,行车记录仪视频获2000万播放,IPO在即
传播渠道:抖音 · 微博 · 汽车之家 · 主流新闻
| Agent | 角色 | 类型 | 立场 | 影响力 | 发言风格 |
|---|---|---|---|---|---|
| 高速惊魂60秒车主 | 当事车主 | 受害者 | -0.9 | 0.8 | 克制但愤怒,"我不是来闹事的",附视频证据 |
| 受伤车主家属李姐 | 车祸伤者家属 | 受害者 | -1.0 | 0.7 | 悲痛愤怒,"我老公还在医院,你们在想IPO" |
| 38号车评人大飞 | 头部车评人 | KOL | -0.5 | 1.0 | 专业评测风格,"实测数据显示",零容忍安全问题 |
| 新能源汽车政策研究员 | 学术型 KOL | KOL | -0.6 | 0.9 | 学术严谨,提供技术图解和引用 |
| 极驰S7车主会群主 | 车主社群领袖 | 支持者 | 0.4 | 0.6 | 理性中有犹豫,"给品牌一点时间" |
| 新能源行业分析师 | 行业分析师 | 支持者 | 0.5 | 0.8 | "短期扰动不改长期逻辑" |
| 4S店前销售小赵 | 前内部人员 | 支持者 | -0.3 | 0.7 | 爆料风格,"内部培训PPT上写着",半真半假 |
品牌代言人曝出出轨丑闻 + 偷税漏税指控,品牌面临代言合同危机
传播渠道:微博 · 抖音 · 娱乐媒体 · 豆瓣
| Agent | 角色 | 类型 | 立场 | 影响力 | 发言风格 |
|---|---|---|---|---|---|
| 愤怒的消费者小美 | 粉丝转黑 | 受害者 | -0.6 | 0.5 | 饭圈用语,"社死""粉转黑" |
| 饭圈脱粉回踩大粉 | 脱粉大粉 | 受害者 | -0.9 | 0.7 | 饭圈黑话+爆料体,"脱粉了""来放实锤了" |
| 娱乐圈纪检委老卓 | 资深娱记 | KOL | -0.3 | 0.9 | "据可靠消息",谨慎但信息量大 |
| 财经观察频道 | 财经分析师 | KOL | -0.4 | 0.8 | "财务模型显示",理性冷静 |
| 理智粉"轩家军"群管 | 粉丝群管理 | 支持者 | 0.7 | 0.5 | 控场话术,"不信谣不传谣",但立场在动摇 |
| 品牌公关行业老兵 | PR 从业者 | 支持者 | 0.0 | 0.8 | 专业视角,"黄金48小时",冷静客观 |
科技博主通过控制变量实验证明打车 App 对老用户加价 23%,视频播放 800 万
传播渠道:B站 · 微博 · 抖音 · 新闻媒体
| Agent | 角色 | 类型 | 立场 | 影响力 | 发言风格 |
|---|---|---|---|---|---|
| 数码小测 | 科技博主,实验设计者 | 受害者 | -0.7 | 0.9 | 数据驱动,"控制变量""置信区间""统计显著" |
| 通勤族代表小刘 | 普通用户 | 受害者 | -0.8 | 0.5 | 日常口语,"老用户就是韭菜?" |
| 算法伦理研究者王教授 | 学术权威 | KOL | -0.5 | 1.0 | 学术+社会关怀,"算法不应成为剥削工具" |
| 互联网行业分析师 | 行业分析师 | KOL | -0.3 | 0.7 | "平台经济的底层逻辑",分析性强 |
| 飞享出行忠实用户老王 | 实用主义用户 | 支持者 | 0.3 | 0.4 | 务实,看更多视频后立场在变化 |
| 平台经济辩护者陈律师 | 法律视角 | 支持者 | 0.2 | 0.7 | "从现行法律看",区分动态定价与歧视定价 |
- Python 3.10+
- 任一 LLM API Key(OpenAI 兼容接口 / Anthropic Claude / 本地 Ollama)
# 1. 克隆仓库
git clone https://github.com/a805026135/CrisisSim.git
cd CrisisSim
# 2. 安装依赖
pip install -r requirements.txt
# 3. 配置环境变量
cp .env.example .env
# 编辑 .env,填入你的 API Key 和模型配置(见下方配置参考)
# 4. 启动服务
python app.py访问 http://localhost:5000 即可使用。
在项目根目录创建 .env 文件(可复制 .env.example):
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# LLM Provider 选择
# 可选值: openai | claude | ollama
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
LLM_PROVIDER=openai
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# OpenAI 兼容接口配置
# 支持: OpenAI / DeepSeek / 通义千问 / 小米MiMo 等
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
OPENAI_API_KEY=your-api-key-here
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o-mini
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Anthropic Claude 配置
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ANTHROPIC_API_KEY=sk-ant-your-key-here
CLAUDE_MODEL=claude-haiku-4-5-20251001
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# Ollama 本地部署配置
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=llama3
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
# 仿真参数
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
MAX_ROUNDS=3 # 仿真轮次 (默认 3)
MEMORY_WINDOW=5 # Agent 记忆窗口大小 (默认 5)| 变量 | 默认值 | 说明 |
|---|---|---|
LLM_PROVIDER |
openai |
LLM 后端选择,可选 openai / claude / ollama |
OPENAI_API_KEY |
"" |
OpenAI 兼容接口的 API Key |
OPENAI_BASE_URL |
https://api.openai.com/v1 |
API 端点地址,可替换为 DeepSeek / MiMo 等 |
OPENAI_MODEL |
gpt-4o-mini |
模型名称 |
ANTHROPIC_API_KEY |
"" |
Anthropic Claude 的 API Key |
CLAUDE_MODEL |
claude-haiku-4-5-20251001 |
Claude 模型名称 |
OLLAMA_BASE_URL |
http://localhost:11434 |
Ollama 服务地址 |
OLLAMA_MODEL |
llama3 |
Ollama 模型名称 |
MAX_ROUNDS |
3 |
仿真推演轮次数 |
MEMORY_WINDOW |
5 |
Agent 短期记忆滑动窗口大小 |
OpenAI(官方)
LLM_PROVIDER=openai
OPENAI_API_KEY=sk-xxx
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o-miniDeepSeek
LLM_PROVIDER=openai
OPENAI_API_KEY=sk-xxx
OPENAI_BASE_URL=https://api.deepseek.com/v1
OPENAI_MODEL=deepseek-chat通义千问
LLM_PROVIDER=openai
OPENAI_API_KEY=sk-xxx
OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
OPENAI_MODEL=qwen-turbo小米 MiMo
LLM_PROVIDER=openai
OPENAI_API_KEY=your-key
OPENAI_BASE_URL=https://token-plan-cn.xiaomimimo.com/v1
OPENAI_MODEL=mimo-v2.5-proAnthropic Claude
LLM_PROVIDER=claude
ANTHROPIC_API_KEY=sk-ant-xxx
CLAUDE_MODEL=claude-haiku-4-5-20251001Ollama 本地部署
LLM_PROVIDER=ollama
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=llama3| 端点 | 方法 | 说明 |
|---|---|---|
/ |
GET | 返回前端页面 |
/api/scenario |
POST | 获取场景详情和 Agent 配置 |
/api/init |
POST | 初始化仿真引擎(加载知识库 + 舆情种子) |
/api/strategies |
POST | 获取 2 套候选策略(非流式) |
/api/strategies_stream |
POST | 流式获取策略生成过程 (SSE) |
/api/execute |
POST | 执行一轮仿真推演 |
/api/search |
POST | 网络搜索(知识/舆情) |
/api/import_opinions |
POST | 导入手动舆情文本 |
/api/progress |
POST | 轮询执行进度 |
/api/kb_status |
POST | 获取知识库和舆情数据量 |
/api/summary |
POST | 获取仿真最终总结 |
初始化引擎:
POST /api/init
{
"session_id": "uuid",
"scenario_key": "tea_safety",
"agent_configs": [ ... ] // 可选:自定义 Agent 配置
}执行仿真轮次:
POST /api/execute
{
"session_id": "uuid",
"strategy": {
"strategy_id": "A",
"title": "...",
"official_statement": "..."
}
}从 5 个预设场景中选择一个,系统自动加载对应的 Agent 角色、知识库和舆情种子数据。
- 查看每个 Agent 的详细设定(姓名、角色描述、发言风格)
- 通过滑块调整 立场值(-1.0 反对 ~ +1.0 支持)和 影响力(0.1 ~ 1.0)
- 可添加自定义 Agent(默认立场 0.0,影响力 0.5)
- 使用网络搜索补充品牌背景和舆情情报
- 手动导入或编辑舆情数据
- AI 公关顾问自动分析当前舆情态势,生成 2 套候选策略
- 每套策略包含:策略名称、描述、理由、完整官方声明草稿
- 选择策略 A 或 B,或切换到"自定义声明"手动撰写
- 点击执行,观察各 Agent 的实时反应
- 消息时间线:每条消息标注发言人、角色类型、情绪标签,官方声明高亮显示
- 情绪分布:正面/负面/中立占比实时更新
- 立场演化:每轮结束后各 Agent 立场折线图更新
- PR 顾问反思:每轮结束显示策略效果评估
- 完成一轮后可选择新策略继续推演
- 比较不同策略在多轮中的舆情走向差异
- 查看最终总结报告,包含每轮策略效果和情绪变化
| 类别 | 技术 | 版本 | 用途 |
|---|---|---|---|
| 后端框架 | Flask | >= 3.0 | Web 服务 + API 路由 |
| 前端 | Vanilla JavaScript | ES2020+ | 页面交互逻辑 |
| 图表库 | Chart.js | 4.4.7 (CDN) | 情绪趋势图 + 立场演化图 |
| LLM 接口 | OpenAI SDK | >= 1.0 | OpenAI 兼容 API 调用 |
| LLM 接口 | Anthropic SDK | >= 0.20 | Claude API 调用 |
| LLM 接口 | httpx | >= 0.25 | Ollama 本地 API 调用 |
| 向量数据库 | ChromaDB | — | 余弦相似度向量检索 |
| 数据模型 | Pydantic | >= 2.0 | 结构化数据验证与序列化 |
| 中文分词 | jieba | >= 0.42 | 关键词提取 |
| 数值计算 | NumPy | >= 1.24 | 数值运算 |
| 异步并发 | asyncio | 标准库 | Agent 并行反应 + 并发控制 |
| 环境配置 | python-dotenv | >= 1.0 | .env 文件加载 |
MIT License









