- SSML TTS with emotional styles (_build_ssml, mstts:express-as) and natural pauses - Agent avatar support: DB migration, API, frontend emoji/URL rendering - AgentChat UX: highlight.js code blocks, copy buttons, streaming cursor, char count, auto-title, keyboard shortcuts, message feedback (thumbs), undo delete, mobile responsive - Virtual company: M2 control, tier-3/4 capabilities, per-dept session fix, deliverable validator, insight analyzer enhancements - New services: agent_profiler, deliverable_validator, redis_task_registry - Android: auth refactor, launcher icons, network security config, update manager - Frontend: useSpeechQueue composable, Agents/AgentConfig/AgentTest enhancements - Various backend fixes and expanded test coverage Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
15 KiB
15 KiB
虚拟公司模块分析报告(K3)
分析日期:2026-07-27 ・ 范围:
/companies全模块(前端 CompanyBuilder / CompanyControlRoom / CompanyPresets + 后端 companies.py / company_orchestrator / company_runner / company_ws) 分析方法:源码静态走查(前后端并行探查),未做运行时压测
一、模块现状概览
1.1 架构
浏览器
├─ CompanyBuilder.vue(3778 行巨型单文件)── /execute/stream(SSE,请求协程内跑)
└─ CompanyControlRoom.vue ── WS /ws/company-projects/{pid}(since_seq 断点续传,>8s 降级 1.5s 轮询)
│
后端
├─ companies.py ~30 个端点:CRUD / 执行×3 / 运行时控制×8 / 知识 / 调度 / 监管 / 导出
├─ company_runner.py 后台 asyncio.Task + 进程内控制态(pause/approve/skip/cancel)+ 信号量 3
└─ company_orchestrator.py
Phase1 CEO 规划(ReAct max_iter=3,注入学习闭环 top5 知识)
Phase2 波次并行(依赖分组 → asyncio.gather,部门信号量 4,per-dept 独立 DB Session)
Phase3 CEO 评审打分(单次 LLM 调用,2 次重试 + parse_failed 兜底)
四档 handoff 上下文传递 / 学习闭环沉淀 / 按部门模型覆盖 / 单项目报告导出
1.2 已完成能力(值得肯定)
- 三阶段执行 + 多轮返工(max_rounds=3)+ 依赖波次并行,设计完整
- M2 运行时控制:暂停/继续/停止/跳过/审批门/单部门取消与重做
- 限额熔断:max_cost / max_duration 三档检查
- 控制室:WS 断点续传、ECharts DAG、部门白盒折叠面板、token+成本实时合计
- 学习闭环:自动沉淀 4 类知识并注入下次 CEO 规划
二、问题清单(按严重度分级)
P0 — 安全 / 正确性,必须修
| # | 问题 | 位置 |
|---|---|---|
| 1 | XSS 风险:4 处 v-html 仅经自写正则 renderMarkdown/renderSummary,无 HTML 转义、未走 DOMPurify(违反项目既定规范) |
CompanyBuilder.vue:453/488/508/615 |
| 2 | 鉴权大面积缺失:knowledge 增删查、schedules CRUD/trigger、publish/unpublish、supervisor 三端点、list_projects、delete_company 等均未做归属校验,任何登录用户可读/改/删他人公司资源 | companies.py:920-1185 多个端点 |
| 3 | 假"停止"按钮:Builder 内 stopExecution 仅 abort 前端 fetch,后端任务继续跑,用户被误导 |
CompanyBuilder.vue:1678 |
| 4 | 进程内状态不可扩展:_RUNNING/_CONTROL/_PROJECT_SEM/_dept_sem 全是进程内字典,多 worker 部署后 pause/cancel/approve 全部失效(代码注释自承"前提单 uvicorn worker") |
company_runner.py:30/62/80, orchestrator.py:227 |
| 5 | SSE execute/stream 断线即任务消失,且占用请求协程 DB session 长跑 | companies.py:491-500 |
| 6 | approve 决策大小写敏感:非白名单值一律映射为 rejected,极易误判 | companies.py:1274 |
| 7 | Kimi K3 / 推理模型 temperature 冲突:company_orchestrator.py 3 处硬编码 temperature≠1(CEO 规划 0.4、CEO 审查 0.2、TeamOrchestrator 内部传默认值),若 CEO Agent 或部门 Agent 配置为 Kimi K3 (moonshot) 则 LLM 调用直接 400 报错——与 agent_chat.py 刚修完的 bug 同根 |
orchestrator.py:379/1572, team_orchestrator.py |
| 8 | 非流式 execute() 缺 M2 防护:旧版 /companies/{id}/execute 端点仍暴露在 API 中,未受暂停/熔断/审批门/部门信号量任何保护,asyncio.gather 直跑并行;绕过全部安全网,成本/稳定性风险 |
orchestrator.py:789-948, companies.py:474-500 |
| 9 | _parse_ceo_json 静默返回 {}:CEO 规划 JSON 解析失败时返回空 dict,departments 为空则整个项目空跑一轮后"成功"结束,无错误提示——用户以为执行了实际什么都没做 |
orchestrator.py:131, 880-945 |
P1 — 功能缺口 / 体验短板
| # | 问题 | 位置 |
|---|---|---|
| 10 | 无重新执行入口:失败项目不能一键以原目标重跑 | CompanyBuilder.vue:557-563 |
| 11 | 项目对比形同虚设:勾选后仅并排显示名称+状态 tag,无成本/轮次/评分/交付物对比 | CompanyBuilder.vue:568-576 |
| 12 | 无时间轴回放:rawEvents 全量在内存(上限 5000)但无 scrubber/步进回放 UI | companyExecution.ts:131 |
| 13 | 两套执行链路并存(Builder SSE + 控制室 WS),SSE 链丢弃工具入参与真实 token | companyExecution.ts:7 |
| 14 | 控制室无知识沉淀展示,执行完无法就地看学习闭环产出 | CompanyControlRoom.vue |
| 15 | 无项目级耗时/成本趋势图(insights 只有部门维度) | CompanyBuilder.vue 洞察 Tab |
| 16 | 列表无分页/搜索(公司卡片、项目表 max-height 240px 硬限、知识列表全量渲染) | CompanyBuilder.vue 多处 |
| 17 | N+1 请求:公司列表逐个串行拉 stats | CompanyBuilder.vue:1389-1393 |
| 18 | 多处 catch { /* ignore */ } 静默吞错,加载失败无提示 |
CompanyBuilder.vue:1376/1392/1414 等 |
| 19 | 移动端零适配:无 @media,控制室固定 300px 1fr 340px 三栏 |
CompanyControlRoom.vue:383 |
| 20 | WS token 拼 URL query,易被代理日志留存 | companies.ts:141 |
| 21 | 共享 db_orch Session 并发竞态:company_runner.py:295 的 Session 被同波并行部门协程共享,SQLAlchemy 在并发 await 交错下可能交叉污染事务态——三档-b 信号量降低但不消除风险;_run_department_stream 已改 per-dept session 但 orchestrator 自身操作仍用共享 session |
company_runner.py:295, orchestrator.py:223 |
| 22 | 循环依赖处理粗暴:所有剩余部门依赖都未满足时直接全部执行,导致下游在缺上游产出的情况下盲目工作,浪费 LLM 成本且输出质量差;应做拓扑验证 + 注入"假设性上游数据"提示 | orchestrator.py:1243-1253 |
| 23 | 非流式 _run_department 与流式版逻辑高度重复(~160行 vs ~165行),非流式版缺 cost tracking / M2-c cancel / live state 监控,维护时需同步修改两处 |
orchestrator.py:440-491 vs 493-657 |
| 24 | 跨部门文件交接断裂(真跑实证 2026-07-27):四档-①交接只传文本摘要,产物文件按 team_projects/{team_id}/ 隔离,下游部门看不到上游文件;CEO 规划把"HTML 原型"同时派给产品部+交付部 → 两部门各自隔离造了一套原型(产品部 A 套 PRD 忠实 17 路由 / 交付部 B 套自创页面偏离 PRD),交付部 QA 对象是自己那套而非上游成果——重复花钱且交付分叉。根因两层:workspace 按 team_id 物理隔离 + CEO 规划未指定"交付物归属唯一部门、下游复用其文件路径" |
team_orchestrator.py 工作区机制, orchestrator.py _build_dept_context(仅文本注入) |
| 25 | 部门无工具系统性故障止损(真跑实证 2026-07-27):QA agent 调用 execute_code/grep_search 持续返回 __import__ not found(Agent 层 P0-3 沙箱症状的线上实锤),agent 在 ReAct 循环里无限换工具重试,空转 ~11000 事件 / ¥5.64(占项目 57% 成本)直至拖满 max_duration 超时熔断、CEO 终评被挤掉。部门层缺少"同工具连续 N 次同质失败 → 降级/跳过/上报"的熔断器 |
team_orchestrator.py ReAct 循环(无失败模式检测) |
P2 — 代码质量 / 隐患
| # | 问题 | 位置 |
|---|---|---|
| 26 | N+1 查询:list 接口逐公司 count 部门;export/编排逐 member 懒加载 | companies.py:111-115, 633-662; orchestrator.py:337-348 |
| 27 | CEO prompt 英文硬编码、默认模型 deepseek-v4-pro、截断魔数 2000/6000、./company_projects/ 相对路径 CWD 依赖 |
orchestrator.py:40-85/378/395/901 |
| 28 | 错误吞没:register_schedule except: pass;学习沉淀失败完全静默;CEO 评审任何异常落入 parse_failed 根因丢失 |
companies.py:996-1026; orchestrator.py:275-280 |
| 29 | round_count 用 String(10) 存数字,统计排序需转型 |
models/company.py:71 |
| 30 | WS 每 0.8s db.expire_all(),多客户端形成稳定 QPS 放大 |
company_ws.py:98 |
| 31 | _safe_name 未防 Windows 保留名(CON/PRN)与超长路径 |
orchestrator.py:1623-1628 |
| 32 | CompanyBuilder.vue 3778 行单文件承担 7 个职责,急需拆分 | — |
| 33 | 知识提取纯规则式,缺乏语义理解:company_knowledge_extractor.py 用硬编码领域关键词正则做 tag 提取,_select_relevant_knowledge 靠关键词命中次数加权评分——两个语义相关但未用同一套词的条目被误判为不相关(假阴性);CEO 规划注入的"历史经验"质量受限于关键词匹配精度 |
company_knowledge_extractor.py, orchestrator.py:136-210 |
| 34 | CEO 审查仅 1 次纠正性重试:顽固 JSON 格式错误(弱模型常见)可能不足以恢复;parse_failed 兜底从 raw text 用正则提取 overall_score,数值不可靠 |
orchestrator.py:1584-1619 |
| 35 | __import__("time") inline import 散落 40+ 处:可读性差,应统一文件顶部 import time as _time |
orchestrator.py 全文 |
三、迭代建议(按优先级)
第一波:安全与正确性(1-2 天,不改架构)
- 统一鉴权:给 companies.py 所有端点过一遍
_assert_company_owner(建议改为依赖注入Depends,从机制上防遗漏);delete_company放行 admin - XSS 治理:renderMarkdown/renderSummary 输出统一走 DOMPurify.sanitize(项目已有先例)
- approve 决策归一化:
.lower().strip()后白名单匹配,非法值返回 422 而非静默当 rejected - 去掉假停止:Builder 的 stopExecution 改调后端
/stop端点(控制室已有正确实现,复用即可) - 执行入口收敛:Builder 的
/execute/stream入口下线或改为 "创建后跳控制室",只留/execute/async+ WS 一条路(顺带解决 P0-5 与 P1-13) - Kimi K3 temperature 归一化:在
AgentLLMConfig或_LLMClient层统一做 provider=moonshot → temperature=1 的归一化(company_orchestrator 3 处 + TeamOrchestrator 1 处),与 agent_chat.py 已修方案一致 - 非流式
execute()加 M2 防护或标记废弃:至少阻断其直接暴露,防止绕过安全网 - CEO 规划空计划阻断:
_parse_ceo_json返回{}或 departments 为空时,直接报错事件而非静默成功(P0-9 修复)
第二波:执行体验闭环(3-5 天)
- 重新执行:历史项目加"以原目标重跑"按钮(复制 goal/ceoPlan/maxRounds 调 execute/async 并跳控制室)
- 项目对比真实化:对比抽屉展示 状态/轮次/成本/token/评分雷达/交付物清单 diff——后端
/projects已返回这些字段,纯前端工作 - 时间轴回放:控制室基于 rawEvents(seq 有序)加进度条 scrubber + 步进/播放,复用 applyEvent 做状态重建
- 控制室接学习闭环:项目完成后侧栏展示本项目沉淀的知识条目(GET /knowledge?project_id=),并可一键采纳/删除
- 合并
_run_department与_run_department_stream:非流式版改为缓冲流式事件到列表,去重 ~160 行重复逻辑,消除两者能力不一致 - 循环依赖智能处理:CEO 规划阶段加拓扑排序验证依赖图无环;运行时循环依赖不再是粗暴全执行,改为注入"上游未完成,基于假设数据工作"提示
- 跨部门文件交接(治 P1-24):短期——
_build_dept_context注入上游部门的工作区绝对路径 + 产物文件清单(不只是文本摘要),CEO 规划 prompt 加硬约束"同一交付物只归属一个部门,下游部门复用其文件路径做 QA/集成";中期——公司级共享 workspace(company_projects/{project_id}/)替代 per-team 隔离 - 工具故障熔断器(治 P1-25):TeamOrchestrator ReAct 循环加失败模式检测——同工具连续 ≥3 次同质错误(相同 error 签名)即停用该工具并注入"该工具当前不可用,请用其它方式或如实说明无法完成"提示;同时修 Agent 层 P0-3 的 execute_code 沙箱(Agent A1 计划已列)
第三波:可观测与规模化(1 周+)
- 运行控制状态外置 Redis:pause/approve/cancel 信号量改 Redis pub/sub + 状态键,为多 worker 铺路(路线图三档-c 早已规划此项)
- per-dept Session 全量隔离:orchestrator 自身 DB 操作也切换为每次独立获取 session(类似
_heartbeat临时 session 模式),根除共享 db_orch 竞态 - 项目级趋势图:stats 接口补时间序列(每日项目数/成本/成功率),洞察 Tab 加趋势折线
- WS 优化:心跳替代
expire_all轮询(事件驱动推送);token 从 query 挪到首条消息或子协议 - 列表分页/搜索:公司、项目、知识三个列表统一分页组件 + 关键词过滤
- 拆分 CompanyBuilder.vue:按职责拆成 CompanyList / CompanyOrgChart / ProjectLauncher / KnowledgePanel / InsightsPanel / SchedulePanel 六个子组件
第四波:质量加固与智能化(持续)
- N+1 治理:list/export/编排三处改 joinedload/子查询
- 硬编码收口:CEO prompt 挪配置、魔数常量化、产出目录走 settings
- 错误可观测:静默 catch 全部补 logger.warning + 关键路径前端 ElMessage 提示
round_count迁移为 Integer(alembic)_safe_name过滤 Windows 保留名 + 长度按字节截断- LLM 驱动的知识提取:替代当前规则式关键词提取,让 LLM 做知识条目摘要(标题+要点+语义标签),同时升级
_select_relevant_knowledge为 embedding 相似度匹配 - LLM 驱动的洞察分析:让 LLM 读多项目的 review_scores + ceo_plan 做跨项目模式识别(部门组合成功率、依赖类型风险、项目描述→成功率关联)
dept_token_usage改用真实 token 数(从 Agent final 事件取),消除 dept_budget_exceeded 警告基于幻数的问题
四、结论
虚拟公司模块功能纵深已经很好(三阶段+运行时控制+学习闭环在同类型产品里属于超额完成),当前的主要矛盾不在"缺功能"而在:
- 安全债——鉴权缺失与 XSS 是上线阻断级问题(第一波必须清)
- 执行链路分裂——SSE/WS 两套并存制造假停止与能力不一致,收敛到
/execute/async+ 控制室是唯一正确的路 - 对比/回放两个规划内功能未落地——数据都在库里,属纯前端工作,性价比最高
- 后端深层竞态与兼容性——共享 Session 并发风险 + temperature 兼容性是延迟炸弹,尽早排雷
本报告整合了 K3 自主分析(前端+安全+架构)与人工后端走查(竞态+执行器+知识提取),共梳理 35 个问题 + 25 项迭代建议,按四波优先级推进。其中 P1-24/P1-25 为 2026-07-27 真跑实证(验收标准驱动重跑设计任务)新发现:验收标准写入 goal 后产物质量从"纯 Markdown 规格"跃升为"真 HTML 高保真原型"(假设验证成立),但同时照出跨部门文件交接断裂与工具故障无止损两个系统性缺口。
建议严格按"第一波 → 第二波"顺序推进,第三波的 Redis 外置与多 worker 部署绑定进行。