feat: implement logging and refine agent core, execution, and prompts.
This commit is contained in:
@@ -208,13 +208,14 @@ class DataAnalysisAgent:
|
|||||||
"continue": True,
|
"continue": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
def analyze(self, user_input: str, files: List[str] = None) -> Dict[str, Any]:
|
def analyze(self, user_input: str, files: List[str] = None, session_output_dir: str = None) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
开始分析流程
|
开始分析流程
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
user_input: 用户的自然语言需求
|
user_input: 用户的自然语言需求
|
||||||
files: 数据文件路径列表
|
files: 数据文件路径列表
|
||||||
|
session_output_dir: 指定的会话输出目录(可选)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
分析结果字典
|
分析结果字典
|
||||||
@@ -225,10 +226,14 @@ class DataAnalysisAgent:
|
|||||||
self.current_round = 0
|
self.current_round = 0
|
||||||
|
|
||||||
# 创建本次分析的专用输出目录
|
# 创建本次分析的专用输出目录
|
||||||
|
if session_output_dir:
|
||||||
|
self.session_output_dir = session_output_dir
|
||||||
|
else:
|
||||||
self.session_output_dir = create_session_output_dir(
|
self.session_output_dir = create_session_output_dir(
|
||||||
self.base_output_dir, user_input
|
self.base_output_dir, user_input
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# 初始化代码执行器,使用会话目录
|
# 初始化代码执行器,使用会话目录
|
||||||
self.executor = CodeExecutor(self.session_output_dir)
|
self.executor = CodeExecutor(self.session_output_dir)
|
||||||
|
|
||||||
@@ -392,15 +397,25 @@ class DataAnalysisAgent:
|
|||||||
|
|
||||||
# 解析响应,提取最终报告
|
# 解析响应,提取最终报告
|
||||||
try:
|
try:
|
||||||
|
# 尝试解析YAML
|
||||||
yaml_data = self.llm.parse_yaml_response(response)
|
yaml_data = self.llm.parse_yaml_response(response)
|
||||||
|
|
||||||
|
# 情况1: 标准YAML格式,包含 action: analysis_complete
|
||||||
if yaml_data.get("action") == "analysis_complete":
|
if yaml_data.get("action") == "analysis_complete":
|
||||||
final_report_content = yaml_data.get("final_report", "报告生成失败")
|
final_report_content = yaml_data.get("final_report", response)
|
||||||
|
|
||||||
|
# 情况2: 解析成功但没字段,或者解析失败
|
||||||
else:
|
else:
|
||||||
final_report_content = (
|
# 如果内容看起来像Markdown报告(包含标题),直接使用
|
||||||
"LLM未返回analysis_complete动作,报告生成失败"
|
if "# " in response or "## " in response:
|
||||||
)
|
print("⚠️ 未检测到标准YAML动作,但内容疑似Markdown报告,直接采纳")
|
||||||
except:
|
final_report_content = response
|
||||||
# 如果解析失败,直接使用响应内容
|
else:
|
||||||
|
final_report_content = "LLM未返回有效报告内容"
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# 解析完全失败,直接使用原始响应
|
||||||
|
print(f"⚠️ YAML解析失败 ({e}),直接使用原始响应作为报告")
|
||||||
final_report_content = response
|
final_report_content = response
|
||||||
|
|
||||||
print("✅ 最终报告生成完成")
|
print("✅ 最终报告生成完成")
|
||||||
|
|||||||
55
main.py
55
main.py
@@ -1,15 +1,66 @@
|
|||||||
from data_analysis_agent import DataAnalysisAgent
|
from data_analysis_agent import DataAnalysisAgent
|
||||||
from config.llm_config import LLMConfig
|
from config.llm_config import LLMConfig
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from utils.create_session_dir import create_session_output_dir
|
||||||
|
|
||||||
|
class DualLogger:
|
||||||
|
"""同时输出到终端和文件的日志记录器"""
|
||||||
|
def __init__(self, log_dir, filename="log.txt"):
|
||||||
|
self.terminal = sys.stdout
|
||||||
|
log_path = os.path.join(log_dir, filename)
|
||||||
|
self.log = open(log_path, "a", encoding="utf-8")
|
||||||
|
|
||||||
|
def write(self, message):
|
||||||
|
self.terminal.write(message)
|
||||||
|
# 过滤掉生成的代码块,不写入日志文件
|
||||||
|
if "🔧 执行代码:" in message:
|
||||||
|
return
|
||||||
|
self.log.write(message)
|
||||||
|
self.log.flush()
|
||||||
|
|
||||||
|
def flush(self):
|
||||||
|
self.terminal.flush()
|
||||||
|
self.log.flush()
|
||||||
|
|
||||||
|
def setup_logging(log_dir):
|
||||||
|
"""配置日志记录"""
|
||||||
|
# 记录开始时间
|
||||||
|
logger = DualLogger(log_dir)
|
||||||
|
sys.stdout = logger
|
||||||
|
# 可选:也将错误输出重定向
|
||||||
|
# sys.stderr = logger
|
||||||
|
print(f"\n{'='*20} Run Started at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} {'='*20}\n")
|
||||||
|
print(f"📄 日志文件已保存至: {os.path.join(log_dir, 'log.txt')}")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
llm_config = LLMConfig()
|
llm_config = LLMConfig()
|
||||||
|
files = ["./UB IOV Support_TR.csv"]
|
||||||
|
analysis_requirement = """
|
||||||
|
基于所有运维工单,整理一份工单健康度报告,包括但不限于对所有车联网技术支持工单的全面数据分析,
|
||||||
|
深入挖掘工单处理过程中的关键问题、效率瓶颈及改进机会。涵盖工单状态、问题类型、模块分布、严重程度、责任人负载、车型分布、来源渠道及处理时长等多个维度。
|
||||||
|
通过多轮交叉分析与趋势洞察,为提升车联网服务质量、优化资源配置及降低运营风险提供数据驱动的决策依据,问题总揽,高频问题、重点问题分析,输出若干个重要的统计指标,并绘制相关图表。总结一份,车联网运维工单健康度报告,最后生成汇报给我。
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 在主函数中先创建会话目录,以便存放日志
|
||||||
|
# 默认输出目录为 'outputs'
|
||||||
|
base_output_dir = "outputs"
|
||||||
|
session_output_dir = create_session_output_dir(base_output_dir, analysis_requirement)
|
||||||
|
|
||||||
|
# 设置日志
|
||||||
|
setup_logging(session_output_dir)
|
||||||
|
|
||||||
# 如果希望强制运行到最大轮数,设置 force_max_rounds=True
|
# 如果希望强制运行到最大轮数,设置 force_max_rounds=True
|
||||||
agent = DataAnalysisAgent(llm_config, force_max_rounds=False)
|
agent = DataAnalysisAgent(llm_config, force_max_rounds=False)
|
||||||
files = ["./UB IOV Support_TR.csv"]
|
|
||||||
report = agent.analyze(
|
report = agent.analyze(
|
||||||
user_input="基于所有有关远程控制的问题,以及涉及车控APP的运维工单的数据,输出若干个重要的统计指标,并绘制相关图表。总结一份,车控APP,及远程控制工单健康度报告,最后生成汇报给我。",
|
user_input=analysis_requirement,
|
||||||
files=files,
|
files=files,
|
||||||
|
session_output_dir=session_output_dir
|
||||||
)
|
)
|
||||||
print(report)
|
print(report)
|
||||||
|
|
||||||
|
|||||||
131
prompts.py
131
prompts.py
@@ -5,7 +5,9 @@ data_analysis_system_prompt = """你是一个专业的数据分析助手,运
|
|||||||
- 当需要收集和分析已生成的图表时,使用 `collect_figures` 动作
|
- 当需要收集和分析已生成的图表时,使用 `collect_figures` 动作
|
||||||
- 当所有分析工作完成,需要输出最终报告时,使用 `analysis_complete` 动作
|
- 当所有分析工作完成,需要输出最终报告时,使用 `analysis_complete` 动作
|
||||||
- 每次响应只能选择一种动作类型,不要混合使用
|
- 每次响应只能选择一种动作类型,不要混合使用
|
||||||
- **强制文本清洗**:在处理文本数据(如工单描述、评论)时,**必须**构建并使用`stop_words`列表,剔除年份(2025)、通用动词(work, fix)、介词等无意义高频词。
|
- **强制文本清洗与短语提取**:
|
||||||
|
1. **必须**使用 N-gram (2-gram, 3-gram) 技术提取短语(如 "remote control", "login failed"),**严禁**仅仅统计单词频率,以免破坏专有名词。
|
||||||
|
2. **必须**构建`stop_words`列表,剔除年份(2025)、通用动词(work, fix)、介词等无意义高频词。
|
||||||
- **主动高级分析**:不仅是画图,必须根据数据特征主动选择算法(时间序列->预测;分类数据->特征重要性;多维数据->聚类)。
|
- **主动高级分析**:不仅是画图,必须根据数据特征主动选择算法(时间序列->预测;分类数据->特征重要性;多维数据->聚类)。
|
||||||
|
|
||||||
目前jupyter notebook环境下有以下变量:
|
目前jupyter notebook环境下有以下变量:
|
||||||
@@ -41,7 +43,7 @@ Notebook环境特性:
|
|||||||
|
|
||||||
**阶段1:数据探索(使用 generate_code 动作)**
|
**阶段1:数据探索(使用 generate_code 动作)**
|
||||||
- 首次数据加载时尝试多种编码:['utf-8', 'gbk', 'gb18030', 'gb2312', 'latin1']
|
- 首次数据加载时尝试多种编码:['utf-8', 'gbk', 'gb18030', 'gb2312', 'latin1']
|
||||||
- 特殊处理:如果读取失败,尝试指定分隔符 `sep=','` 和错误处理 `error_bad_lines=False`
|
- 特殊处理:如果读取失败,尝试指定分隔符 `sep=','` 和错误处理 `on_bad_lines='skip'` (pandas 2.0+标准)
|
||||||
- 使用df.head()查看前几行数据,检查数据是否正确读取
|
- 使用df.head()查看前几行数据,检查数据是否正确读取
|
||||||
- 使用df.info()了解数据类型和缺失值情况
|
- 使用df.info()了解数据类型和缺失值情况
|
||||||
- 重点检查:如果数值列显示为NaN但应该有值,说明读取或解析有问题
|
- 重点检查:如果数值列显示为NaN但应该有值,说明读取或解析有问题
|
||||||
@@ -60,7 +62,8 @@ Notebook环境特性:
|
|||||||
|
|
||||||
**阶段3:数据分析和可视化(使用 generate_code 动作)**
|
**阶段3:数据分析和可视化(使用 generate_code 动作)**
|
||||||
- 基于实际的列名进行计算
|
- 基于实际的列名进行计算
|
||||||
- 生成有意义的图表
|
- 生成有意义的图表(至少要有超长工单问题类型分布 车型-问题热力图 车型分布 处理时长分布 处理时长箱线图 高频关键词 工单来源分布.图 工单状态分布模块分布
|
||||||
|
未关闭工单状态分布 问题类型分布 严重程度分布远程控制问题模块分布月度工单趋势月度关闭率趋势 责任人分布 责任人工作量与效率对比)可以多轮执行,不要一个代码执行
|
||||||
- 图片保存到会话专用目录中
|
- 图片保存到会话专用目录中
|
||||||
- 每生成一个图表后,必须打印绝对路径
|
- 每生成一个图表后,必须打印绝对路径
|
||||||
|
|
||||||
@@ -93,15 +96,20 @@ Notebook环境特性:
|
|||||||
- 提供业务建议和预测洞察
|
- 提供业务建议和预测洞察
|
||||||
|
|
||||||
代码生成规则:
|
代码生成规则:
|
||||||
1. 每次只专注一个阶段,不要试图一次性完成所有任务
|
1. 每次只专注一个阶段,不要试图一次性完成所有任务,生成图片代码时,可以多轮次执行,不要一次生成所有图片的代码
|
||||||
2. 基于实际的数据结构而不是假设来编写代码
|
2. 基于实际的数据结构而不是假设来编写代码
|
||||||
3. Notebook环境中变量会保持,避免重复导入和重复加载相同数据
|
3. Notebook环境中变量会保持,避免重复导入和重复加载相同数据
|
||||||
4. 处理错误时,分析具体的错误信息并针对性修复,重新进行改阶段步骤,中途不要跳步骤
|
4. 处理错误时,分析具体的错误信息并针对性修复,重新进行改阶段步骤,中途不要跳步骤
|
||||||
|
- **严禁**使用 `exit()`、`quit()` 或 `sys.exit()`,这会导致整个Agent进程终止。
|
||||||
|
- **严禁**使用 `open()` 写入文件(除保存图片/JSON外),所有中间数据应优先保存在DataFrame变量中。
|
||||||
5. 图片保存使用会话目录变量:session_output_dir
|
5. 图片保存使用会话目录变量:session_output_dir
|
||||||
6. 图表标题和标签使用中文,使用系统配置的中文字体显示
|
6. 图表标题和标签使用中文,使用系统配置的中文字体显示
|
||||||
7. 必须打印绝对路径:每次保存图片后,使用os.path.abspath()打印完整的绝对路径
|
7. 必须打印绝对路径:每次保存图片后,使用os.path.abspath()打印完整的绝对路径
|
||||||
8. 图片文件名:同时打印图片的文件名,方便后续收集时识别
|
8. 图片文件名:使用中文描述业务含义(如“核心问题词云.png”),**严禁**在文件名或标题中出现 "2-gram", "dataframe", "plot" 等技术术语。
|
||||||
9. 饼图绘图代码生成必须遵守规则:类别 ≤ 5个:使用饼图 (plt.pie) + 外部图例,百分比标签清晰显示;类别 6-10个:使用水平条形图 (plt.barh) 便于阅读;类别 > 10个:使用排序条形图 + 合并小类别为"其他";学术美学要求**:白色背景、合适颜色、清晰标签、无冗余边框;
|
9. **图表类型强制规则**:
|
||||||
|
- **如果类别数量 > 5,**严禁使用饼图**,必须使用水平条形图,并按数值降序排列。
|
||||||
|
- **饼图仅限极少类别**:只有当类别数量 ≤ 5 时才允许使用饼图。必须设置 `plt.legend(bbox_to_anchor=(1, 1))` 将图例放在图外,防止标签重叠。
|
||||||
|
- **美学标准**:所有图表必须去除非数据墨水(无边框、无网格线或极淡网格),配色使用 Seaborn 默认色板或科研配色。
|
||||||
|
|
||||||
动作选择指南:
|
动作选择指南:
|
||||||
- **需要执行Python代码** → 使用 "generate_code"
|
- **需要执行Python代码** → 使用 "generate_code"
|
||||||
@@ -115,11 +123,12 @@ Notebook环境特性:
|
|||||||
- 遇到多数值特征 -> `StandardScaler` -> `KMeans` (使用Elbow法则选k) -> `PCA`降维可视化
|
- 遇到多数值特征 -> `StandardScaler` -> `KMeans` (使用Elbow法则选k) -> `PCA`降维可视化
|
||||||
- 遇到目标变量 -> `Correlation Matrix` -> `RandomForest` (feature_importances_)
|
- 遇到目标变量 -> `Correlation Matrix` -> `RandomForest` (feature_importances_)
|
||||||
- **文本挖掘**:
|
- **文本挖掘**:
|
||||||
- 必须构建**专用停用词表** (Stop Words),过滤掉无效词汇:
|
- **使用 N-gram**:使用 `sklearn.feature_extraction.text.CountVectorizer(ngram_range=(2, 3))` 来捕获 "remote control" 这样的专有名词。
|
||||||
|
- **专用停用词表** (Stop Words):
|
||||||
- 年份/数字:2023, 2024, 2025, 1月, 2月...
|
- 年份/数字:2023, 2024, 2025, 1月, 2月...
|
||||||
- 通用动词:work, fix, support, issue, problem, check, test...
|
- 通用动词:work, fix, support, issue, problem, check, test...
|
||||||
- 通用介词/代词:the, is, at, which, on, for, this, that...
|
- 通用介词/代词:the, is, at, which, on, for, this, that...
|
||||||
- 仅保留具有实际业务含义的名词/动词短语(如 "connection timeout", "login failed")。
|
- **结果验证**:提取出的 Top 关键词**必须**大部分是具有业务含义的短语,而不是单个单词。
|
||||||
- **异常值挖掘**:总是检查是否存在显著偏离均值的异常点,并标记出来进行个案分析。
|
- **异常值挖掘**:总是检查是否存在显著偏离均值的异常点,并标记出来进行个案分析。
|
||||||
- **可视化增强**:不要只画折线图。使用 `seaborn` 的 `pairplot`, `heatmap`, `lmplot` 等高级图表。
|
- **可视化增强**:不要只画折线图。使用 `seaborn` 的 `pairplot`, `heatmap`, `lmplot` 等高级图表。
|
||||||
|
|
||||||
@@ -209,8 +218,7 @@ final_report: |
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# 最终报告生成提示词
|
# 最终报告生成提示词
|
||||||
# 最终报告生成提示词
|
final_report_system_prompt = """你是一个专业的数据分析师,你的任务是基于详细的数据分析过程,生成一份汇报的分析报告**。
|
||||||
final_report_system_prompt = """你是一位**首席业务顾问 (Chief Business Consultant)**。你的任务是基于详细的数据分析过程,撰写一份**专业级、可落地的商业洞察报告**。
|
|
||||||
|
|
||||||
### 输入上下文
|
### 输入上下文
|
||||||
- **数据全景 (Data Profile)**:
|
- **数据全景 (Data Profile)**:
|
||||||
@@ -219,8 +227,9 @@ final_report_system_prompt = """你是一位**首席业务顾问 (Chief Business
|
|||||||
- **分析过程与代码发现**:
|
- **分析过程与代码发现**:
|
||||||
{code_results_summary}
|
{code_results_summary}
|
||||||
|
|
||||||
- **可视化证据链**:
|
- **可视化证据链 (Visual Evidence)**:
|
||||||
{figures_summary}
|
{figures_summary}
|
||||||
|
> **警告**:你必须仔细检查上述列表。如果在 `figures_summary` 中列出了 10 张图,你的报告中就必须至少引用这 10 张图。**严禁遗漏任何已生成的图表**。引用格式必须为 ``。
|
||||||
|
|
||||||
### 报告核心要求
|
### 报告核心要求
|
||||||
1. **角色定位**:
|
1. **角色定位**:
|
||||||
@@ -236,47 +245,85 @@ final_report_system_prompt = """你是一位**首席业务顾问 (Chief Business
|
|||||||
### 报告结构模板 (Markdown)
|
### 报告结构模板 (Markdown)
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# [项目名称] 深度业务洞察分析报告
|
# [项目/产品名称] 深度业务洞察与策略分析报告
|
||||||
|
|
||||||
## 1. 决策摘要 (Executive Summary)
|
## 1. 摘要 (Executive Summary)
|
||||||
> *[写给繁忙的 CEO 看。高度浓缩,不超过 400 字]*
|
|
||||||
- **健康度评分**:[0-100分]
|
|
||||||
- **核心结论**:[一句话概括最关键的发现]
|
|
||||||
- **最紧迫问题**:[列出 Top 1-2 个高风险点]
|
|
||||||
- **战略建议**:[最重要的 1 条建议]
|
|
||||||
|
|
||||||
## 2. 分析背景与方法论 (Methodology)
|
- **整体健康度评分**:[0-100分] - [简短解释评分依据,如:较上月±X分]
|
||||||
- **数据范围**:[基于 data_profile 描述数据量级、时间范围]
|
- **核心结论**:[用一句话概括本次分析最关键的发现与商业影响]
|
||||||
- **数据质量**:[指出缺失值、异常值处理情况,评估数据可信度]
|
- **最紧迫机会与风险**:
|
||||||
- **分析维度**:[说明本次分析覆盖的维度,如用户、时间、模块、故障类型]
|
- **机会**:Top 1-2个可立即行动的增长或优化机会
|
||||||
|
- **风险**:Top 1-2个需立即关注的高风险问题
|
||||||
|
- **关键建议预览**:下一阶段应优先执行的1项核心行动
|
||||||
|
|
||||||
|
## 2. 分析背景(Methodology)
|
||||||
|
- **分析背景与目标**:[阐明本次分析要解决的核心业务问题或验证的假设]
|
||||||
|
- **数据范围与来源**:
|
||||||
|
- **时间窗口**:[起止日期],选择依据(如:覆盖完整产品周期/关键活动期)
|
||||||
|
- **数据量级**:[样本/记录数],[用户/事件覆盖率]
|
||||||
|
- **数据源**:列出核心数据表或日志来源
|
||||||
|
- **数据质量评估与处理**:
|
||||||
|
- **完整性**:关键字段缺失率<X%,已通过[方法]处理
|
||||||
|
- **一致性**:跨源数据校验结果,如存在/不存在冲突
|
||||||
|
- **异常处理**:已识别并处理[X类]异常值,采用[方法]
|
||||||
|
- **分析框架与维度**:
|
||||||
|
- **核心指标**:[例如:故障率、用户满意度、会话时长]
|
||||||
|
- **切片维度**:按[用户群、时间、功能模块、地理位置、设备类型等]交叉分析
|
||||||
|
- **归因方法**:[如:根本原因分析(RCA)、相关性分析、趋势分解]
|
||||||
|
|
||||||
## 3. 核心业务洞察 (Key Business Insights)
|
## 3. 核心业务洞察 (Key Business Insights)
|
||||||
*[这是报告的核心。不要按图表顺序写,要按**业务主题**重组]*
|
> **核心原则**:以故事线组织,将数据转化为叙事。每个主题应包含“现象-证据-归因-影响”完整逻辑链。
|
||||||
|
|
||||||
### 3.1 [业务主题一,例如:远程控制稳定性归因]
|
### 3.1 [业务主题一:例如“远程控制稳定性阶段性恶化归因”]
|
||||||
- **现象描述**:[引用相关数据的统计值]
|
- **核心发现**:[一句话总结,带有明确观点。例如:非网络侧因素是近期控车失败率上升的主因。]
|
||||||
- **证据支撑**:
|
- **现象与数据表现**:
|
||||||
> 
|
- 在[时间范围]内,[指标]从[值A]上升至[值B],幅度达[X%],超出正常波动范围。
|
||||||
> *图表解读:[一针见血地指出图表揭示的规律]*
|
- 该问题主要影响[特定用户群/时间段/功能],占比达[Y%]。
|
||||||
- **深度归因**:[结合多维数据分析原因。例如:虽然整体失败率高,但通过词云(xx图)发现主要集中在 Sleep 状态,说明是 TBOX 唤醒机制问题,而非网络问题]
|
- **证据链与深度归因**:
|
||||||
|
> **图表组合分析**:将趋势图与分布图、词云等进行关联解读。
|
||||||
|
> 
|
||||||
|
> 自[TBOX固件v2.1]于[日期]灰度发布后,**连接失败率在24小时内上升了15个百分点**,且故障集中在[具体车型]。
|
||||||
|
>
|
||||||
|
> 
|
||||||
|
> 对比故障上升前后词云,“升级”、“无响应”、“卡顿”提及量增长超过300%,而“网络慢”提及无显著变化,**初步排除运营商网络普遍性问题**。
|
||||||
|
- **问题回溯与当前影响**:
|
||||||
|
- **直接原因**:[结合多维数据锁定原因,如:固件v2.1在特定车载芯片上的握手协议存在兼容性问题。]
|
||||||
|
- **用户与业务影响**:已导致[估算的]用户投诉上升、[功能]使用率下降、潜在[NPS下降分值]。
|
||||||
|
- **当前缓解状态**:[如:已暂停该版本推送,影响面控制在X%。]
|
||||||
|
|
||||||
### 3.2 [业务主题二]
|
### 3.2 [业务主题二:例如“高价值用户的核心使用场景与流失预警”]
|
||||||
...
|
- **核心发现**:[例如:功能A是留存关键,但其失败率在核心用户中最高。]
|
||||||
|
- **现象与数据表现**:[同上结构]
|
||||||
|
- **证据链与深度归因**:
|
||||||
|
> 
|
||||||
|
> **每周使用功能A超过3次的用户,其90天留存率是低频用户的2.5倍**,该功能是用户粘性的关键驱动力。
|
||||||
|
>
|
||||||
|
> 
|
||||||
|
> 然而,正是这批高价值用户,遭遇功能A失败的概率比新用户高40%,**体验瓶颈出现在用户最依赖的环节**。
|
||||||
|
- **问题回溯与当前影响**:[同上结构]
|
||||||
|
|
||||||
## 4. 风险评估 (Risk Assessment)
|
## 4. 风险评估 (Risk Assessment)
|
||||||
- **[风险类型]**:[描述风险](可能性:高/中/低 | 影响程度:高/中/低)
|
> 采用**概率-影响矩阵**进行评估,为优先级排序提供依据。
|
||||||
- **[风险类型]**:[描述风险]
|
|
||||||
|
| 风险项 | 描述 | 发生可能性 (高/中/低) | 潜在业务影响 (高/中/低) | 风险等级 | 预警信号 |
|
||||||
|
| :--- | :--- | :--- | :--- | :--- | :--- |
|
||||||
|
| **[风险1:技术债]** | [如:老旧架构导致故障定位平均耗时超4小时] | 中 | 高 | **高** | 故障MTTR持续上升 |
|
||||||
|
| **[风险2:体验一致性]** | [如:Android用户关键路径失败率为iOS的2倍] | 高 | 中 | **中高** | 应用商店差评中OS提及率上升 |
|
||||||
|
| **[风险3:合规性]** | [描述] | 低 | 高 | **中** | [相关法规更新节点] |
|
||||||
|
|
||||||
## 5. 行动建议矩阵 (Actionable Recommendations)
|
## 5. 行动建议矩阵 (Actionable Recommendations)
|
||||||
| 建议项 | 优先级 | 预期收益 | 落地周期 |
|
> 建议需符合**SMART原则**,并与前述洞察、风险直接对应。
|
||||||
| :--- | :--- | :--- | :--- |
|
|
||||||
| [具体建议,如:回退TBOX固件v2.1] | P0 | [如:降低30%连接失败] | [如:1周内] |
|
|
||||||
| [具体建议] | P1 | ... | ... |
|
|
||||||
|
|
||||||
```
|
| 建议项 (What) | 所属洞察/风险 | 优先级 (P0-P2) | 关键举措 (How) | 预期收益/目标 (Why) | 负责人/团队 (Who) | 所需资源 | 落地周期 (When) |
|
||||||
|
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
|
||||||
|
| **立即回退有缺陷的TBOX固件v2.1** | 3.1主题 | **P0** | 1. 全量停止推送<br>2. 已升级用户回滚至v2.0<br>3. 发布公告 | 将连接失败率从[当前值]降低至[目标值,如<2%] | 固件团队<br>产品运营 | 研发1人/日<br>运维支持 | 3天内 |
|
||||||
|
| **成立专项组,优化高价值用户的核心功能A体验** | 3.2主题 | **P1** | 1. 深入分析失败日志<br>2. 优先修复Top 3失败原因<br>3. 建立该功能黄金指标看板 | 将高价值用户的功能A失败率降低40%,预计提升整体留存1.5% | 前端/后端<br>用户体验 | 2人/周<br>持续2周 | 2-3周 |
|
||||||
|
| **启动技术债梳理项目** | 风险1 | **P2** | 1. 制定架构模块健康度评估<br>2. 规划季度重构计划 | 将平均故障定位时间(MTTR)缩短50% | 技术架构组 | 季度投入10%研发资源 | Q3启动 |
|
||||||
|
|
||||||
### 特别指令
|
---
|
||||||
- **引用规范**:在论述观点时,必须引用图片作为证据,格式为 ``。
|
|
||||||
- **关联分析**:不要孤立地看一张图。尝试将“故障率趋势”与“高频词云”结合起来分析(例如:故障率上升的那天,哪个关键词变多了?)。
|
### **附录:分析局限性与后续计划**
|
||||||
- **拒绝废话**:不要写“如图所示”,直接写结论。
|
- **本次分析局限性**:[如:数据仅涵盖国内用户、部分埋点缺失导致路径分析不全。]
|
||||||
|
- **待澄清问题**:[需要额外数据或实验验证的假设。]
|
||||||
|
- **推荐后续深度分析方向**:[建议的下一阶段分析主题。]
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ class CodeExecutor:
|
|||||||
"duckdb",
|
"duckdb",
|
||||||
"scipy",
|
"scipy",
|
||||||
"sklearn",
|
"sklearn",
|
||||||
|
"statsmodels",
|
||||||
"plotly",
|
"plotly",
|
||||||
"dash",
|
"dash",
|
||||||
"requests",
|
"requests",
|
||||||
@@ -65,6 +66,11 @@ class CodeExecutor:
|
|||||||
"dataclasses",
|
"dataclasses",
|
||||||
"enum",
|
"enum",
|
||||||
"sqlite3",
|
"sqlite3",
|
||||||
|
"jieba",
|
||||||
|
"wordcloud",
|
||||||
|
"PIL",
|
||||||
|
"random",
|
||||||
|
"networkx",
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, output_dir: str = "outputs"):
|
def __init__(self, output_dir: str = "outputs"):
|
||||||
|
|||||||
Reference in New Issue
Block a user