- Add company module (3-tier org, CEO planning, parallel departments) - Add company orchestrator, knowledge extractor, presets, scheduler - Add company API endpoints, models, and frontend views - Add 今天吃啥 PWA app (69 dishes, real images, offline support) - Add team_projects output directory structure - Add unified manage.ps1 for service lifecycle - Add Windows startup guide v1.0 - Add TTS troubleshooting doc - Update frontend (AgentChat UX overhaul, new views) - Update backend (voice engine fix, multi-tenant, RBAC) - Remove deprecated startup scripts and old docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
123 lines
4.6 KiB
Python
123 lines
4.6 KiB
Python
"""
|
|
洞察分析器 — 跨项目统计分析,生成最佳实践建议
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from typing import Dict, List, Any
|
|
|
|
from sqlalchemy.orm import Session
|
|
from app.models.company import CompanyProject
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def analyze_company(company_id: str, db: Session) -> Dict[str, Any]:
|
|
"""分析公司所有项目,生成洞察报告。"""
|
|
projects = (
|
|
db.query(CompanyProject)
|
|
.filter(CompanyProject.company_id == company_id)
|
|
.order_by(CompanyProject.created_at.desc())
|
|
.all()
|
|
)
|
|
|
|
if not projects:
|
|
return {
|
|
"dept_stats": [],
|
|
"collaboration_pairs": [],
|
|
"avg_rounds": 0,
|
|
"avg_cost": 0,
|
|
"failure_reasons": [],
|
|
"recommendations": ["还没有项目数据,执行一些项目后这里会显示分析结果"],
|
|
}
|
|
|
|
total = len(projects)
|
|
completed = [p for p in projects if p.status == "completed"]
|
|
failed = [p for p in projects if p.status == "failed"]
|
|
success_rate = round(len(completed) / total * 100, 1) if total > 0 else 0
|
|
|
|
# Department statistics
|
|
dept_stats: Dict[str, Dict] = {}
|
|
for p in projects:
|
|
ceo_plan = p.ceo_plan or {}
|
|
dept_plans = ceo_plan.get("departments", [])
|
|
review_scores = p.review_scores or []
|
|
|
|
for dp in dept_plans:
|
|
name = dp.get("department_name", "unknown")
|
|
if name not in dept_stats:
|
|
dept_stats[name] = {"name": name, "execution_count": 0, "success_count": 0, "avg_score": 0, "total_score": 0, "score_count": 0}
|
|
dept_stats[name]["execution_count"] += 1
|
|
|
|
# Match scores
|
|
for s in review_scores:
|
|
name = s.get("name", "")
|
|
if name in dept_stats:
|
|
dept_stats[name]["total_score"] += s.get("score", 0)
|
|
dept_stats[name]["score_count"] += 1
|
|
if s.get("pass"):
|
|
dept_stats[name]["success_count"] += 1
|
|
|
|
# Calculate averages
|
|
for k, v in dept_stats.items():
|
|
if v["score_count"] > 0:
|
|
v["avg_score"] = round(v["total_score"] / v["score_count"], 1)
|
|
v["success_rate"] = round(v["success_count"] / v["execution_count"] * 100, 1) if v["execution_count"] > 0 else 0
|
|
|
|
# Collaboration pairs (dependencies)
|
|
dep_pairs: Dict[str, int] = {}
|
|
for p in projects:
|
|
ceo_plan = p.ceo_plan or {}
|
|
dept_plans = ceo_plan.get("departments", [])
|
|
for dp in dept_plans:
|
|
deps = dp.get("dependencies", [])
|
|
if isinstance(deps, str):
|
|
deps = [deps] if deps else []
|
|
for d in deps:
|
|
pair_key = f"{d}→{dp.get('department_name', '')}"
|
|
dep_pairs[pair_key] = dep_pairs.get(pair_key, 0) + 1
|
|
|
|
top_pairs = sorted(dep_pairs.items(), key=lambda x: x[1], reverse=True)[:5]
|
|
collaboration_pairs = [{"pair": k, "count": v} for k, v in top_pairs]
|
|
|
|
# Rounds
|
|
avg_rounds = round(sum(int(p.round_count or "1") for p in projects) / total, 1) if total > 0 else 0
|
|
|
|
# Failure reasons (from review scores)
|
|
failure_reasons = []
|
|
for p in projects:
|
|
scores = p.review_scores or []
|
|
for s in scores:
|
|
if not s.get("pass", True):
|
|
failure_reasons.append({
|
|
"project": p.name,
|
|
"department": s.get("name", ""),
|
|
"score": s.get("score", 0),
|
|
"feedback": s.get("feedback", "")[:200],
|
|
})
|
|
|
|
# Recommendations
|
|
recommendations = []
|
|
if success_rate < 50:
|
|
recommendations.append("成功率偏低,建议检查项目目标是否与公司能力匹配")
|
|
if avg_rounds > 1.5:
|
|
recommendations.append(f"平均迭代 {avg_rounds} 轮,建议优化首轮规划质量,减少返工")
|
|
low_depts = [k for k, v in dept_stats.items() if v.get("avg_score", 0) < 6 and v["score_count"] > 0]
|
|
if low_depts:
|
|
recommendations.append(f"以下部门评分偏低,建议优化其 Agent 配置或成员组成: {', '.join(low_depts)}")
|
|
if not recommendations:
|
|
recommendations.append("整体表现良好,继续保持当前的项目执行模式")
|
|
|
|
return {
|
|
"total_projects": total,
|
|
"completed_projects": len(completed),
|
|
"failed_projects": len(failed),
|
|
"success_rate": success_rate,
|
|
"dept_stats": list(dept_stats.values()),
|
|
"collaboration_pairs": collaboration_pairs,
|
|
"avg_rounds": avg_rounds,
|
|
"avg_cost": 0, # Token cost tracking requires execution log integration
|
|
"failure_reasons": failure_reasons[:10],
|
|
"recommendations": recommendations,
|
|
}
|