- 日报/周报/月报改为结构化卡片推送(column_set布局) - 新增 report:daily/weekly/monthly 权限到角色管理 - 产出统计只算中期制作阶段动画秒数 - 效率之星改为跨项目加权通过率 - AI点评补充风险数据源 - 禁用多余admin账号,股东角色加报告权限 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
98 lines
3.3 KiB
Python
98 lines
3.3 KiB
Python
"""豆包大模型服务 —— 通过火山引擎 ARK 平台调用"""
|
||
import logging
|
||
from config import ARK_API_KEY, ARK_MODEL, ARK_BASE_URL
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
# 延迟初始化,避免无 Key 时报错
|
||
_client = None
|
||
|
||
|
||
def _get_client():
|
||
global _client
|
||
if _client is None and ARK_API_KEY:
|
||
from openai import OpenAI
|
||
_client = OpenAI(api_key=ARK_API_KEY, base_url=ARK_BASE_URL)
|
||
return _client
|
||
|
||
|
||
def generate_report_summary(data_context: str, report_type: str) -> str:
|
||
"""
|
||
调用豆包生成报告摘要
|
||
:param data_context: 数据库汇总数据(纯文本)
|
||
:param report_type: daily / weekly / monthly
|
||
:return: AI 生成的 markdown 摘要,失败时返回空字符串
|
||
"""
|
||
client = _get_client()
|
||
if not client:
|
||
logger.warning("豆包 AI 未配置 API Key,跳过摘要生成")
|
||
return ""
|
||
|
||
type_labels = {"daily": "日报", "weekly": "周报", "monthly": "月报"}
|
||
label = type_labels.get(report_type, "报告")
|
||
|
||
system_prompt = (
|
||
"你是 AirLabs 动画团队的项目管理助手。"
|
||
"请根据提供的数据,用简洁的中文生成一段{label}点评。\n"
|
||
"重要规则:\n"
|
||
"1. 不要重复罗列原始数据(项目数、提交人次、未提交人员等已在报告上方展示)\n"
|
||
"2. 直接给出分析洞察和可执行建议\n"
|
||
"3. 如果有风险项目,重点提醒并给出具体改进方向\n"
|
||
"4. 语言简练专业,适合管理层阅读\n"
|
||
"5. 不要使用标题(如 ## 核心数据概览),直接写正文\n"
|
||
"6. 总字数控制在 200 字以内"
|
||
).format(label=label)
|
||
|
||
try:
|
||
response = client.chat.completions.create(
|
||
model=ARK_MODEL,
|
||
messages=[
|
||
{"role": "system", "content": system_prompt},
|
||
{"role": "user", "content": f"以下是{label}数据,请生成总结:\n\n{data_context}"},
|
||
],
|
||
temperature=0.7,
|
||
max_tokens=1024,
|
||
timeout=30,
|
||
)
|
||
return response.choices[0].message.content.strip()
|
||
except Exception as e:
|
||
logger.error(f"豆包 AI 调用失败: {e}")
|
||
return ""
|
||
|
||
|
||
def generate_risk_analysis(project_data: str) -> str:
|
||
"""
|
||
调用豆包分析项目风险
|
||
:param project_data: 项目数据文本
|
||
:return: AI 生成的风险分析,失败时返回空字符串
|
||
"""
|
||
client = _get_client()
|
||
if not client:
|
||
return ""
|
||
|
||
system_prompt = (
|
||
"你是 AirLabs 动画团队的项目风险分析专家。"
|
||
"请根据项目数据,分析风险原因并给出改进建议。"
|
||
"要求:\n"
|
||
"1. 分析要具体,基于数据说话\n"
|
||
"2. 建议要可执行\n"
|
||
"3. 使用中文,简练专业\n"
|
||
"4. 总字数控制在 150 字以内"
|
||
)
|
||
|
||
try:
|
||
response = client.chat.completions.create(
|
||
model=ARK_MODEL,
|
||
messages=[
|
||
{"role": "system", "content": system_prompt},
|
||
{"role": "user", "content": f"项目数据:\n\n{project_data}"},
|
||
],
|
||
temperature=0.7,
|
||
max_tokens=512,
|
||
timeout=30,
|
||
)
|
||
return response.choices[0].message.content.strip()
|
||
except Exception as e:
|
||
logger.error(f"豆包 AI 风险分析失败: {e}")
|
||
return ""
|