Skip to content

Latest commit

 

History

History
768 lines (606 loc) · 19.8 KB

File metadata and controls

768 lines (606 loc) · 19.8 KB

WF-002: 知识库生成

📌 工作流基本信息

属性 内容
工作流ID WF-002
工作流名称 知识库生成
功能描述 从MatrixOne库中的历史Issue数据提炼产品知识、问题模式、标签体系,生成Markdown文档并存入数据库
实现状态 ✅ 已实现
云端可用 ✅ 完全可用
核心价值 自动学习产品结构和问题模式,为WF-003(智能提Issue)提供知识支持

🔄 流程步骤总览

┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐   ┌──────────┐
│  步骤1   │──▶│  步骤2   │──▶│  步骤3   │──▶│  步骤4   │──▶│  步骤5   │──▶│  步骤6   │──▶│  步骤7   │
│读取Issue │   │AI提炼产品│   │ 分析标签 │   │识别常见  │   │生成MD文档│   │存入数据库│   │保存文件  │
└──────────┘   └──────────┘   └──────────┘   └──────────┘   └──────────┘   └──────────┘   └──────────┘
  从MO库查询      AI识别产品     统计Labels      高频Issue      Markdown      写入知识库表    .md文件
  历史Issue       模块/功能       按前缀分类      组合模式       结构化文档     版本化管理     latest版本

快速理解

  1. 步骤1 - 从MO库读取历史Issue数据(最新快照)
  2. 步骤2 - AI分析200个样本,识别产品结构(MOI/MO、模块、功能)
  3. 步骤3 - 统计Labels体系(customer/、area/、kind/等前缀)
  4. 步骤4 - 识别高频Issue组合(≥10个的常见类型)
  5. 步骤5 - 生成Markdown知识库文档(产品+标签+常见Issue)
  6. 步骤6 - 存入issue_knowledge_base表(结构化存储)
  7. 步骤7 - 保存MD文件(latest版本+历史版本)

核心特点:✅ AI驱动提炼 | ✅ MD文档+数据库双存储 | ✅ Issue规范作为基础


📥 整体输入

1. 数据源输入

输入项 类型 说明 来源
repo_owner String 仓库所有者 matrixorigin
repo_name String 仓库名称 matrixone / matrixflow
历史Issue数据 数据库 MO库中的issues_snapshot表 WF-001的输出

2. AI服务配置

输入项 类型 说明 示例
AI_PROVIDER String AI服务提供商 qwen(推荐)
DASHSCOPE_API_KEY String 通义千问API密钥 sk-xxxxxxxxxxxx
QWEN_MODEL String 模型名称 qwen-plus

3. Issue规范模板(作为输入)

输入项 类型 说明 位置
模板文件 Markdown Issue标准模板,作为知识库的基础 feature_issue_and_kanban/templates/*.md

模板文件作用

  • 提供Issue标准字段结构
  • 作为AI提炼的参考基准
  • 定义产品分类(MO/MOI/Customer等)

4. 提炼规则配置

输入项 类型 说明 默认值
min_issue_count Integer 标签最小出现次数(低于此值过滤) 3
sample_size Integer AI分析的样本数量 200
common_issue_threshold Integer 常见Issue类型阈值 10

📤 整体输出

1. Markdown知识库文件

输出项 文件路径 说明
最新知识库 data/knowledge_base/{owner}_{repo}_knowledge_latest.md 最新版本,覆盖式更新
带时间戳版本 data/knowledge_base/{owner}_{repo}_knowledge_{YYYYMMDD}.md 历史版本备份

2. 数据库存储

输出项 表名 说明
知识库记录 issue_knowledge_base 结构化知识数据

3. 知识库内容结构

Markdown文档包含

  1. 产品结构 - 识别的产品/模块列表
  2. 标签体系 - 按前缀分类的标签统计
  3. 常见Issue类型 - 高频Issue模式
  4. Issue目录 - 按产品/模块组织的Issue分类

🔄 详细步骤拆分

步骤1: 从MO数据库读取历史Issue

步骤ID: WF-002-S01
功能: 从MatrixOne读取所有历史Issue数据
实现状态: ✅ 已实现

输入

  • repo_owner: 仓库所有者
  • repo_name: 仓库名称
  • 数据库连接: MO连接配置(来自WF-001)

处理逻辑

SQL查询

SELECT 
    issue_number,
    title,
    labels,           -- JSON格式的Labels
    state,
    created_at
FROM issues_snapshot
WHERE repo_owner = :owner 
  AND repo_name = :repo
  AND snapshot_time = (
      SELECT MAX(snapshot_time) 
      FROM issues_snapshot
      WHERE repo_owner = :owner 
        AND repo_name = :repo
  )

解析Labels

# Labels字段是JSON字符串,需要解析
labels_data = json.loads(issue['labels'])
# 结果: [{"name": "bug", "color": "d73a4a"}, ...]

输出

  • Issue列表(Python字典数组):
    [
        {
            "number": 8450,
            "title": "Bug: 查询超时",
            "labels": [
                {"name": "bug", "color": "d73a4a"},
                {"name": "customer/金盘", "color": "fbca04"}
            ],
            "state": "open",
            "created_at": "2024-01-01T00:00:00Z"
        },
        ...
    ]

代码模块

  • 文件: feature_issue_and_kanban/issue_creator/knowledge_extractor.py
  • : KnowledgeExtractor
  • 方法: _load_all_issues(repo_owner, repo_name)

步骤2: AI提炼产品结构

步骤ID: WF-002-S02
功能: 使用AI分析Issue样本,识别产品分类、模块、功能
实现状态: ✅ 已实现

输入

  • 历史Issue数据(步骤1输出)
  • sample_size: AI分析样本数量(默认200个)
  • AI配置: 通义千问API

处理逻辑

采样策略

# 如果Issue总数>200,随机采样200个
sampled_issues = random.sample(issues, min(200, len(issues)))

AI Prompt构建

prompt = f"""
你是产品分析专家。请根据以下 {len(sampled)} 个 Issue 样本,提取产品结构。

Issue样本:
{json.dumps(sampled, ensure_ascii=False, indent=2)}

请识别:
1) 主产品(如 MOI、MO)
2) 子产品/模块
3) 主要功能

返回纯 JSON,格式示例:
{{
    "MOI": {{
        "type": "platform",
        "sub_products": {{
            "问数": {{
                "features": ["NL2SQL", "数据分析"],
                "issue_count": 100
            }},
            "ChatBI": {{
                "features": ["对话交互", "BI分析"],
                "issue_count": 50
            }}
        }}
    }},
    "MO": {{
        "type": "database",
        "modules": {{
            "storage": {{"issue_count": 50}},
            "sql": {{"issue_count": 80}}
        }}
    }}
}}

只返回 JSON,不要其他说明。
"""

AI调用

client = OpenAI(api_key=DASHSCOPE_API_KEY, base_url=QWEN_BASE_URL)
response = client.chat.completions.create(
    model=QWEN_MODEL,
    messages=[
        {"role": "system", "content": "你只输出合法 JSON,不要 markdown 代码块。"},
        {"role": "user", "content": prompt}
    ]
)

回退机制(AI失败时):

# 基于规则提取:从Labels中识别 area/ 前缀
products = {}
for issue in issues:
    for label in issue['labels']:
        if label['name'].startswith('area/'):
            area = label['name'].replace('area/', '')
            # 归类到 MOI 产品
            products.setdefault('MOI', {})['sub_products'][area] = {
                'issue_count': ...
            }

输出

  • 产品结构字典(JSON格式):
    {
        "MOI": {
            "type": "platform",
            "sub_products": {
                "问数": {
                    "features": ["NL2SQL", "数据分析"],
                    "issue_count": 100
                }
            }
        },
        "MO": {
            "type": "database",
            "modules": {
                "storage": {"issue_count": 50}
            }
        }
    }

代码模块

  • 方法: _extract_products(issues)

步骤3: 分析标签体系

步骤ID: WF-002-S03
功能: 统计Labels,按前缀分类,过滤低频标签
实现状态: ✅ 已实现

输入

  • 历史Issue数据(步骤1输出)
  • min_issue_count: 最小出现次数(默认3)

处理逻辑

标签统计

label_stats = defaultdict(lambda: defaultdict(int))

for issue in issues:
    for label in issue['labels']:
        name = label['name']
        
        # 按前缀分类(如 customer/, area/, kind/)
        if "/" in name:
            prefix = name.split("/", 1)[0] + "/"
            label_stats[prefix][name] += 1
        else:
            # 无前缀的标签归入 "other"
            label_stats["other"][name] += 1

过滤低频标签

result = {}
for prefix, labels in label_stats.items():
    # 只保留出现次数 >= min_issue_count 的标签
    filtered = {
        label: count 
        for label, count in labels.items() 
        if count >= min_issue_count
    }
    if filtered:
        result[prefix] = filtered

排序

# 按出现次数降序排列
result[prefix] = dict(sorted(filtered.items(), key=lambda x: -x[1]))

输出

  • 标签体系字典(JSON格式):
    {
        "customer/": {
            "customer/金盘": 50,
            "customer/XX公司": 30,
            "customer/YY银行": 25
        },
        "area/": {
            "area/问数": 100,
            "area/ChatBI": 80
        },
        "kind/": {
            "kind/bug": 200,
            "kind/feature": 150
        },
        "other": {
            "bug": 100,
            "enhancement": 50
        }
    }

代码模块

  • 方法: _extract_label_system(issues)

步骤4: AI识别常见Issue类型

步骤ID: WF-002-S04
功能: 找出高频出现的Label组合,识别常见问题模式
实现状态: ✅ 已实现

输入

  • 历史Issue数据(步骤1输出)
  • threshold: 常见Issue阈值(默认10,即至少10个Issue)

处理逻辑

按Label组合分组

grouped = defaultdict(list)

for issue in issues:
    # 提取 kind/ 和 area/ 标签
    key_labels = [
        label['name'] 
        for label in issue['labels'] 
        if 'kind/' in label['name'] or 'area/' in label['name']
    ]
    
    # 按字母排序形成唯一键
    key = tuple(sorted(key_labels))
    
    if key:
        grouped[key].append(issue)

识别高频组合

common_issues = []
for labels_tuple, issue_list in grouped.items():
    # 至少10个Issue才算常见类型
    if len(issue_list) >= 10:
        common_issues.append({
            "labels": list(labels_tuple),
            "count": len(issue_list),
            "examples": [
                {"number": i["number"], "title": i["title"]} 
                for i in issue_list[:5]  # 取前5个作为示例
            ]
        })

# 按数量降序排列,取前50个
common_issues.sort(key=lambda x: -x['count'])
common_issues = common_issues[:50]

输出

  • 常见Issue类型列表(JSON格式):
    [
        {
            "labels": ["area/问数", "kind/bug"],
            "count": 120,
            "examples": [
                {"number": 8450, "title": "NL2SQL翻译错误"},
                {"number": 8451, "title": "查询超时"},
                ...
            ]
        },
        {
            "labels": ["area/ChatBI", "kind/feature"],
            "count": 80,
            "examples": [...]
        }
    ]

代码模块

  • 方法: _extract_common_issue_types(issues)

步骤5: 生成Markdown知识库文档

步骤ID: WF-002-S05
功能: 将提炼的知识组织为结构化Markdown文档
实现状态: ✅ 已实现

输入

  • 产品结构(步骤2输出)
  • 标签体系(步骤3输出)
  • 常见Issue类型(步骤4输出)

处理逻辑

Markdown生成逻辑

markdown = f"""# Issue知识库索引

**生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}

---

## 一、产品结构

### MOI (平台)
- 问数 (100 Issues)
  - 功能: NL2SQL, 数据分析
- ChatBI (80 Issues)
  - 功能: 对话交互, BI分析

### MO (数据库)
- storage (50 Issues)
- sql (80 Issues)

---

## 二、标签体系

### customer/
- `customer/金盘` (50)
- `customer/XX公司` (30)

### area/
- `area/问数` (100)
- `area/ChatBI` (80)

### kind/
- `kind/bug` (200)
- `kind/feature` (150)

---

## 三、常见Issue类型

### 1. area/问数, kind/bug (120 Issues)
- #8450: NL2SQL翻译错误
- #8451: 查询超时
- #8452: 结果不准确

### 2. area/ChatBI, kind/feature (80 Issues)
- #7890: 增加图表类型
- #7891: 支持导出报告
"""

输出

  • Markdown文本(字符串)

代码模块

  • 方法: _generate_markdown_index(knowledge)

步骤6: 保存到数据库

步骤ID: WF-002-S06
功能: 将知识库数据存入 issue_knowledge_base
实现状态: ✅ 已实现

输入

  • 产品结构(步骤2输出)
  • 标签体系(步骤3输出)
  • 常见Issue类型(步骤4输出)

处理逻辑

生成版本号

version = int(datetime.now().timestamp())  # 时间戳作为版本号

存储产品结构

INSERT INTO issue_knowledge_base (
    knowledge_type,    -- 'product'
    category,          -- 产品名(如 'MOI')
    title,             -- 产品名
    description,       -- JSON格式的产品详情
    version            -- 版本号
) VALUES (...)

存储标签体系

INSERT INTO issue_knowledge_base (
    knowledge_type,    -- 'label'
    category,          -- 标签前缀(如 'customer/')
    title,             -- 标签名(如 'customer/金盘')
    description,       -- 描述(如 '出现50次')
    issue_count,       -- 出现次数
    version
) VALUES (...)

存储常见Issue类型

INSERT INTO issue_knowledge_base (
    knowledge_type,    -- 'common_issue'
    category,          -- Labels组合(逗号分隔)
    title,             -- 描述标题
    description,       -- JSON格式的详情(含examples)
    issue_count,       -- Issue数量
    version
) VALUES (...)

输出

  • 数据库记录: 存入 issue_knowledge_base

代码模块

  • 方法:
    • _save_to_database(products, label_system, common_issues)
    • _insert_knowledge(...)

步骤7: 保存Markdown文件

步骤ID: WF-002-S07
功能: 将Markdown文档保存到文件系统
实现状态: ✅ 已实现

输入

  • Markdown文本(步骤5输出)
  • repo_owner, repo_name

处理逻辑

文件路径生成

output_dir = Path("data/knowledge_base")
output_dir.mkdir(parents=True, exist_ok=True)

# 带时间戳的历史版本
timestamp = datetime.now().strftime("%Y%m%d")
history_file = output_dir / f"{repo_owner}_{repo_name}_knowledge_{timestamp}.md"

# 最新版本(覆盖式)
latest_file = output_dir / f"{repo_owner}_{repo_name}_knowledge_latest.md"

写入文件

history_file.write_text(markdown, encoding="utf-8")
latest_file.write_text(markdown, encoding="utf-8")

输出

  • 文件:
    • data/knowledge_base/matrixorigin_matrixone_knowledge_20260304.md
    • data/knowledge_base/matrixorigin_matrixone_knowledge_latest.md

代码模块

  • 方法: _save_markdown_file(markdown, repo_owner, repo_name)

🗄️ 数据库表结构

issue_knowledge_base(知识库表)

字段名 类型 说明 示例
id INTEGER 主键 -
knowledge_type VARCHAR(50) 知识类型 product / label / common_issue
category VARCHAR(100) 分类 MOI / customer/ / area/问数,kind/bug
title VARCHAR(200) 标题 问数 / customer/金盘
description TEXT 详细描述(JSON或文本) {"features": [...]}
issue_count INTEGER 关联Issue数量 100
version INTEGER 版本号(时间戳) 1709535600
created_at DATETIME 创建时间 -

⚙️ 配置文件说明

配置位置: config/config.py + 代码内部参数

关键参数

# AI配置(同WF-001)
AI_PROVIDER = "qwen"
DASHSCOPE_API_KEY = os.getenv("DASHSCOPE_API_KEY")

# 知识提炼参数(代码内部)
min_issue_count = 3          # 标签最小出现次数
sample_size = 200            # AI分析样本数量
common_issue_threshold = 10  # 常见Issue阈值

🔧 运行方式

方式1:手动执行脚本

python3 feature_issue_and_kanban/scripts/update_knowledge_base.py \
    --repo-owner matrixorigin \
    --repo-name matrixone

方式2:Python代码调用

from feature_issue_and_kanban.issue_creator.knowledge_extractor import KnowledgeExtractor
from modules.database_storage.mo_client import MOStorage
from modules/llm_parser.llm_parser import LLMParser

# 初始化
storage = MOStorage()
llm = LLMParser()
extractor = KnowledgeExtractor(storage, llm)

# 提炼知识库
result = extractor.extract_full_knowledge_base("matrixorigin", "matrixone")

print(f"✅ 知识库生成完成")
print(f"产品数量: {len(result['products'])}")
print(f"标签数量: {sum(len(v) for v in result['label_system'].values())}")
print(f"常见Issue类型: {len(result['common_issues'])}")

✅ 实现验证

验证步骤

  1. 检查Markdown文件

    ls -lh data/knowledge_base/
    cat data/knowledge_base/matrixorigin_matrixone_knowledge_latest.md
  2. 检查数据库记录

    -- 查看知识库记录
    SELECT knowledge_type, COUNT(*) 
    FROM issue_knowledge_base 
    GROUP BY knowledge_type;
    
    -- 查看产品列表
    SELECT * FROM issue_knowledge_base 
    WHERE knowledge_type = 'product';
    
    -- 查看标签体系
    SELECT category, title, issue_count 
    FROM issue_knowledge_base 
    WHERE knowledge_type = 'label' 
    ORDER BY issue_count DESC 
    LIMIT 20;

🚨 关键确认点(根据用户要求)

✅ 1. 存储方式

确认:生成MD文档并保存到 data/knowledge_base/ 目录

✅ 2. 提炼规则来源

确认

  • AI驱动:通过通义千问API智能识别
  • 基于历史数据:从MO库中的Issue学习
  • 规则回退:AI失败时使用基于Labels的规则提取

✅ 3. AI调用内容

确认:AI提炼包括:

  • 产品分类(MOI/MO等)
  • 产品功能列表
  • 主要问题类型
  • Issue对应目录(按area/customer/kind组织)

✅ 4. Issue规范文件作用

确认feature_issue_and_kanban/templates/*.md 作为:

  • 知识库的基础结构参考
  • AI提炼的字段模板
  • 产品分类的参考标准

📊 性能指标

指标 数值 说明
处理速度 ~1000 issues/分钟 数据读取和统计
AI调用 1-2次 仅对样本数据调用AI
生成时间 ~2-5分钟 1000个Issue的完整提炼
文件大小 ~50-200KB Markdown文档

🔄 云端部署注意事项

✅ 完全可用

该工作流在云端部署无任何限制

  • 只依赖数据库读取和AI API调用
  • 文件写入可用云存储替代
  • 无本地环境依赖

建议

  • 定期执行:建议每周或每次WF-001运行后执行
  • 增量更新:通过版本号(timestamp)管理多版本知识库
  • 缓存策略:latest版本可缓存给WF-003使用

文档版本: v1.0
最后更新: 2026-03-04