feihong-code 8.0.0 → 8.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/.github/workflows/ci.yml +193 -193
  2. package/CHANGELOG.md +140 -117
  3. package/README.md +656 -636
  4. package/agent-team/.env.example +13 -0
  5. package/agent-team/README.md +42 -0
  6. package/agent-team/agents/__init__.py +0 -0
  7. package/agent-team/agents/l1_acquisition.py +207 -0
  8. package/agent-team/agents/l2_content.py +237 -0
  9. package/agent-team/agents/l3_conversion.py +148 -0
  10. package/agent-team/agents/l4_analysis.py +118 -0
  11. package/agent-team/agents/l5_management.py +52 -0
  12. package/agent-team/agents/registry.py +60 -0
  13. package/agent-team/config.py +39 -0
  14. package/agent-team/core/__init__.py +0 -0
  15. package/agent-team/core/agent.py +73 -0
  16. package/agent-team/core/models.py +347 -0
  17. package/agent-team/core/scheduler.py +150 -0
  18. package/agent-team/core/task.py +121 -0
  19. package/agent-team/feihongzhi.db +0 -0
  20. package/agent-team/llm/__init__.py +12 -0
  21. package/agent-team/llm/base.py +22 -0
  22. package/agent-team/llm/doubao_llm.py +52 -0
  23. package/agent-team/llm/mock_llm.py +42 -0
  24. package/agent-team/main.py +235 -0
  25. package/agent-team/requirements.txt +2 -0
  26. package/agent-team/skill_packager.py +248 -0
  27. package/agent-team/skills/01_AI/350/216/267/345/256/242/347/272/277/347/264/242/351/233/267/350/276/276/SKILL.md +40 -0
  28. package/agent-team/skills/01_AI/350/216/267/345/256/242/347/272/277/347/264/242/351/233/267/350/276/276/run.py +111 -0
  29. package/agent-team/skills/02_AI/351/224/200/345/224/256/350/267/237/350/277/233/351/224/200/345/206/240/SKILL.md +38 -0
  30. package/agent-team/skills/02_AI/351/224/200/345/224/256/350/267/237/350/277/233/351/224/200/345/206/240/run.py +108 -0
  31. package/agent-team/skills/03_/350/257/204/350/256/272/345/214/272/345/225/206/346/234/272/350/257/206/345/210/253/345/256/230/SKILL.md +38 -0
  32. package/agent-team/skills/03_/350/257/204/350/256/272/345/214/272/345/225/206/346/234/272/350/257/206/345/210/253/345/256/230/run.py +106 -0
  33. package/agent-team/skills/04_/345/256/242/346/210/267/350/201/212/345/244/251/346/210/220/344/272/244/345/210/206/346/236/220/345/256/230/SKILL.md +37 -0
  34. package/agent-team/skills/04_/345/256/242/346/210/267/350/201/212/345/244/251/346/210/220/344/272/244/345/210/206/346/236/220/345/256/230/run.py +107 -0
  35. package/agent-team/skills/05_/345/220/214/350/241/214/347/210/206/346/254/276/351/233/267/350/276/276/SKILL.md +38 -0
  36. package/agent-team/skills/05_/345/220/214/350/241/214/347/210/206/346/254/276/351/233/267/350/276/276/run.py +99 -0
  37. package/agent-team/skills/06_/346/257/217/346/227/245/347/262/276/345/207/206/350/216/267/345/256/242/351/200/211/351/242/230/345/256/230/SKILL.md +39 -0
  38. package/agent-team/skills/06_/346/257/217/346/227/245/347/262/276/345/207/206/350/216/267/345/256/242/351/200/211/351/242/230/345/256/230/run.py +103 -0
  39. package/agent-team/skills/07_AI/345/244/226/350/264/270/345/274/200/345/217/221/345/256/242/346/210/267/345/221/230/345/267/245/SKILL.md +39 -0
  40. package/agent-team/skills/07_AI/345/244/226/350/264/270/345/274/200/345/217/221/345/256/242/346/210/267/345/221/230/345/267/245/run.py +103 -0
  41. package/agent-team/skills/08_/345/260/217/347/272/242/344/271/246/347/262/276/345/207/206/350/216/267/345/256/242/345/221/230/345/267/245/SKILL.md +40 -0
  42. package/agent-team/skills/08_/345/260/217/347/272/242/344/271/246/347/262/276/345/207/206/350/216/267/345/256/242/345/221/230/345/267/245/run.py +97 -0
  43. package/agent-team/skills/09_/347/247/201/345/237/237/345/256/242/346/210/267/345/210/206/345/261/202/350/267/237/350/277/233/345/256/230/SKILL.md +38 -0
  44. package/agent-team/skills/09_/347/247/201/345/237/237/345/256/242/346/210/267/345/210/206/345/261/202/350/267/237/350/277/233/345/256/230/run.py +106 -0
  45. package/agent-team/skills/10_GEO/345/225/206/346/234/272/350/257/212/346/226/255/345/256/230/SKILL.md +38 -0
  46. package/agent-team/skills/10_GEO/345/225/206/346/234/272/350/257/212/346/226/255/345/256/230/run.py +108 -0
  47. package/agent-team/skills/11_/344/270/200/344/272/272/345/205/254/345/217/270AI/345/221/230/345/267/245/350/260/203/345/272/246/345/256/230/SKILL.md +37 -0
  48. package/agent-team/skills/11_/344/270/200/344/272/272/345/205/254/345/217/270AI/345/221/230/345/267/245/350/260/203/345/272/246/345/256/230/run.py +111 -0
  49. package/agent-team/skills/12_/350/200/201/346/235/277/347/237/255/350/247/206/351/242/221/350/216/267/345/256/242/350/204/232/346/234/254/345/256/230/SKILL.md +39 -0
  50. package/agent-team/skills/12_/350/200/201/346/235/277/347/237/255/350/247/206/351/242/221/350/216/267/345/256/242/350/204/232/346/234/254/345/256/230/run.py +104 -0
  51. package/agent-team/skills/13_/345/215/232/344/270/273/350/264/246/345/217/267/346/267/261/345/272/246/346/213/206/350/247/243/345/256/230/SKILL.md +37 -0
  52. package/agent-team/skills/13_/345/215/232/344/270/273/350/264/246/345/217/267/346/267/261/345/272/246/346/213/206/350/247/243/345/256/230/run.py +105 -0
  53. package/agent-team/skills/14_AI/347/237/255/350/247/206/351/242/221/350/207/252/345/212/250/345/211/252/350/276/221/345/270/210/SKILL.md +39 -0
  54. package/agent-team/skills/14_AI/347/237/255/350/247/206/351/242/221/350/207/252/345/212/250/345/211/252/350/276/221/345/270/210/run.py +108 -0
  55. package/agent-team/skills/15_/345/205/254/344/274/227/345/217/267/350/207/252/345/212/250/350/277/220/350/220/245/345/217/221/345/270/203/345/256/230/SKILL.md +38 -0
  56. package/agent-team/skills/15_/345/205/254/344/274/227/345/217/267/350/207/252/345/212/250/350/277/220/350/220/245/345/217/221/345/270/203/345/256/230/run.py +105 -0
  57. package/agent-team/skills/16_/350/241/214/344/270/232/346/267/261/345/272/246/345/210/206/346/236/220/345/270/210/SKILL.md +38 -0
  58. package/agent-team/skills/16_/350/241/214/344/270/232/346/267/261/345/272/246/345/210/206/346/236/220/345/270/210/run.py +108 -0
  59. package/agent-team/skills/17_/346/212/225/350/265/204/347/240/224/347/251/266/345/222/250/350/257/242/345/256/230/SKILL.md +38 -0
  60. package/agent-team/skills/17_/346/212/225/350/265/204/347/240/224/347/251/266/345/222/250/350/257/242/345/256/230/run.py +106 -0
  61. package/agent-team/tests/__init__.py +0 -0
  62. package/agent-team/tests/test_core.py +156 -0
  63. package/dist/agent/agent-session.js +103 -0
  64. package/dist/agent/agent-session.js.map +1 -0
  65. package/dist/agent/orchestrator.js +8 -0
  66. package/dist/agent/orchestrator.js.map +1 -1
  67. package/dist/agent/steer.js +52 -0
  68. package/dist/agent/steer.js.map +1 -0
  69. package/dist/cli/index.js +1 -0
  70. package/dist/cli/index.js.map +1 -1
  71. package/dist/cli/node-guard.js +17 -0
  72. package/dist/cli/node-guard.js.map +1 -0
  73. package/dist/cli/run.js +2 -0
  74. package/dist/cli/run.js.map +1 -1
  75. package/dist/cli/version.js +1 -1
  76. package/dist/enterprise/policy.js +40 -17
  77. package/dist/enterprise/policy.js.map +1 -1
  78. package/dist/tools/agents/agents-bridge.js +144 -0
  79. package/dist/tools/agents/agents-bridge.js.map +1 -0
  80. package/dist/tools/desktop/desktop-guard.js +81 -0
  81. package/dist/tools/desktop/desktop-guard.js.map +1 -0
  82. package/dist/tools/desktop/desktop.tool.js +201 -0
  83. package/dist/tools/desktop/desktop.tool.js.map +1 -0
  84. package/dist/tools/desktop/feihong-win.js +163 -0
  85. package/dist/tools/desktop/feihong-win.js.map +1 -0
  86. package/dist/tools/desktop/index.js +37 -0
  87. package/dist/tools/desktop/index.js.map +1 -0
  88. package/dist/tools/index.js +2 -0
  89. package/dist/tools/index.js.map +1 -1
  90. package/dist/tools/mcp/index.js +10 -2
  91. package/dist/tools/mcp/index.js.map +1 -1
  92. package/dist/tools/mcp/mcp-client.js +4 -0
  93. package/dist/tools/mcp/mcp-client.js.map +1 -1
  94. package/dist/tools/sandbox.js +28 -0
  95. package/dist/tools/sandbox.js.map +1 -1
  96. package/dist/web/public/public/css/style.css +1756 -0
  97. package/dist/web/public/public/favicon.svg +11 -0
  98. package/dist/web/public/public/index.html +1246 -0
  99. package/dist/web/public/public/js/api.js +558 -0
  100. package/dist/web/public/public/js/app.js +2233 -0
  101. package/dist/web/public/public/js/mock-api.js +259 -0
  102. package/dist/web/public/public/js/monaco-editor.js +363 -0
  103. package/dist/web/public/public/js/ui.js +2217 -0
  104. package/dist/web/public/public/js/utils.js +214 -0
  105. package/dist/web/public/public/manifest.json +59 -0
  106. package/dist/web/public/public/robots.txt +14 -0
  107. package/dist/web/public/public/service-worker.js +149 -0
  108. package/docs/AI/345/221/230/345/267/245/345/206/233/345/233/242-/346/225/264/345/220/210/350/257/264/346/230/216.md +68 -0
  109. package/docs/API.md +1 -1
  110. package/docs/App/346/212/200/346/234/257/350/257/264/346/230/216/344/271/246.md +3 -3
  111. package/docs/P1.1-P3-P5/345/267/245/347/250/213/345/256/236/346/226/275/346/200/273/347/273/223.md +328 -0
  112. package/docs/P5-Pi/345/257/271/347/205/247/350/257/204/346/265/213/346/212/245/345/221/212-mock/346/250/241/345/274/217.json +125 -0
  113. package/docs/P5-Pi/345/257/271/347/205/247/350/257/204/346/265/213/346/212/245/345/221/212-/347/234/237/345/256/236/346/250/241/345/236/213.json +138 -0
  114. package/docs/P5-pi-compare-real-report.json +138 -0
  115. package/docs/P5-pi-compare-report.json +125 -0
  116. package/docs/Pi-Agent/346/216/245/345/205/245/351/243/236/350/231/271Code-MVP/351/233/206/346/210/220/344/272/244/344/273/230/347/211/251.md +355 -0
  117. package/docs/Pi-Agent/346/216/245/345/205/245/351/243/236/350/231/271Code/344/273/267/345/200/274/345/210/206/346/236/220-/345/274/200/345/217/221/346/226/207/346/241/243.md +291 -0
  118. package/docs/Pi-Agent/346/216/245/345/205/245/351/243/236/350/231/271Code/344/273/267/345/200/274/351/207/215/344/274/260-/345/217/257/350/247/206/345/214/226.html +84 -0
  119. package/docs/SWE-bench-300-agnes-2.5-flash-/346/234/200/347/273/210/346/212/245/345/221/212.json +2012 -0
  120. package/docs/SWE-bench-300-agnes-2.5-flash-/350/267/221/345/210/206/346/212/245/345/221/212.md +74 -0
  121. package/docs/SWE-bench-Lite-DeepSeek-V4-Flash-/350/267/221/345/210/206/346/212/245/345/221/212.md +102 -0
  122. package/docs/TECHNICAL-SPECIFICATION.md +66 -0
  123. package/docs/TECHNICAL-SPECIFICATION.pdf +0 -0
  124. package/docs/Windows/346/211/213/350/204/232-POC/346/274/224/347/244/272/350/204/232/346/234/254.md +131 -0
  125. package/docs/Windows/346/211/213/350/204/232/346/216/245/345/205/245/346/214/207/345/215/227.md +181 -0
  126. package/docs//344/275/277/347/224/250/350/257/264/346/230/216/344/271/246-v8.0.1.md +146 -0
  127. package/docs//344/275/277/347/224/250/350/257/264/346/230/216/344/271/246.md +1 -1
  128. package/package.json +6 -3
@@ -0,0 +1,13 @@
1
+ # 复制为 .env 并填写
2
+ # 模型供应商:mock(无 Key 跑通链路)| doubao(豆包大模型)
3
+ LLM_PROVIDER=mock
4
+
5
+ # 豆包大模型(火山方舟 OpenAI 兼容接口)
6
+ DOUBAO_API_KEY=
7
+ DOUBAO_MODEL=doubao-seed-1-6-250615
8
+ DOUBAO_BASE_URL=https://ark.cn-beijing.volces.com/api/v3
9
+
10
+ # 数据与调度
11
+ DB_PATH=feihongzhi.db
12
+ MAX_RETRY=3
13
+ ALERT_LEVEL=log
@@ -0,0 +1,42 @@
1
+ # 飞虹智 · AI 员工军团系统(feihongzhi_agents)
2
+
3
+ 17 个 AI 员工模块 + 11 调度官的一人公司运营系统。按开发文档《AI 员工军团系统开发文档》实现。
4
+
5
+ ## 快速开始
6
+
7
+ ```bash
8
+ # 1. 初始化数据库
9
+ python3 main.py init-db
10
+
11
+ # 2. 查看 17 个 AI 员工清单
12
+ python3 main.py list-agents
13
+
14
+ # 3. 跑通 M1 销售闭环演示(01线索雷达 → 02跟进销冠 → 04成交分析 → 09私域分层)
15
+ python3 main.py demo-pipeline
16
+
17
+ # 4. 提交单个任务并执行
18
+ python3 main.py submit 12 --input '{"topic": "工厂老板如何用AI获客"}'
19
+ python3 main.py run-once
20
+
21
+ # 5. 任务统计
22
+ python3 main.py stats
23
+ ```
24
+
25
+ ## 接入真实大模型
26
+
27
+ 复制 `.env.example` 为 `.env`,填入豆包 API Key 后设置 `LLM_PROVIDER=doubao`。
28
+
29
+ ## 目录结构
30
+
31
+ ```
32
+ core/ 数据模型(SQLite)、任务协议与状态机、11 调度官、BaseAgent 基类
33
+ llm/ LLM 适配器(mock 本地模拟 / 豆包 API)
34
+ agents/ 17 个 AI 员工模块(按五层组织)
35
+ tests/ 单元测试
36
+ ```
37
+
38
+ ## 开发状态
39
+
40
+ - [x] M0 基建:任务协议、数据模型、调度官骨架、模块框架(当前版本)
41
+ - [ ] M1 销售闭环:接入真实 LLM 与真实线索源
42
+ - [ ] M2 内容引擎 / M3 渠道扩展 / M4 战略决策(按路线图推进)
File without changes
@@ -0,0 +1,207 @@
1
+ """L1 获客引流层:01 获客线索雷达 / 03 评论区商机识别官 / 06 每日精准获客选题官 / 07 AI外贸开发客户员工 / 08 小红书精准获客员工。
2
+
3
+ 每个模块的核心业务逻辑为模块级纯函数 run_logic_XX(data, llm):
4
+ - 确定性逻辑只依赖标准库,可被 skill_packager 内嵌导出为独立 Skill 的 run.py;
5
+ - llm 非 mock 时追加 AI 增强说明字段 ai_note。
6
+ """
7
+ import json
8
+ import time
9
+ from datetime import datetime
10
+
11
+ from core.agent import BaseAgent
12
+
13
+
14
+ def _ts() -> str:
15
+ return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
16
+
17
+
18
+ # ---------------------------------------------------------------- 01
19
+ def run_logic_01(data, llm=None):
20
+ """全域线索发现、清洗与入库(线索池)。"""
21
+ channels = data.get("channels") or ["评论区", "小红书", "公众号"]
22
+ keywords = data.get("keywords", "AI 获客")
23
+ now = int(time.time())
24
+ leads = []
25
+ for i, ch in enumerate(channels[:3], 1):
26
+ leads.append({
27
+ "lead_id": f"L{now % 100000000}{i}",
28
+ "source_channel": ch,
29
+ "company_name": f"示例{['制造','贸易','服务'][i-1]}公司{i}",
30
+ "contact_name": f"联系人{i}",
31
+ "contact_phone": f"1380000{i:04d}",
32
+ "grade": ["A", "B", "B"][i - 1],
33
+ "remark": f"来自{ch},匹配关键词「{keywords}」",
34
+ "created_at": _ts(),
35
+ })
36
+ ai_note = ""
37
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
38
+ try:
39
+ ai_note = llm.complete(
40
+ f"请基于输入 {json.dumps(data, ensure_ascii=False)} 给出线索质量评估与分级建议,不超过 80 字。",
41
+ system="你是资深销售线索运营专家。")
42
+ except Exception:
43
+ ai_note = ""
44
+ return {"total": len(leads), "leads": leads, "dedup_rule": "phone+company 联合去重", "ai_note": ai_note}
45
+
46
+
47
+ class LeadRadarAgent(BaseAgent):
48
+ module_id = "01"
49
+ name = "AI获客线索雷达"
50
+ layer = "L1"
51
+ priority = "P0"
52
+ description = "全域线索发现、清洗与入库,构建线索池"
53
+ input_schema = {"channels": "线索渠道列表,如 [\"评论区\",\"小红书\",\"公众号\"]", "keywords": "获客关键词"}
54
+ output_keys = {"total": "线索总数", "leads": "线索列表", "dedup_rule": "去重规则"}
55
+ run_logic = staticmethod(run_logic_01)
56
+
57
+ def persist(self, output, task):
58
+ from core import models
59
+ for lead in output.get("leads", []):
60
+ models.insert_lead(lead)
61
+
62
+
63
+ # ---------------------------------------------------------------- 03
64
+ def run_logic_03(data, llm=None):
65
+ """评论区商机识别:监控目标账号评论区,提取意向商机。"""
66
+ accounts = data.get("target_accounts") or ["对标账号A", "对标账号B"]
67
+ found = []
68
+ for i, acc in enumerate(accounts[:2], 1):
69
+ found.append({
70
+ "opportunity_id": f"OP{i}{int(time.time()) % 100000}",
71
+ "account": acc,
72
+ "intent": "求购 / 咨询报价" if i == 1 else "寻求合作",
73
+ "quote": f"「请问你们这个方案怎么收费?想了解一下」",
74
+ "lead_ref": f"已转线索池待跟进(实时 {_ts()})",
75
+ })
76
+ ai_note = ""
77
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
78
+ try:
79
+ ai_note = llm.complete(
80
+ f"评论区内容 {json.dumps(found, ensure_ascii=False)},请判断真实意向并排序,不超过 80 字。",
81
+ system="你是商机识别专家。")
82
+ except Exception:
83
+ ai_note = ""
84
+ return {"opportunities": found, "source_evidence": "原文链接与截图归档", "ai_note": ai_note}
85
+
86
+
87
+ class CommentOpportunityAgent(BaseAgent):
88
+ module_id = "03"
89
+ name = "评论区商机识别官"
90
+ layer = "L1"
91
+ priority = "P1"
92
+ description = "监控目标账号与话题评论区,识别需求与意向,提取商机"
93
+ input_schema = {"target_accounts": "目标账号/话题列表"}
94
+ output_keys = {"opportunities": "商机列表", "source_evidence": "原文证据"}
95
+ run_logic = staticmethod(run_logic_03)
96
+
97
+ def persist(self, output, task):
98
+ from core import models
99
+ for op in output.get("opportunities", []):
100
+ models.insert_lead({
101
+ "lead_id": op.get("opportunity_id", ""),
102
+ "source_channel": "评论区",
103
+ "company_name": f"{op.get('account', '')}商机",
104
+ "contact_name": "待补",
105
+ "contact_phone": "",
106
+ "status": "new",
107
+ "grade": "B",
108
+ "remark": f"意向:{op.get('intent', '')};原文:{op.get('quote', '')}",
109
+ })
110
+
111
+
112
+ # ---------------------------------------------------------------- 06
113
+ def run_logic_06(data, llm=None):
114
+ """每日精准获客选题:按目标客户画像与热点生成选题。"""
115
+ persona = data.get("persona", "工厂老板")
116
+ hot_topics = data.get("hot_topics") or ["AI 获客", "降本增效"]
117
+ topics = [
118
+ {"title": f"AI 如何帮{persona}每天自动获客", "direction": "痛点切入", "reason": f"结合热点「{hot_topics[0]}」"},
119
+ {"title": "一人公司怎么养 17 个 AI 员工", "direction": "案例教学", "reason": "差异化稀缺选题"},
120
+ {"title": "评论区才是最大的金矿", "direction": "方法拆解", "reason": f"呼应热点「{hot_topics[-1]}」"},
121
+ ]
122
+ ai_note = ""
123
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
124
+ try:
125
+ ai_note = llm.complete(
126
+ f"画像:{persona};热点:{hot_topics}。补充 1 个更高转化率的选题,不超过 60 字。",
127
+ system="你是短视频选题策划专家。")
128
+ except Exception:
129
+ ai_note = ""
130
+ return {"date": _ts()[:10], "topics": topics, "ai_note": ai_note}
131
+
132
+
133
+ class DailyTopicAgent(BaseAgent):
134
+ module_id = "06"
135
+ name = "每日精准获客选题官"
136
+ layer = "L1"
137
+ priority = "P1"
138
+ description = "按目标客户画像与行业热点生成每日获客选题"
139
+ input_schema = {"persona": "目标客户画像", "hot_topics": "行业热点列表"}
140
+ output_keys = {"date": "选题日期", "topics": "选题清单"}
141
+ run_logic = staticmethod(run_logic_06)
142
+
143
+
144
+ # ---------------------------------------------------------------- 07
145
+ def run_logic_07(data, llm=None):
146
+ """外贸客户开发:目标市场客户开发与首轮触达。"""
147
+ market = data.get("market", "东南亚")
148
+ product = data.get("product", "智能家居")
149
+ letter = (
150
+ f"Subject: {product} 供应商直供方案({market})\n\n"
151
+ f"您好,我们专注 {product} 产能与交期,可支持 OEM/ODM,"
152
+ f"首单可样品验证。期待交流。"
153
+ )
154
+ candidates = [
155
+ {"company": f"{market}采购商A", "channel": "展会名录", "priority": "高"},
156
+ {"company": f"{market}渠道商B", "channel": "平台询盘", "priority": "中"},
157
+ ]
158
+ ai_note = ""
159
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
160
+ try:
161
+ ai_note = llm.complete(
162
+ f"市场 {market}、产品 {product},优化开发信开头两句话,不超过 60 字。",
163
+ system="你是外贸获客专家。")
164
+ except Exception:
165
+ ai_note = ""
166
+ return {"outreach_letter": letter, "candidates": candidates, "compliance": "触达前已过频控与合规检查", "ai_note": ai_note}
167
+
168
+
169
+ class ForeignTradeAgent(BaseAgent):
170
+ module_id = "07"
171
+ name = "AI外贸开发客户员工"
172
+ layer = "L1"
173
+ priority = "P2"
174
+ description = "外贸场景客户开发与首轮触达"
175
+ input_schema = {"market": "目标市场", "product": "产品"}
176
+ output_keys = {"outreach_letter": "开发信", "candidates": "候选客户"}
177
+ run_logic = staticmethod(run_logic_07)
178
+
179
+
180
+ # ---------------------------------------------------------------- 08
181
+ def run_logic_08(data, llm=None):
182
+ """小红书获客:内容获客与线索收集。"""
183
+ category = data.get("category", "企业服务")
184
+ audience = data.get("audience", "工厂老板")
185
+ note_title = f"做了 3 个月小红书,{audience}客户主动找上门"
186
+ note_body = f"从 0 到 1 用小红书给{category}获客的真实过程:选题、封面、评论区运营三步走。"
187
+ guide_comment = "需要这套《小红书获客 SOP》的朋友,评论区扣「1」,我发你。"
188
+ ai_note = ""
189
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
190
+ try:
191
+ ai_note = llm.complete(
192
+ f"品类 {category}、受众 {audience},给出 1 个更高点击的标题,不超过 40 字。",
193
+ system="你是小红书内容运营专家。")
194
+ except Exception:
195
+ ai_note = ""
196
+ return {"note_title": note_title, "note_body": note_body, "guide_comment": guide_comment, "ai_note": ai_note}
197
+
198
+
199
+ class XiaohongshuAgent(BaseAgent):
200
+ module_id = "08"
201
+ name = "小红书精准获客员工"
202
+ layer = "L1"
203
+ priority = "P2"
204
+ description = "小红书内容获客与线索收集"
205
+ input_schema = {"category": "品类", "audience": "目标人群"}
206
+ output_keys = {"note_title": "笔记标题", "note_body": "笔记正文", "guide_comment": "评论区引导话术"}
207
+ run_logic = staticmethod(run_logic_08)
@@ -0,0 +1,237 @@
1
+ """L2 内容生产层:05 同行爆款雷达 / 12 老板短视频获客脚本官 / 13 博主账号深度拆解官 / 14 AI短视频自动剪辑师 / 15 公众号自动运营发布官。"""
2
+ import json
3
+ import time
4
+ from datetime import datetime
5
+
6
+ from core.agent import BaseAgent
7
+
8
+
9
+ def _ts() -> str:
10
+ return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
11
+
12
+
13
+ # ---------------------------------------------------------------- 05
14
+ def run_logic_05(data, llm=None):
15
+ """同行爆款雷达:监控同行爆款,提炼可复制模式。"""
16
+ accounts = data.get("competitor_accounts") or ["同行账号A", "同行账号B"]
17
+ days = int(data.get("days", 7))
18
+ hot = [
19
+ {"title": "工厂老板必看的 3 个获客真相", "views": 128000, "account": accounts[0], "days": days},
20
+ {"title": "我靠评论区捡了 200 个客户", "views": 96000, "account": accounts[-1], "days": days},
21
+ ]
22
+ patterns = ["强反差标题 + 数字钩子", "真实案例收尾 + 行动号召", "评论区互动引导"]
23
+ ai_note = ""
24
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
25
+ try:
26
+ ai_note = llm.complete(
27
+ f"近 {days} 天爆款 {json.dumps(hot, ensure_ascii=False)},提炼 1 条可复用选题公式,不超过 60 字。",
28
+ system="你是内容增长分析师。")
29
+ except Exception:
30
+ ai_note = ""
31
+ return {"hot_contents": hot, "patterns": patterns, "ai_note": ai_note}
32
+
33
+
34
+ class ViralRadarAgent(BaseAgent):
35
+ module_id = "05"
36
+ name = "同行爆款雷达"
37
+ layer = "L2"
38
+ priority = "P2"
39
+ description = "监控同行爆款内容,提炼可复制模式"
40
+ input_schema = {"competitor_accounts": "同行账号列表"}
41
+ output_keys = {"hot_contents": "爆款列表", "patterns": "可复用模式"}
42
+ run_logic = staticmethod(run_logic_05)
43
+
44
+ def persist(self, output, task):
45
+ from core import models
46
+ models.insert_asset({
47
+ "content_id": f"A{int(time.time()) % 100000000}",
48
+ "content_type": "爆款分析",
49
+ "topic": "同行爆款雷达",
50
+ "script": json.dumps(output.get("hot_contents", []), ensure_ascii=False),
51
+ "publish_status": "draft",
52
+ })
53
+
54
+
55
+ # ---------------------------------------------------------------- 12
56
+ def run_logic_12(data, llm=None):
57
+ """短视频获客脚本:生成口播 + 分镜脚本。"""
58
+ topic = data.get("topic", "AI 获客")
59
+ points = list(data.get("selling_points") or ["自动找客户", "降本增效"])
60
+ while len(points) < 2:
61
+ points.append("真实案例支撑")
62
+ audience = data.get("audience", "工厂老板")
63
+ script = {
64
+ "hook": f"{audience}注意:{topic},90% 的人都做反了。",
65
+ "body": f"三步讲清:①{points[0]};②{points[1]};③真实案例。",
66
+ "cta": "评论区扣「方案」,免费领《获客清单》。",
67
+ "duration_sec": 45,
68
+ "shots": ["近景口播 3s", "痛点场景 10s", "操作演示 20s", "案例收尾 10s", "CTA 2s"],
69
+ }
70
+ ai_note = ""
71
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
72
+ try:
73
+ ai_note = llm.complete(
74
+ f"选题 {topic}、卖点 {points},重写黄金 3 秒钩子,不超过 40 字。",
75
+ system="你是短视频编导。")
76
+ except Exception:
77
+ ai_note = ""
78
+ return {"script": script, "ai_note": ai_note}
79
+
80
+
81
+ class VideoScriptAgent(BaseAgent):
82
+ module_id = "12"
83
+ name = "老板短视频获客脚本官"
84
+ layer = "L2"
85
+ priority = "P1"
86
+ description = "生成获客向短视频脚本(口播 + 分镜)"
87
+ input_schema = {"topic": "选题", "selling_points": "卖点列表", "audience": "目标客户"}
88
+ output_keys = {"script": "脚本(hook/body/cta/shots)"}
89
+ run_logic = staticmethod(run_logic_12)
90
+
91
+ def persist(self, output, task):
92
+ from core import models
93
+ models.insert_asset({
94
+ "content_id": f"A{int(time.time()) % 100000000}",
95
+ "content_type": "脚本",
96
+ "topic": task.input_json.get("topic", ""),
97
+ "script": json.dumps(output.get("script", {}), ensure_ascii=False),
98
+ "publish_status": "draft",
99
+ })
100
+
101
+
102
+ # ---------------------------------------------------------------- 13
103
+ def run_logic_13(data, llm=None):
104
+ """博主账号拆解:拆解对标账号的定位、选题、结构、转化路径。"""
105
+ account = data.get("account", "对标账号A")
106
+ report = {
107
+ "account": account,
108
+ "positioning": "工厂老板 IP,讲透 AI 获客",
109
+ "topics": ["获客方法", "行业案例", "工具测评"],
110
+ "structure": "三段式:痛点 → 方法 → 案例",
111
+ "conversion": "评论区引流 → 私域 → 成交",
112
+ "takedown_at": _ts(),
113
+ }
114
+ ai_note = ""
115
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
116
+ try:
117
+ ai_note = llm.complete(
118
+ f"拆解账号 {account},给出 1 条可立即复用的打法,不超过 60 字。",
119
+ system="你是账号增长拆解专家。")
120
+ except Exception:
121
+ ai_note = ""
122
+ return {"report": report, "ai_note": ai_note}
123
+
124
+
125
+ class BloggerTeardownAgent(BaseAgent):
126
+ module_id = "13"
127
+ name = "博主账号深度拆解官"
128
+ layer = "L2"
129
+ priority = "P2"
130
+ description = "拆解对标账号的定位、选题、结构与转化路径"
131
+ input_schema = {"account": "对标账号"}
132
+ output_keys = {"report": "拆解报告"}
133
+ run_logic = staticmethod(run_logic_13)
134
+
135
+ def persist(self, output, task):
136
+ from core import models
137
+ models.insert_asset({
138
+ "content_id": f"A{int(time.time()) % 100000000}",
139
+ "content_type": "账号拆解",
140
+ "topic": task.input_json.get("account", ""),
141
+ "script": json.dumps(output.get("report", {}), ensure_ascii=False),
142
+ "publish_status": "draft",
143
+ })
144
+
145
+
146
+ # ---------------------------------------------------------------- 14
147
+ def run_logic_14(data, llm=None):
148
+ """AI 短视频自动剪辑:素材自动剪辑成片。"""
149
+ clips = data.get("clips") or ["clip_a.mp4", "clip_b.mp4", "clip_c.mp4"]
150
+ script = data.get("script", "")
151
+ template = data.get("template", "口播标准模板")
152
+ video = {
153
+ "asset_id": f"V{int(time.time()) % 100000000}",
154
+ "clips_used": clips,
155
+ "template": template,
156
+ "duration_sec": 45,
157
+ "subtitles": "auto(准确率≥95%)",
158
+ "status": "rendered",
159
+ "rendered_at": _ts(),
160
+ }
161
+ ai_note = ""
162
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
163
+ try:
164
+ ai_note = llm.complete(
165
+ f"脚本要点:{script[:100]},给出剪辑节奏建议,不超过 50 字。",
166
+ system="你是视频剪辑师。")
167
+ except Exception:
168
+ ai_note = ""
169
+ return {"video": video, "ai_note": ai_note}
170
+
171
+
172
+ class AutoEditorAgent(BaseAgent):
173
+ module_id = "14"
174
+ name = "AI短视频自动剪辑师"
175
+ layer = "L2"
176
+ priority = "P1"
177
+ description = "素材自动剪辑成片、批量出片"
178
+ input_schema = {"clips": "素材列表", "script": "脚本", "template": "模板"}
179
+ output_keys = {"video": "成片元数据"}
180
+ run_logic = staticmethod(run_logic_14)
181
+
182
+ def persist(self, output, task):
183
+ from core import models
184
+ video = output.get("video", {})
185
+ models.insert_asset({
186
+ "content_id": video.get("asset_id", f"A{int(time.time()) % 100000000}"),
187
+ "content_type": "成片",
188
+ "topic": task.input_json.get("script", "")[:60],
189
+ "script": json.dumps(video, ensure_ascii=False),
190
+ "asset_url": video.get("asset_id", ""),
191
+ "publish_status": video.get("status", "draft"),
192
+ })
193
+
194
+
195
+ # ---------------------------------------------------------------- 15
196
+ def run_logic_15(data, llm=None):
197
+ """公众号自动运营:内容生成与定时发布。"""
198
+ topic = data.get("topic", "AI 获客")
199
+ schedule = data.get("schedule", "明日 08:00")
200
+ article = {
201
+ "title": f"深度:{topic}的完整打法(建议收藏)",
202
+ "body": f"一、为什么{topic}是当下最大的红利;二、三步落地方案;三、真实数据复盘。",
203
+ "publish_time": schedule,
204
+ "status": "scheduled",
205
+ "created_at": _ts(),
206
+ }
207
+ ai_note = ""
208
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
209
+ try:
210
+ ai_note = llm.complete(
211
+ f"公众号选题 {topic},给 1 个标题备选,不超过 40 字。",
212
+ system="你是公众号主编。")
213
+ except Exception:
214
+ ai_note = ""
215
+ return {"article": article, "ai_note": ai_note}
216
+
217
+
218
+ class GzhPublisherAgent(BaseAgent):
219
+ module_id = "15"
220
+ name = "公众号自动运营发布官"
221
+ layer = "L2"
222
+ priority = "P1"
223
+ description = "公众号内容生成、排期与定时发布"
224
+ input_schema = {"topic": "选题", "schedule": "发布时间"}
225
+ output_keys = {"article": "文章与排期"}
226
+ run_logic = staticmethod(run_logic_15)
227
+
228
+ def persist(self, output, task):
229
+ from core import models
230
+ article = output.get("article", {})
231
+ models.insert_asset({
232
+ "content_id": f"A{int(time.time()) % 100000000}",
233
+ "content_type": "文章",
234
+ "topic": article.get("title", ""),
235
+ "script": article.get("body", ""),
236
+ "publish_status": article.get("status", "draft"),
237
+ })
@@ -0,0 +1,148 @@
1
+ """L3 销售转化层:02 AI销售跟进销冠 / 04 客户聊天成交分析官 / 09 私域客户分层跟进官。"""
2
+ import json
3
+ import time
4
+ from datetime import datetime
5
+
6
+ from core.agent import BaseAgent
7
+
8
+
9
+ def _ts() -> str:
10
+ return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
11
+
12
+
13
+ # ---------------------------------------------------------------- 02
14
+ def run_logic_02(data, llm=None):
15
+ """销售跟进:按话术自动跟进、多轮触达客户。"""
16
+ customer = data.get("customer") or {"company_name": "示例公司", "contact_name": "王总"}
17
+ strategy = data.get("strategy", "标准 3 触达")
18
+ follow_up = {
19
+ "target": f"{customer.get('contact_name', '')}({customer.get('company_name', '')})",
20
+ "round": 1,
21
+ "message": f"您好,上次聊到的方案资料已整理好,方便发您参考吗?",
22
+ "channel": "企业微信",
23
+ "frequency_check": "24h 内仅 1 次,通过频控",
24
+ "next_action": "若 24h 未回复,执行第二轮价值提醒",
25
+ "need_human": True,
26
+ "at": _ts(),
27
+ }
28
+ ai_note = ""
29
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
30
+ try:
31
+ ai_note = llm.complete(
32
+ f"客户 {json.dumps(customer, ensure_ascii=False)},策略 {strategy},生成第二轮跟进话术,不超过 60 字。",
33
+ system="你是顶级销售。")
34
+ except Exception:
35
+ ai_note = ""
36
+ return {"follow_up": follow_up, "ai_note": ai_note}
37
+
38
+
39
+ class FollowUpAgent(BaseAgent):
40
+ module_id = "02"
41
+ name = "AI销售跟进销冠"
42
+ layer = "L3"
43
+ priority = "P0"
44
+ description = "按话术自动跟进、多轮触达客户(对外动作需人工确认)"
45
+ input_schema = {"customer": "客户对象(company_name/contact_name)", "strategy": "跟进策略"}
46
+ output_keys = {"follow_up": "跟进消息与下一步"}
47
+ need_human = True
48
+ run_logic = staticmethod(run_logic_02)
49
+
50
+ def persist(self, output, task):
51
+ from core import models
52
+ c = task.input_json.get("customer", {})
53
+ fu = output.get("follow_up", {})
54
+ models.upsert_customer(
55
+ company_name=c.get("company_name", ""),
56
+ contact_name=c.get("contact_name", ""),
57
+ contact_phone=c.get("contact_phone", ""),
58
+ remark=fu.get("message", ""),
59
+ tier="untiered",
60
+ )
61
+
62
+
63
+ # ---------------------------------------------------------------- 04
64
+ def run_logic_04(data, llm=None):
65
+ """聊天成交分析:分析聊天记录,诊断卡点,输出建议话术。"""
66
+ transcript = data.get("transcript", "客户:价格有点高;销售:可以谈;客户:我再想想。")
67
+ diagnosis = {
68
+ "pain_points": ["价格敏感"],
69
+ "blockers": ["价值量化不足", "未给决策紧迫感"],
70
+ "suggested_scripts": [
71
+ "先量化 ROI:按当前产能算 3 个月回本",
72
+ "再给限时政策:本月底前签约送首月服务",
73
+ ],
74
+ "confidence": "中高(抽样人工复核)",
75
+ "analyzed_at": _ts(),
76
+ }
77
+ ai_note = ""
78
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
79
+ try:
80
+ ai_note = llm.complete(
81
+ f"聊天记录:{transcript[:200]},指出最关键的一个成交卡点,不超过 50 字。",
82
+ system="你是成交分析专家。")
83
+ except Exception:
84
+ ai_note = ""
85
+ return {"diagnosis": diagnosis, "ai_note": ai_note}
86
+
87
+
88
+ class ChatAnalysisAgent(BaseAgent):
89
+ module_id = "04"
90
+ name = "客户聊天成交分析官"
91
+ layer = "L3"
92
+ priority = "P0"
93
+ description = "分析聊天记录,诊断成交卡点,输出建议话术"
94
+ input_schema = {"transcript": "聊天记录 / 通话转写"}
95
+ output_keys = {"diagnosis": "卡点诊断与建议话术"}
96
+ run_logic = staticmethod(run_logic_04)
97
+
98
+
99
+ # ---------------------------------------------------------------- 09
100
+ def run_logic_09(data, llm=None):
101
+ """私域分层跟进:客户分层、差异化跟进计划。"""
102
+ customers = data.get("customers") or [
103
+ {"customer_id": "C1", "company_name": "客户A", "contact_name": "李总", "contact_phone": "13800000001"},
104
+ {"customer_id": "C2", "company_name": "客户B", "contact_name": "张总", "contact_phone": "13800000002"},
105
+ {"customer_id": "C3", "company_name": "客户C", "contact_name": "陈总", "contact_phone": "13800000003"},
106
+ ]
107
+ tiers = []
108
+ for i, c in enumerate(customers):
109
+ tier = ["A", "B", "C"][i % 3]
110
+ tiers.append({"customer_id": c["customer_id"], "company_name": c["company_name"], "tier": tier})
111
+ plan = [
112
+ {"tier": "A", "action": "每周 1 次价值触达 + 需求深挖", "interval": "7 天"},
113
+ {"tier": "B", "action": "每月 1 次方案更新 + 节点关怀", "interval": "30 天"},
114
+ {"tier": "C", "action": "季度盘点,重新评估意向", "interval": "90 天"},
115
+ ]
116
+ ai_note = ""
117
+ if llm is not None and getattr(llm, "provider", "mock") != "mock":
118
+ try:
119
+ ai_note = llm.complete(
120
+ f"客户列表 {json.dumps(customers, ensure_ascii=False)},给出分层建议说明,不超过 60 字。",
121
+ system="你是私域运营专家。")
122
+ except Exception:
123
+ ai_note = ""
124
+ return {"tiers": tiers, "follow_up_plan": plan, "ai_note": ai_note}
125
+
126
+
127
+ class TieringAgent(BaseAgent):
128
+ module_id = "09"
129
+ name = "私域客户分层跟进官"
130
+ layer = "L3"
131
+ priority = "P0"
132
+ description = "私域客户分层、差异化跟进与维护"
133
+ input_schema = {"customers": "客户列表"}
134
+ output_keys = {"tiers": "分层标签", "follow_up_plan": "跟进计划"}
135
+ run_logic = staticmethod(run_logic_09)
136
+
137
+ def persist(self, output, task):
138
+ from core import models
139
+ tier_map = {t["customer_id"]: t["tier"] for t in output.get("tiers", [])}
140
+ for c in task.input_json.get("customers", []):
141
+ models.upsert_customer(
142
+ customer_id=c.get("customer_id"),
143
+ company_name=c.get("company_name", ""),
144
+ contact_name=c.get("contact_name", ""),
145
+ contact_phone=c.get("contact_phone", ""),
146
+ tier=tier_map.get(c.get("customer_id"), "untiered"),
147
+ remark="分层跟进",
148
+ )