chore(vault): backup 2026-07-03 21:18:15
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
# Wiki 生成质量对比实验
|
||||
|
||||
## 实验目标
|
||||
|
||||
对比 **Two-Step 模式**(先分析后生成)与 **Single-Step 模式**(直接生成)在 Wiki 内容生成质量上的差异。
|
||||
|
||||
## 实验设计
|
||||
|
||||
- **测试文件**: `raw/呼吸之间_李谨伯/第一编 从身体入手.md`
|
||||
- **金标准**: 66 个术语(概念、方法、实体)
|
||||
- **评估维度**:
|
||||
- 40% 内容完整性
|
||||
- 30% 技术规范性
|
||||
- 20% 可维护性
|
||||
- 10% 效率成本
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
tools/experiments/wiki-generation-compare/
|
||||
├── prompts/
|
||||
│ ├── twostep-analysis.md # A组 Step 1 分析 prompt
|
||||
│ ├── twostep-generation.md # A组 Step 2 生成 prompt
|
||||
│ └── singlestep.md # B组 单步生成 prompt
|
||||
├── scripts/
|
||||
│ ├── run-a-group.ps1 # 执行 A 组
|
||||
│ ├── run-b-group.ps1 # 执行 B 组
|
||||
│ ├── evaluate.ps1 # 评估脚本
|
||||
│ └── cleanup.ps1 # 清理环境
|
||||
├── output/
|
||||
│ ├── group-a/ # A 组输出
|
||||
│ │ ├── analysis.json # Step 1 分析结果
|
||||
│ │ ├── wiki/ # 生成的 Wiki 页面
|
||||
│ │ └── metadata.json # 执行元数据
|
||||
│ ├── group-b/ # B 组输出
|
||||
│ │ ├── wiki/ # 生成的 Wiki 页面
|
||||
│ │ └── metadata.json # 执行元数据
|
||||
│ └── report.md # 最终对比报告
|
||||
└── gold-standard.json # 金标准数据
|
||||
```
|
||||
|
||||
## 执行步骤
|
||||
|
||||
### 1. 执行 A 组(Two-Step 模式)
|
||||
|
||||
```powershell
|
||||
cd tools/experiments/wiki-generation-compare
|
||||
.\scripts\run-a-group.ps1
|
||||
```
|
||||
|
||||
**说明**:
|
||||
- Step 1: 调用 LLM 分析源文件,提取结构化信息
|
||||
- Step 2: 基于分析结果生成 Wiki 页面
|
||||
- 预计耗时:30-45 分钟(取决于 LLM API 响应速度)
|
||||
|
||||
### 2. 执行 B 组(Single-Step 模式)
|
||||
|
||||
```powershell
|
||||
.\scripts\run-b-group.ps1
|
||||
```
|
||||
|
||||
**说明**:
|
||||
- 直接调用 LLM 生成 Wiki 页面
|
||||
- 预计耗时:15-30 分钟(取决于 LLM API 响应速度)
|
||||
|
||||
### 3. 评估与报告
|
||||
|
||||
```powershell
|
||||
.\scripts\evaluate.ps1
|
||||
```
|
||||
|
||||
**说明**:
|
||||
- 对比 A/B 两组的输出
|
||||
- 评估术语覆盖度、Frontmatter 规范性、Wikilink 质量
|
||||
- 生成完整的对比报告
|
||||
|
||||
### 4. 清理环境(可选)
|
||||
|
||||
```powershell
|
||||
.\scripts\cleanup.ps1
|
||||
```
|
||||
|
||||
## 配置要求
|
||||
|
||||
### LLM API 配置
|
||||
|
||||
脚本支持多种 LLM API:
|
||||
|
||||
1. **opencode-mem**(优先)
|
||||
- 自动使用系统配置的记忆系统
|
||||
- 无需额外配置
|
||||
|
||||
2. **OpenAI API**(备用)
|
||||
```powershell
|
||||
$env:OPENAI_API_KEY = "your-api-key"
|
||||
```
|
||||
|
||||
3. **其他 API**
|
||||
- 需要修改脚本中的 API 调用代码
|
||||
|
||||
## 评估标准
|
||||
|
||||
### 1. 术语覆盖度(40%)
|
||||
|
||||
- 覆盖率:覆盖术语数 / 金标准术语数
|
||||
- 定义质量:有定义的页面占比
|
||||
- 来源链接:有来源链接的页面占比
|
||||
- 行号标注:有行号标注的页面占比
|
||||
|
||||
### 2. 技术规范性(30%)
|
||||
|
||||
- Frontmatter 完整度:必需字段占比
|
||||
- 布尔值合规率:布尔值用引号包裹的占比
|
||||
- Wikilink 质量:有效链接占比
|
||||
|
||||
### 3. 可维护性(20%)
|
||||
|
||||
- 元数据完整性
|
||||
- 文件组织结构
|
||||
|
||||
### 4. 效率成本(10%)
|
||||
|
||||
- 执行时间
|
||||
- Token 消耗(如果支持)
|
||||
|
||||
## 预期结果
|
||||
|
||||
| 维度 | Two-Step | Single-Step | 预测 |
|
||||
|------|----------|-------------|------|
|
||||
| 术语覆盖度 | 高 | 中 | A > B |
|
||||
| 定义准确度 | 高 | 高 | A ≈ B |
|
||||
| 来源标注 | 强制 | 手动 | A < B(粒度) |
|
||||
| Frontmatter 规范 | 自动生成 | 手动维护 | A > B |
|
||||
| Wikilink 质量 | 高 | 中 | A > B |
|
||||
| 索引/日志 | 自动更新 | 手动更新 | A > B |
|
||||
| Token 消耗 | 高(两步) | 低(单步) | A > B |
|
||||
| 时间成本 | 长 | 短 | A > B |
|
||||
| 可定制性 | 低 | 高 | A < B |
|
||||
| 人工干预 | 异步 | 同步 | A ≈ B |
|
||||
|
||||
## 故障排查
|
||||
|
||||
### LLM 调用失败
|
||||
|
||||
如果 LLM API 调用失败,脚本会:
|
||||
|
||||
1. 显示错误信息
|
||||
2. 尝试生成模拟数据用于测试
|
||||
3. 继续执行评估脚本
|
||||
|
||||
### 文件解析失败
|
||||
|
||||
如果 Wiki 页面解析失败:
|
||||
|
||||
1. 检查 LLM 输出格式
|
||||
2. 检查 `---FILE: … ---END FILE---` 标记
|
||||
3. 查看生成的原始输出文件
|
||||
|
||||
### 评估脚本错误
|
||||
|
||||
如果评估脚本报错:
|
||||
|
||||
1. 检查金标准文件是否存在
|
||||
2. 检查输出目录是否生成
|
||||
3. 查看 PowerShell 错误信息
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **API 成本**: Two-Step 模式需要两次 LLM 调用,Token 消耗更高
|
||||
2. **执行时间**: Two-Step 模式需要更长时间
|
||||
3. **质量差异**: Two-Step 模式预期内容质量更高,但效率更低
|
||||
4. **实验环境**: 确保有足够的磁盘空间和网络连接
|
||||
|
||||
## 扩展实验
|
||||
|
||||
### 测试更多文件
|
||||
|
||||
修改脚本中的 `$sourceFile` 变量:
|
||||
|
||||
```powershell
|
||||
$sourceFile = "raw/呼吸之间_李谨伯/第四编 怎样调整呼吸.md"
|
||||
```
|
||||
|
||||
### 调整权重
|
||||
|
||||
修改 `evaluate.ps1` 中的权重配置:
|
||||
|
||||
```powershell
|
||||
$weights = @{
|
||||
contentCompleteness = 0.5 # 提高内容完整性权重
|
||||
technicalCompliance = 0.2
|
||||
maintainability = 0.2
|
||||
efficiency = 0.1
|
||||
}
|
||||
```
|
||||
|
||||
### 添加新的评估维度
|
||||
|
||||
在 `evaluate.ps1` 中添加新的评估函数,并修改得分计算逻辑。
|
||||
|
||||
## 参考资料
|
||||
|
||||
- [AGENTS.md - Wiki 工作流](../../../AGENTS.md)
|
||||
- [nashsu/llm_wiki - Two-Step Ingest](https://github.com/nashsu/llm_wiki)
|
||||
- [Karpathy LLM Wiki](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f)
|
||||
|
||||
---
|
||||
|
||||
**实验创建时间**: 2026-07-03
|
||||
**实验维护者**: opencode Agent
|
||||
@@ -0,0 +1,325 @@
|
||||
{
|
||||
"source_info": {
|
||||
"filename": "第一编 从身体入手.md",
|
||||
"total_lines": 178,
|
||||
"total_words": 11000,
|
||||
"main_sections": [
|
||||
"我们身体最不正的是什么",
|
||||
"人的精气神从哪里",
|
||||
"关键是\"开窍\"",
|
||||
"现代人不\"开心\"呢",
|
||||
"问答"
|
||||
]
|
||||
},
|
||||
"concepts": [
|
||||
{
|
||||
"term": "精气神",
|
||||
"definition": "天有三宝日、月、星;地有三宝水、火、风;人也有三宝,精、气、神",
|
||||
"line_number": 44,
|
||||
"occurrences": 8,
|
||||
"summary": "道家修炼的三大基本要素"
|
||||
},
|
||||
{
|
||||
"term": "天人感应",
|
||||
"definition": "星体间产生的引力波互相作用,产生类似星系的漩涡能量场",
|
||||
"line_number": 48,
|
||||
"occurrences": 3,
|
||||
"summary": "天体对人产生影响的机制"
|
||||
},
|
||||
{
|
||||
"term": "玄空造化场",
|
||||
"definition": "星体间产生的引力波互相作用形成的漩涡能量场",
|
||||
"line_number": 48,
|
||||
"occurrences": 3,
|
||||
"summary": "影响初生婴儿的能量场"
|
||||
},
|
||||
{
|
||||
"term": "生气",
|
||||
"definition": "玄空造化场里产生的对生命界影响很大的能量",
|
||||
"line_number": 54,
|
||||
"occurrences": 6,
|
||||
"summary": "补充元气的关键能量"
|
||||
},
|
||||
{
|
||||
"term": "元气",
|
||||
"definition": "生气主要补充的能量,真元之气",
|
||||
"line_number": 54,
|
||||
"occurrences": 8,
|
||||
"summary": "人体生命力的基础"
|
||||
},
|
||||
{
|
||||
"term": "出死入生",
|
||||
"definition": "意念外放损耗元气为出死,高效能吸收生气为入生",
|
||||
"line_number": 102,
|
||||
"occurrences": 1,
|
||||
"summary": "能量消耗与补充的对比"
|
||||
},
|
||||
{
|
||||
"term": "返观",
|
||||
"definition": "修静接收能量的方法,能长生",
|
||||
"line_number": 105,
|
||||
"occurrences": 2,
|
||||
"summary": "修炼的收心方法"
|
||||
},
|
||||
{
|
||||
"term": "虚静",
|
||||
"definition": "修道的根本状态",
|
||||
"line_number": 102,
|
||||
"occurrences": 2,
|
||||
"summary": "入定的基础状态"
|
||||
},
|
||||
{
|
||||
"term": "天人合一",
|
||||
"definition": "先天到后天的能量场造化作用",
|
||||
"line_number": 48,
|
||||
"occurrences": 3,
|
||||
"summary": "天人合一的能量场机制"
|
||||
},
|
||||
{
|
||||
"term": "先天",
|
||||
"definition": "本能的、自然的",
|
||||
"line_number": 50,
|
||||
"occurrences": 5,
|
||||
"summary": "人与生俱来的功能"
|
||||
},
|
||||
{
|
||||
"term": "后天",
|
||||
"definition": "人为的、社会化的",
|
||||
"line_number": 50,
|
||||
"occurrences": 3,
|
||||
"summary": "后天习得的知识"
|
||||
}
|
||||
],
|
||||
"methods": [
|
||||
{
|
||||
"term": "正身",
|
||||
"definition": "挺腰,直背,正脊柱的方法",
|
||||
"line_number": 26,
|
||||
"occurrences": 3,
|
||||
"steps": [
|
||||
"挺腰",
|
||||
"直背",
|
||||
"正脊柱",
|
||||
"鼻子微收"
|
||||
]
|
||||
},
|
||||
{
|
||||
"term": "晃海",
|
||||
"definition": "练正身的方法",
|
||||
"line_number": 26,
|
||||
"occurrences": 2,
|
||||
"steps": []
|
||||
},
|
||||
{
|
||||
"term": "开窍",
|
||||
"definition": "开发人身上的窍门、窍点,相当于安装了信号放大器",
|
||||
"line_number": 62,
|
||||
"occurrences": 10,
|
||||
"steps": [
|
||||
"打开夹脊窍",
|
||||
"打开中丹田窍"
|
||||
]
|
||||
},
|
||||
{
|
||||
"term": "盘腿",
|
||||
"definition": "防漏,分双盘、单盘、散盘",
|
||||
"line_number": 156,
|
||||
"occurrences": 5,
|
||||
"steps": [
|
||||
"选择盘腿方式",
|
||||
"保持坐姿"
|
||||
]
|
||||
},
|
||||
{
|
||||
"term": "人气接引",
|
||||
"definition": "通过打开夹脊窍和中丹田窍来接人气的方法",
|
||||
"line_number": 84,
|
||||
"occurrences": 1,
|
||||
"steps": []
|
||||
}
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"term": "泥丸",
|
||||
"definition": "人的脑垂体,统管内分泌的总窍",
|
||||
"line_number": 70,
|
||||
"occurrences": 3,
|
||||
"location": "脑部"
|
||||
},
|
||||
{
|
||||
"term": "意窍",
|
||||
"definition": "又叫上丹田,在两眉和两眼中间",
|
||||
"line_number": 70,
|
||||
"occurrences": 5,
|
||||
"location": "眉心"
|
||||
},
|
||||
{
|
||||
"term": "玉枕窍",
|
||||
"definition": "又叫神窍,注意不是玉枕穴",
|
||||
"line_number": 70,
|
||||
"occurrences": 3,
|
||||
"location": "后脑"
|
||||
},
|
||||
{
|
||||
"term": "尾闾窍",
|
||||
"definition": "在命门下一寸,肾上腺素集中地",
|
||||
"line_number": 78,
|
||||
"occurrences": 3,
|
||||
"location": "后腰"
|
||||
},
|
||||
{
|
||||
"term": "气海",
|
||||
"definition": "储存人体卫气的窍位",
|
||||
"line_number": 80,
|
||||
"occurrences": 2,
|
||||
"location": "腹部"
|
||||
},
|
||||
{
|
||||
"term": "下丹田",
|
||||
"definition": "在脐内三寸,性激素存储之地",
|
||||
"line_number": 80,
|
||||
"occurrences": 4,
|
||||
"location": "腹部"
|
||||
},
|
||||
{
|
||||
"term": "中丹田",
|
||||
"definition": "又称绛宫,胸腺所在地",
|
||||
"line_number": 84,
|
||||
"occurrences": 5,
|
||||
"location": "胸部"
|
||||
},
|
||||
{
|
||||
"term": "夹脊窍",
|
||||
"definition": "在两胳膊窝的连接处,接人气",
|
||||
"line_number": 84,
|
||||
"occurrences": 4,
|
||||
"location": "背部"
|
||||
},
|
||||
{
|
||||
"term": "会阴窍",
|
||||
"definition": "在肛门前口,也叫阴窍、阴跷窍",
|
||||
"line_number": 80,
|
||||
"occurrences": 3,
|
||||
"location": "会阴"
|
||||
},
|
||||
{
|
||||
"term": "玄牝之门",
|
||||
"definition": "肛门前口的别称",
|
||||
"line_number": 80,
|
||||
"occurrences": 1,
|
||||
"location": "会阴"
|
||||
}
|
||||
],
|
||||
"relationships": [
|
||||
{
|
||||
"source": "精气神",
|
||||
"target": "元气",
|
||||
"type": "extends",
|
||||
"description": "元气是精气神的具体体现"
|
||||
},
|
||||
{
|
||||
"source": "天人感应",
|
||||
"target": "玄空造化场",
|
||||
"type": "example_of",
|
||||
"description": "玄空造化场是天人感应的机制"
|
||||
},
|
||||
{
|
||||
"source": "生气",
|
||||
"target": "元气",
|
||||
"type": "supports",
|
||||
"description": "生气主要补充元气"
|
||||
},
|
||||
{
|
||||
"source": "出死入生",
|
||||
"target": "元气",
|
||||
"type": "affects",
|
||||
"description": "出死损耗元气,入生补充元气"
|
||||
},
|
||||
{
|
||||
"source": "返观",
|
||||
"target": "虚静",
|
||||
"type": "part_of",
|
||||
"description": "返观是达到虚静的方法"
|
||||
}
|
||||
],
|
||||
"key_data": [
|
||||
{
|
||||
"type": "数字",
|
||||
"content": "六十二根神经根组织",
|
||||
"line_number": 26
|
||||
},
|
||||
{
|
||||
"type": "数字",
|
||||
"content": "三十八万公里(月亮离地球距离)",
|
||||
"line_number": 46
|
||||
},
|
||||
{
|
||||
"type": "数字",
|
||||
"content": "九大行星",
|
||||
"line_number": 48
|
||||
},
|
||||
{
|
||||
"type": "具体结论",
|
||||
"content": "精足不思淫,气足不思食,神足不思睡",
|
||||
"line_number": 44
|
||||
},
|
||||
{
|
||||
"type": "具体结论",
|
||||
"content": "身正才能气通,气通才能意静,意静才能神活",
|
||||
"line_number": 26
|
||||
}
|
||||
],
|
||||
"source_summary": "本章主要讲述道家修炼的身体基础,包括脊柱正身的重要性、精气神的概念、天人感应理论、开窍方法等核心内容,强调身体形态对气脉流通和修炼效果的直接影响。",
|
||||
"recommended_pages": [
|
||||
{
|
||||
"title": "精气神",
|
||||
"type": "concept",
|
||||
"reason": "全书核心概念,出现频率高"
|
||||
},
|
||||
{
|
||||
"title": "天人感应",
|
||||
"type": "concept",
|
||||
"reason": "道家理论基础,多个章节涉及"
|
||||
},
|
||||
{
|
||||
"title": "玄空造化场",
|
||||
"type": "concept",
|
||||
"reason": "重要理论机制,解释天人合一"
|
||||
},
|
||||
{
|
||||
"title": "正身",
|
||||
"type": "method",
|
||||
"reason": "修炼第一步,多次提及"
|
||||
},
|
||||
{
|
||||
"title": "开窍",
|
||||
"type": "method",
|
||||
"reason": "关键技术,贯穿全书"
|
||||
},
|
||||
{
|
||||
"title": "泥丸",
|
||||
"type": "entity",
|
||||
"reason": "重要关窍,总窍"
|
||||
},
|
||||
{
|
||||
"title": "意窍",
|
||||
"type": "entity",
|
||||
"reason": "上丹田,出死入生关键"
|
||||
},
|
||||
{
|
||||
"title": "尾闾窍",
|
||||
"type": "entity",
|
||||
"reason": "接地气关键窍位"
|
||||
},
|
||||
{
|
||||
"title": "气海",
|
||||
"type": "entity",
|
||||
"reason": "储存卫气的重要位置"
|
||||
},
|
||||
{
|
||||
"title": "下丹田",
|
||||
"type": "entity",
|
||||
"reason": "性激素存储之地"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
{
|
||||
"source_info": {
|
||||
"filename": "第一编 从身体入手.md",
|
||||
"total_lines": 178,
|
||||
"total_words": 11000,
|
||||
"main_sections": [
|
||||
"我们身体最不正的是什么",
|
||||
"人的精气神从哪里",
|
||||
"关键是\"开窍\"",
|
||||
"现代人不\"开心\"呢",
|
||||
"问答"
|
||||
]
|
||||
},
|
||||
"concepts": [
|
||||
{
|
||||
"term": "精气神",
|
||||
"definition": "天有三宝日、月、星;地有三宝水、火、风;人也有三宝,精、气、神",
|
||||
"line_number": 44,
|
||||
"occurrences": 8,
|
||||
"summary": "道家修炼的三大基本要素"
|
||||
},
|
||||
{
|
||||
"term": "天人感应",
|
||||
"definition": "星体间产生的引力波互相作用,产生类似星系的漩涡能量场",
|
||||
"line_number": 48,
|
||||
"occurrences": 3,
|
||||
"summary": "天体对人产生影响的机制"
|
||||
},
|
||||
{
|
||||
"term": "玄空造化场",
|
||||
"definition": "星体间产生的引力波互相作用形成的漩涡能量场",
|
||||
"line_number": 48,
|
||||
"occurrences": 3,
|
||||
"summary": "影响初生婴儿的能量场"
|
||||
},
|
||||
{
|
||||
"term": "生气",
|
||||
"definition": "玄空造化场里产生的对生命界影响很大的能量",
|
||||
"line_number": 54,
|
||||
"occurrences": 6,
|
||||
"summary": "补充元气的关键能量"
|
||||
},
|
||||
{
|
||||
"term": "元气",
|
||||
"definition": "生气主要补充的能量,真元之气",
|
||||
"line_number": 54,
|
||||
"occurrences": 8,
|
||||
"summary": "人体生命力的基础"
|
||||
},
|
||||
{
|
||||
"term": "出死入生",
|
||||
"definition": "意念外放损耗元气为出死,高效能吸收生气为入生",
|
||||
"line_number": 102,
|
||||
"occurrences": 1,
|
||||
"summary": "能量消耗与补充的对比"
|
||||
},
|
||||
{
|
||||
"term": "返观",
|
||||
"definition": "修静接收能量的方法,能长生",
|
||||
"line_number": 105,
|
||||
"occurrences": 2,
|
||||
"summary": "修炼的收心方法"
|
||||
},
|
||||
{
|
||||
"term": "虚静",
|
||||
"definition": "修道的根本状态",
|
||||
"line_number": 102,
|
||||
"occurrences": 2,
|
||||
"summary": "入定的基础状态"
|
||||
},
|
||||
{
|
||||
"term": "天人合一",
|
||||
"definition": "先天到后天的能量场造化作用",
|
||||
"line_number": 48,
|
||||
"occurrences": 3,
|
||||
"summary": "天人合一的能量场机制"
|
||||
},
|
||||
{
|
||||
"term": "先天",
|
||||
"definition": "本能的、自然的",
|
||||
"line_number": 50,
|
||||
"occurrences": 5,
|
||||
"summary": "人与生俱来的功能"
|
||||
},
|
||||
{
|
||||
"term": "后天",
|
||||
"definition": "人为的、社会化的",
|
||||
"line_number": 50,
|
||||
"occurrences": 3,
|
||||
"summary": "后天习得的知识"
|
||||
}
|
||||
],
|
||||
"methods": [
|
||||
{
|
||||
"term": "正身",
|
||||
"definition": "挺腰,直背,正脊柱的方法",
|
||||
"line_number": 26,
|
||||
"occurrences": 3,
|
||||
"steps": [
|
||||
"挺腰",
|
||||
"直背",
|
||||
"正脊柱",
|
||||
"鼻子微收"
|
||||
]
|
||||
},
|
||||
{
|
||||
"term": "晃海",
|
||||
"definition": "练正身的方法",
|
||||
"line_number": 26,
|
||||
"occurrences": 2,
|
||||
"steps": []
|
||||
},
|
||||
{
|
||||
"term": "开窍",
|
||||
"definition": "开发人身上的窍门、窍点,相当于安装了信号放大器",
|
||||
"line_number": 62,
|
||||
"occurrences": 10,
|
||||
"steps": [
|
||||
"打开夹脊窍",
|
||||
"打开中丹田窍"
|
||||
]
|
||||
},
|
||||
{
|
||||
"term": "盘腿",
|
||||
"definition": "防漏,分双盘、单盘、散盘",
|
||||
"line_number": 156,
|
||||
"occurrences": 5,
|
||||
"steps": [
|
||||
"选择盘腿方式",
|
||||
"保持坐姿"
|
||||
]
|
||||
},
|
||||
{
|
||||
"term": "人气接引",
|
||||
"definition": "通过打开夹脊窍和中丹田窍来接人气的方法",
|
||||
"line_number": 84,
|
||||
"occurrences": 1,
|
||||
"steps": []
|
||||
}
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"term": "泥丸",
|
||||
"definition": "人的脑垂体,统管内分泌的总窍",
|
||||
"line_number": 70,
|
||||
"occurrences": 3,
|
||||
"location": "脑部"
|
||||
},
|
||||
{
|
||||
"term": "意窍",
|
||||
"definition": "又叫上丹田,在两眉和两眼中间",
|
||||
"line_number": 70,
|
||||
"occurrences": 5,
|
||||
"location": "眉心"
|
||||
},
|
||||
{
|
||||
"term": "玉枕窍",
|
||||
"definition": "又叫神窍,注意不是玉枕穴",
|
||||
"line_number": 70,
|
||||
"occurrences": 3,
|
||||
"location": "后脑"
|
||||
},
|
||||
{
|
||||
"term": "尾闾窍",
|
||||
"definition": "在命门下一寸,肾上腺素集中地",
|
||||
"line_number": 78,
|
||||
"occurrences": 3,
|
||||
"location": "后腰"
|
||||
},
|
||||
{
|
||||
"term": "气海",
|
||||
"definition": "储存人体卫气的窍位",
|
||||
"line_number": 80,
|
||||
"occurrences": 2,
|
||||
"location": "腹部"
|
||||
},
|
||||
{
|
||||
"term": "下丹田",
|
||||
"definition": "在脐内三寸,性激素存储之地",
|
||||
"line_number": 80,
|
||||
"occurrences": 4,
|
||||
"location": "腹部"
|
||||
},
|
||||
{
|
||||
"term": "中丹田",
|
||||
"definition": "又称绛宫,胸腺所在地",
|
||||
"line_number": 84,
|
||||
"occurrences": 5,
|
||||
"location": "胸部"
|
||||
},
|
||||
{
|
||||
"term": "夹脊窍",
|
||||
"definition": "在两胳膊窝的连接处,接人气",
|
||||
"line_number": 84,
|
||||
"occurrences": 4,
|
||||
"location": "背部"
|
||||
},
|
||||
{
|
||||
"term": "会阴窍",
|
||||
"definition": "在肛门前口,也叫阴窍、阴跷窍",
|
||||
"line_number": 80,
|
||||
"occurrences": 3,
|
||||
"location": "会阴"
|
||||
},
|
||||
{
|
||||
"term": "玄牝之门",
|
||||
"definition": "肛门前口的别称",
|
||||
"line_number": 80,
|
||||
"occurrences": 1,
|
||||
"location": "会阴"
|
||||
}
|
||||
],
|
||||
"relationships": [
|
||||
{
|
||||
"source": "精气神",
|
||||
"target": "元气",
|
||||
"type": "extends",
|
||||
"description": "元气是精气神的具体体现"
|
||||
},
|
||||
{
|
||||
"source": "天人感应",
|
||||
"target": "玄空造化场",
|
||||
"type": "example_of",
|
||||
"description": "玄空造化场是天人感应的机制"
|
||||
},
|
||||
{
|
||||
"source": "生气",
|
||||
"target": "元气",
|
||||
"type": "supports",
|
||||
"description": "生气主要补充元气"
|
||||
},
|
||||
{
|
||||
"source": "出死入生",
|
||||
"target": "元气",
|
||||
"type": "affects",
|
||||
"description": "出死损耗元气,入生补充元气"
|
||||
},
|
||||
{
|
||||
"source": "返观",
|
||||
"target": "虚静",
|
||||
"type": "part_of",
|
||||
"description": "返观是达到虚静的方法"
|
||||
}
|
||||
],
|
||||
"key_data": [
|
||||
{
|
||||
"type": "数字",
|
||||
"content": "六十二根神经根组织",
|
||||
"line_number": 26
|
||||
},
|
||||
{
|
||||
"type": "数字",
|
||||
"content": "三十八万公里(月亮离地球距离)",
|
||||
"line_number": 46
|
||||
},
|
||||
{
|
||||
"type": "数字",
|
||||
"content": "九大行星",
|
||||
"line_number": 48
|
||||
},
|
||||
{
|
||||
"type": "具体结论",
|
||||
"content": "精足不思淫,气足不思食,神足不思睡",
|
||||
"line_number": 44
|
||||
},
|
||||
{
|
||||
"type": "具体结论",
|
||||
"content": "身正才能气通,气通才能意静,意静才能神活",
|
||||
"line_number": 26
|
||||
}
|
||||
],
|
||||
"source_summary": "本章主要讲述道家修炼的身体基础,包括脊柱正身的重要性、精气神的概念、天人感应理论、开窍方法等核心内容,强调身体形态对气脉流通和修炼效果的直接影响。",
|
||||
"recommended_pages": [
|
||||
{
|
||||
"title": "精气神",
|
||||
"type": "concept",
|
||||
"reason": "全书核心概念,出现频率高"
|
||||
},
|
||||
{
|
||||
"title": "天人感应",
|
||||
"type": "concept",
|
||||
"reason": "道家理论基础,多个章节涉及"
|
||||
},
|
||||
{
|
||||
"title": "玄空造化场",
|
||||
"type": "concept",
|
||||
"reason": "重要理论机制,解释天人合一"
|
||||
},
|
||||
{
|
||||
"title": "正身",
|
||||
"type": "method",
|
||||
"reason": "修炼第一步,多次提及"
|
||||
},
|
||||
{
|
||||
"title": "开窍",
|
||||
"type": "method",
|
||||
"reason": "关键技术,贯穿全书"
|
||||
},
|
||||
{
|
||||
"title": "泥丸",
|
||||
"type": "entity",
|
||||
"reason": "重要关窍,总窍"
|
||||
},
|
||||
{
|
||||
"title": "意窍",
|
||||
"type": "entity",
|
||||
"reason": "上丹田,出死入生关键"
|
||||
},
|
||||
{
|
||||
"title": "尾闾窍",
|
||||
"type": "entity",
|
||||
"reason": "接地气关键窍位"
|
||||
},
|
||||
{
|
||||
"title": "气海",
|
||||
"type": "entity",
|
||||
"reason": "储存卫气的重要位置"
|
||||
},
|
||||
{
|
||||
"title": "下丹田",
|
||||
"type": "entity",
|
||||
"reason": "性激素存储之地"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"group": "A",
|
||||
"mode": "Two-Step",
|
||||
"sourceFile": "raw/呼吸之间_李谨伯/第一编 从身体入手.md",
|
||||
"startTime": "2026-07-03 21:02:57",
|
||||
"endTime": "2026-07-03 21:02:57",
|
||||
"durationMinutes": 0.0,
|
||||
"step1Status": "completed",
|
||||
"step2Status": "completed",
|
||||
"pagesGenerated": 10
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- concept
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: concept
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 天人感应
|
||||
|
||||
> **一句话定义**:道家修炼的核心概念[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
道家理论基础,多个章节涉及。
|
||||
|
||||
## 关键要点
|
||||
|
||||
- 要点 1[raw:第一编 从身体入手.md:1]
|
||||
- 要点 2[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 道家修炼理论
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- concept
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: concept
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 玄空造化场
|
||||
|
||||
> **一句话定义**:道家修炼的核心概念[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
重要理论机制,解释天人合一。
|
||||
|
||||
## 关键要点
|
||||
|
||||
- 要点 1[raw:第一编 从身体入手.md:1]
|
||||
- 要点 2[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 道家修炼理论
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- concept
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: concept
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 精气神
|
||||
|
||||
> **一句话定义**:道家修炼的核心概念[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
全书核心概念,出现频率高。
|
||||
|
||||
## 关键要点
|
||||
|
||||
- 要点 1[raw:第一编 从身体入手.md:1]
|
||||
- 要点 2[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 道家修炼理论
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- entity
|
||||
- 关窍
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: entity
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 下丹田
|
||||
|
||||
> **一句话定义**:重要的修炼关窍[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
性激素存储之地。
|
||||
|
||||
## 位置描述
|
||||
|
||||
- 位置:体内[raw:第一编 从身体入手.md:1]
|
||||
- 功能:接气[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 关窍位置
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- entity
|
||||
- 关窍
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: entity
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 尾闾窍
|
||||
|
||||
> **一句话定义**:重要的修炼关窍[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
接地气关键窍位。
|
||||
|
||||
## 位置描述
|
||||
|
||||
- 位置:体内[raw:第一编 从身体入手.md:1]
|
||||
- 功能:接气[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 关窍位置
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- entity
|
||||
- 关窍
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: entity
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 意窍
|
||||
|
||||
> **一句话定义**:重要的修炼关窍[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
上丹田,出死入生关键。
|
||||
|
||||
## 位置描述
|
||||
|
||||
- 位置:体内[raw:第一编 从身体入手.md:1]
|
||||
- 功能:接气[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 关窍位置
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- entity
|
||||
- 关窍
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: entity
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 气海
|
||||
|
||||
> **一句话定义**:重要的修炼关窍[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
储存卫气的重要位置。
|
||||
|
||||
## 位置描述
|
||||
|
||||
- 位置:体内[raw:第一编 从身体入手.md:1]
|
||||
- 功能:接气[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 关窍位置
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- entity
|
||||
- 关窍
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: entity
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 泥丸
|
||||
|
||||
> **一句话定义**:重要的修炼关窍[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
重要关窍,总窍。
|
||||
|
||||
## 位置描述
|
||||
|
||||
- 位置:体内[raw:第一编 从身体入手.md:1]
|
||||
- 功能:接气[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 关窍位置
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- method
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: method
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 开窍
|
||||
|
||||
> **一句话定义**:道家修炼的重要方法[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
关键技术,贯穿全书。
|
||||
|
||||
## 方法步骤
|
||||
|
||||
- 步骤 1[raw:第一编 从身体入手.md:1]
|
||||
- 步骤 2[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 道家修炼方法
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- method
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: method
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 正身
|
||||
|
||||
> **一句话定义**:道家修炼的重要方法[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
修炼第一步,多次提及。
|
||||
|
||||
## 方法步骤
|
||||
|
||||
- 步骤 1[raw:第一编 从身体入手.md:1]
|
||||
- 步骤 2[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 道家修炼方法
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"group": "B",
|
||||
"mode": "Single-Step",
|
||||
"sourceFile": "raw/呼吸之间_李谨伯/第一编 从身体入手.md",
|
||||
"startTime": "2026-07-03 21:02:58",
|
||||
"endTime": "2026-07-03 21:02:58",
|
||||
"durationMinutes": 0.0,
|
||||
"pagesGenerated": 8
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- concept
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: concept
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 天人感应
|
||||
|
||||
> **一句话定义**:天体对人产生影响的机制[raw:第一编 从身体入手.md:48]。
|
||||
|
||||
## 定义
|
||||
|
||||
星体间产生的引力波互相作用,产生类似星系的漩涡能量场[raw:第一编 从身体入手.md:48]。
|
||||
|
||||
## 关键要点
|
||||
|
||||
- 出现次数: 3[raw:第一编 从身体入手.md:48]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 天体对人产生影响的机制
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- concept
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: concept
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 玄空造化场
|
||||
|
||||
> **一句话定义**:影响初生婴儿的能量场[raw:第一编 从身体入手.md:48]。
|
||||
|
||||
## 定义
|
||||
|
||||
星体间产生的引力波互相作用形成的漩涡能量场[raw:第一编 从身体入手.md:48]。
|
||||
|
||||
## 关键要点
|
||||
|
||||
- 出现次数: 3[raw:第一编 从身体入手.md:48]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 影响初生婴儿的能量场
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- concept
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: concept
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 精气神
|
||||
|
||||
> **一句话定义**:道家修炼的三大基本要素[raw:第一编 从身体入手.md:44]。
|
||||
|
||||
## 定义
|
||||
|
||||
天有三宝日、月、星;地有三宝水、火、风;人也有三宝,精、气、神[raw:第一编 从身体入手.md:44]。
|
||||
|
||||
## 关键要点
|
||||
|
||||
- 出现次数: 8[raw:第一编 从身体入手.md:44]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 道家修炼的三大基本要素
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- entity
|
||||
- 关窍
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: entity
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 意窍
|
||||
|
||||
> **一句话定义**:又叫上丹田,在两眉和两眼中间[raw:第一编 从身体入手.md:70]。
|
||||
|
||||
## 定义
|
||||
|
||||
又叫上丹田,在两眉和两眼中间[raw:第一编 从身体入手.md:70]。
|
||||
|
||||
## 位置描述
|
||||
|
||||
- 位置: 眉心[raw:第一编 从身体入手.md:70]
|
||||
- 出现次数: 5[raw:第一编 从身体入手.md:70]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 又叫上丹田,在两眉和两眼中间
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- entity
|
||||
- 关窍
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: entity
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 泥丸
|
||||
|
||||
> **一句话定义**:人的脑垂体,统管内分泌的总窍[raw:第一编 从身体入手.md:70]。
|
||||
|
||||
## 定义
|
||||
|
||||
人的脑垂体,统管内分泌的总窍[raw:第一编 从身体入手.md:70]。
|
||||
|
||||
## 位置描述
|
||||
|
||||
- 位置: 脑部[raw:第一编 从身体入手.md:70]
|
||||
- 出现次数: 3[raw:第一编 从身体入手.md:70]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 人的脑垂体,统管内分泌的总窍
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- entity
|
||||
- 关窍
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: entity
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 玉枕窍
|
||||
|
||||
> **一句话定义**:又叫神窍,注意不是玉枕穴[raw:第一编 从身体入手.md:70]。
|
||||
|
||||
## 定义
|
||||
|
||||
又叫神窍,注意不是玉枕穴[raw:第一编 从身体入手.md:70]。
|
||||
|
||||
## 位置描述
|
||||
|
||||
- 位置: 后脑[raw:第一编 从身体入手.md:70]
|
||||
- 出现次数: 3[raw:第一编 从身体入手.md:70]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 又叫神窍,注意不是玉枕穴
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- method
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: method
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 晃海
|
||||
|
||||
> **一句话定义**:练正身的方法[raw:第一编 从身体入手.md:26]。
|
||||
|
||||
## 定义
|
||||
|
||||
练正身的方法[raw:第一编 从身体入手.md:26]。
|
||||
|
||||
## 方法步骤
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 练正身的方法
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- method
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: method
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 正身
|
||||
|
||||
> **一句话定义**:挺腰,直背,正脊柱的方法[raw:第一编 从身体入手.md:26]。
|
||||
|
||||
## 定义
|
||||
|
||||
挺腰,直背,正脊柱的方法[raw:第一编 从身体入手.md:26]。
|
||||
|
||||
## 方法步骤
|
||||
|
||||
- 挺腰[raw:第一编 从身体入手.md:26]
|
||||
- 直背[raw:第一编 从身体入手.md:26]
|
||||
- 正脊柱[raw:第一编 从身体入手.md:26]
|
||||
- 鼻子微收[raw:第一编 从身体入手.md:26]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 挺腰,直背,正脊柱的方法
|
||||
@@ -0,0 +1,97 @@
|
||||
# Wiki 生成质量对比实验报告
|
||||
|
||||
## 实验概览
|
||||
|
||||
- **测试文件**: raw/呼吸之间_李谨伯/第一编 从身体入手.md
|
||||
- **金标准术语数**: 26
|
||||
- **A 组模式**: Two-Step(分析 + 生成)
|
||||
- **B 组模式**: Single-Step(直接生成)
|
||||
- **权重配置**: 40% 内容完整性 + 30% 技术规范性 + 20% 可维护性 + 10% 效率成本
|
||||
|
||||
## 执行时间
|
||||
|
||||
| 组别 | 模式 | 开始时间 | 结束时间 | 耗时(分钟) | 生成页面数 |
|
||||
|------|------|----------|----------|-------------|-----------|
|
||||
| A 组 | Two-Step | 2026-07-03 21:02:57 | 2026-07-03 21:02:57 | 0.0 | 10 |
|
||||
| B 组 | Single-Step | 2026-07-03 21:02:58 | 2026-07-03 21:02:58 | 0.0 | 8 |
|
||||
|
||||
## 详细得分
|
||||
|
||||
### A 组(Two-Step)
|
||||
|
||||
| 维度 | 得分 | 权重 | 加权得分 |
|
||||
|------|------|------|---------|
|
||||
| 内容完整性 | 75.4% | 40% | 30.2 |
|
||||
| 技术规范性 | 60.0% | 30% | 18.0 |
|
||||
| 可维护性 | 80.0% | 20% | 16.0 |
|
||||
| 效率成本 | 100.0% | 10% | 10.0 |
|
||||
| **总分** | - | **100%** | **74.2** |
|
||||
|
||||
### B 组(Single-Step)
|
||||
|
||||
| 维度 | 得分 | 权重 | 加权得分 |
|
||||
|------|------|------|---------|
|
||||
| 内容完整性 | 72.3% | 40% | 28.9 |
|
||||
| 技术规范性 | 60.0% | 30% | 18.0 |
|
||||
| 可维护性 | 80.0% | 20% | 16.0 |
|
||||
| 效率成本 | 100.0% | 10% | 10.0 |
|
||||
| **总分** | - | **100%** | **72.9** |
|
||||
|
||||
## 详细对比
|
||||
|
||||
### 1. 术语覆盖度
|
||||
|
||||
| 组别 | 金标准术语数 | 覆盖术语数 | 覆盖率 | 未覆盖术语 |
|
||||
|------|-------------|-----------|--------|-----------|
|
||||
| A 组 | 26 | 10 | 38.5% | 16 个 |
|
||||
| B 组 | 26 | 8 | 30.8% | 18 个 |
|
||||
|
||||
**A 组未覆盖术语**: 生气, 元气, 出死入生, 返观, 虚静…
|
||||
**B 组未覆盖术语**: 生气, 元气, 出死入生, 返观, 虚静…
|
||||
|
||||
### 2. Frontmatter 规范性
|
||||
|
||||
| 组别 | 总文件数 | 平均字段完整度 |
|
||||
|------|---------|---------------|
|
||||
| A 组 | 10 | 100.0% |
|
||||
| B 组 | 8 | 100.0% |
|
||||
|
||||
### 3. Wikilink 质量
|
||||
|
||||
| 组别 | 总链接数 | 有效链接数 | 无效链接数 | 链接准确率 |
|
||||
|------|---------|-----------|-----------|-----------|
|
||||
| A 组 | 30 | 0 | 30 | 0.0% |
|
||||
| B 组 | 24 | 0 | 24 | 0.0% |
|
||||
|
||||
### 4. 内容质量细节
|
||||
|
||||
| 组别 | 有定义 | 有来源链接 | 有行号标注 |
|
||||
|------|--------|-----------|-----------|
|
||||
| A 组 | 10/10 | 10/10 | 10/10 |
|
||||
| B 组 | 8/8 | 8/8 | 8/8 |
|
||||
|
||||
## 结论
|
||||
|
||||
### 综合评价
|
||||
|
||||
**A 组(Two-Step 模式)总分更高,推荐使用。**
|
||||
|
||||
### 各维度对比
|
||||
|
||||
- **内容完整性**: A 组优于 B 组(75.4% vs 72.3%)
|
||||
- **技术规范性**: B 组优于 A 组(60.0% vs 60.0%)
|
||||
- **效率成本**: B 组优于 A 组
|
||||
|
||||
## 附录:生成页面列表
|
||||
|
||||
### A 组生成页面
|
||||
|
||||
天人感应, 玄空造化场, 精气神, 下丹田, 尾闾窍, 意窍, 气海, 泥丸, 开窍, 正身
|
||||
|
||||
### B 组生成页面
|
||||
|
||||
天人感应, 玄空造化场, 精气神, 意窍, 泥丸, 玉枕窍, 晃海, 正身
|
||||
|
||||
---
|
||||
|
||||
**报告生成时间**: 2026-07-03 21:06:23
|
||||
@@ -0,0 +1,130 @@
|
||||
你是一位知识库构建专家。请直接从源文件中提取关键术语,并生成完整的 Wiki 页面。
|
||||
|
||||
## 任务说明
|
||||
|
||||
阅读以下源文件,识别其中的关键术语(概念、方法、实体),并为每个术语创建完整的 Wiki 页面。
|
||||
|
||||
## 术语类型
|
||||
|
||||
1. **概念类**:理论术语(如:精气神、天人感应、玄空造化场)
|
||||
2. **方法类**:修炼方法(如:正身、晃海、开窍、盘腿)
|
||||
3. **实体类**:关窍位置(如:泥丸、意窍、玉枕窍、尾闾窍)
|
||||
|
||||
## Wiki 页面格式
|
||||
|
||||
每个页面必须包含:
|
||||
|
||||
1. **YAML Frontmatter**:
|
||||
```yaml
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
- "[[道家修炼]]"
|
||||
tags:
|
||||
- wiki
|
||||
- concept # concept/entity/method
|
||||
- 道家
|
||||
- 养生
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: concept # concept/entity/method
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
```
|
||||
|
||||
2. **正文结构**:
|
||||
```markdown
|
||||
# {术语名称}
|
||||
|
||||
> **一句话定义**:{核心定义}
|
||||
|
||||
## 定义
|
||||
|
||||
{详细的定义和解释}
|
||||
|
||||
## 关键要点
|
||||
|
||||
- 要点 1
|
||||
- 要点 2
|
||||
|
||||
## 与其他概念的关系
|
||||
|
||||
- [[相关概念]] — {关系说明}
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 具体说明
|
||||
```
|
||||
|
||||
## 源文件内容
|
||||
|
||||
{SOURCE_CONTENT}
|
||||
|
||||
## 生成要求
|
||||
|
||||
1. **术语识别**:
|
||||
- 优先提取书中明确定义的术语
|
||||
- 每个术语独立创建页面
|
||||
- 避免合并不同的概念
|
||||
|
||||
2. **内容准确**:
|
||||
- 定义必须引用原书原话
|
||||
- 所有数字/百分比必须标注 `[raw:第一编 从身体入手.md:行号]`
|
||||
|
||||
3. **文件格式**:
|
||||
- 每个页面用 `---FILE: wiki/{type}/{术语}.md---` 包裹
|
||||
- 结尾用 `---END FILE---` 标记
|
||||
|
||||
4. **链接质量**:
|
||||
- 使用 `[[术语]]` 格式创建内部链接
|
||||
- 同一批次生成的术语应相互链接
|
||||
|
||||
## 输出格式示例
|
||||
|
||||
```
|
||||
---FILE: wiki/concepts/精气神.md---
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
- "[[道家修炼]]"
|
||||
tags:
|
||||
- wiki
|
||||
- concept
|
||||
- 道家
|
||||
- 养生
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: concept
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# 精气神
|
||||
|
||||
> **一句话定义**:道家修炼的三大基本要素——精、气、神,称为人身"三宝"[raw:第一编 从身体入手.md:44]。
|
||||
|
||||
## 定义
|
||||
|
||||
天有三宝,日、月、星;地有三宝,水、火、风;人也有三宝,精、气、神[raw:第一编 从身体入手.md:44]。
|
||||
|
||||
## 关键要点
|
||||
|
||||
- 精足不思淫,气足不思食,神足不思睡[raw:第一编 从身体入手.md:44]
|
||||
|
||||
## 与其他概念的关系
|
||||
|
||||
- [[元气]] — 生气主要补充的就是元气[raw:第一编 从身体入手.md:54]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]
|
||||
---END FILE---
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 不要跳过重要的术语
|
||||
2. 每个页面保持边界清晰
|
||||
3. Frontmatter 字段必须完整
|
||||
4. 所有来源引用必须标注行号
|
||||
@@ -0,0 +1,99 @@
|
||||
你是一位知识库分析专家。请仔细分析以下源文件,提取结构化信息。
|
||||
|
||||
## 任务说明
|
||||
|
||||
从源文件中提取以下结构化信息,以 JSON 格式输出:
|
||||
|
||||
```json
|
||||
{
|
||||
"source_info": {
|
||||
"filename": "文件名",
|
||||
"total_lines": 总行数,
|
||||
"total_words": 总字数,
|
||||
"main_sections": ["主要小节1", "主要小节2", ...]
|
||||
},
|
||||
"concepts": [
|
||||
{
|
||||
"term": "概念名称",
|
||||
"definition": "定义内容",
|
||||
"line_number": 行号,
|
||||
"occurrences": 出现次数,
|
||||
"summary": "简要概述"
|
||||
}
|
||||
],
|
||||
"methods": [
|
||||
{
|
||||
"term": "方法名称",
|
||||
"definition": "定义内容",
|
||||
"line_number": 行号,
|
||||
"occurrences": 出现次数,
|
||||
"steps": ["步骤1", "步骤2", ...]
|
||||
}
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"term": "实体名称",
|
||||
"definition": "定义内容",
|
||||
"line_number": 行号,
|
||||
"occurrences": 出现次数,
|
||||
"location": "位置描述"
|
||||
}
|
||||
],
|
||||
"relationships": [
|
||||
{
|
||||
"source": "术语A",
|
||||
"target": "术语B",
|
||||
"type": "part_of|extends|example_of|contradicts|supports",
|
||||
"description": "关系说明"
|
||||
}
|
||||
],
|
||||
"key_data": [
|
||||
{
|
||||
"type": "数字|百分比|结论",
|
||||
"content": "数据内容",
|
||||
"line_number": 行号
|
||||
}
|
||||
],
|
||||
"source_summary": "源文件的完整摘要,约 200-300 字",
|
||||
"recommended_pages": [
|
||||
{
|
||||
"title": "页面标题",
|
||||
"type": "concept|entity|method",
|
||||
"reason": "创建理由"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 分析要求
|
||||
|
||||
1. **术语识别**:
|
||||
- 概念类:理论术语(如:精气神、天人感应)
|
||||
- 方法类:修炼方法(如:正身、开窍)
|
||||
- 实体类:关窍位置(如:泥丸、意窍)
|
||||
|
||||
2. **定义提取**:
|
||||
- 优先提取书中明确定义的句子
|
||||
- 记录行号(从 1 开始计数)
|
||||
|
||||
3. **关系识别**:
|
||||
- 识别术语间的依赖、包含、示例、矛盾等关系
|
||||
- 特别关注"部分"关系(如:精气神包含精、气、神)
|
||||
|
||||
4. **数据点提取**:
|
||||
- 数字、百分比、具体结论
|
||||
- 必须记录行号
|
||||
|
||||
5. **推荐页面**:
|
||||
- 基于分析结果,推荐应创建的 Wiki 页面
|
||||
- 说明推荐理由
|
||||
|
||||
## 源文件内容
|
||||
|
||||
{SOURCE_CONTENT}
|
||||
|
||||
## 输出要求
|
||||
|
||||
- 仅输出 JSON,不要包含其他文字
|
||||
- 确保是有效的 JSON 格式
|
||||
- 数组项数量根据实际内容确定,不必强制填满
|
||||
@@ -0,0 +1,137 @@
|
||||
你是一位知识库构建专家。请基于以下分析结果,生成完整的 Wiki 页面。
|
||||
|
||||
## 任务说明
|
||||
|
||||
根据 Step 1 的分析结果,为每个推荐页面生成完整的 Markdown Wiki 页面。
|
||||
|
||||
每个页面必须包含:
|
||||
|
||||
1. **YAML Frontmatter**(符合 AGENTS.md 规范):
|
||||
```yaml
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
- "[[道家修炼]]" # 根据内容调整
|
||||
tags:
|
||||
- wiki
|
||||
- concept # concept/entity/method
|
||||
- 道家
|
||||
- 养生 # 根据内容调整
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: concept # concept/entity/method
|
||||
confidence: 3 # 1-5:1=推测 2=单源 3=已验证 4=多源一致 5=无可争议
|
||||
status: active # active/superseded/deprecated/tentative/needs-review
|
||||
relations:
|
||||
- type: part_of
|
||||
target: "[[父级术语]]"
|
||||
description: "关系说明"
|
||||
confidence: 3
|
||||
---
|
||||
```
|
||||
|
||||
2. **正文结构**:
|
||||
```markdown
|
||||
# {术语名称}
|
||||
|
||||
> **一句话定义**:{核心定义}
|
||||
|
||||
## 定义
|
||||
|
||||
{详细的定义和解释}
|
||||
|
||||
## 关键要点
|
||||
|
||||
- 要点 1
|
||||
- 要点 2
|
||||
|
||||
## 与其他概念的关系
|
||||
|
||||
- [[相关概念]] — {关系说明}
|
||||
|
||||
## 来源
|
||||
|
||||
> **溯源规则**:所有数字/百分比/具体结论必须标注 `[raw:第一编 从身体入手.md:行号]` 格式。
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 具体说明
|
||||
```
|
||||
|
||||
## 分析结果(Step 1 输出)
|
||||
|
||||
{ANALYSIS_RESULT}
|
||||
|
||||
## 生成要求
|
||||
|
||||
1. **文件格式**:
|
||||
- 每个页面用 `---FILE: wiki/{type}/{术语}.md---` 包裹
|
||||
- 结尾用 `---END FILE---` 标记
|
||||
|
||||
2. **内容要求**:
|
||||
- 定义必须准确引用原书
|
||||
- 关键要点需提取书中的原话或准确概括
|
||||
- 所有数字/百分比必须标注 `[raw:文件名:行号]`
|
||||
|
||||
3. **链接要求**:
|
||||
- 使用 `[[术语]]` 格式创建内部链接
|
||||
- 优先链接到同批次生成的页面
|
||||
- 如果术语已存在于 Wiki 中,链接到现有页面
|
||||
|
||||
4. **布尔值规范**:
|
||||
- 所有布尔值用引号包裹:`marp: "true"`
|
||||
|
||||
## 输出格式示例
|
||||
|
||||
```
|
||||
---FILE: wiki/concepts/精气神.md---
|
||||
---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
- "[[道家修炼]]"
|
||||
tags:
|
||||
- wiki
|
||||
- concept
|
||||
- 道家
|
||||
- 养生
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: concept
|
||||
confidence: 3
|
||||
status: active
|
||||
relations:
|
||||
- type: part_of
|
||||
target: "[[道家修炼基础]]"
|
||||
description: "精气神是道家修炼的三大基本要素"
|
||||
confidence: 3
|
||||
---
|
||||
|
||||
# 精气神
|
||||
|
||||
> **一句话定义**:道家修炼的三大基本要素——精、气、神,称为人身"三宝"[raw:第一编 从身体入手.md:44]。
|
||||
|
||||
## 定义
|
||||
|
||||
天有三宝,日、月、星;地有三宝,水、火、风;人也有三宝,精、气、神[raw:第一编 从身体入手.md:44]。修道的人可以几天不吃饭,也可以一天吃好几顿。所谓"精足不思淫,气足不思食,神足不思睡"[raw:第一编 从身体入手.md:44]。
|
||||
|
||||
## 关键要点
|
||||
|
||||
- 精足不思淫,气足不思食,神足不思睡[raw:第一编 从身体入手.md:44]
|
||||
- 精气神来自天、地、人三宝的补充[raw:第一编 从身体入手.md:44]
|
||||
- 闭关时,辟谷不吃饭,靠服气[raw:第一编 从身体入手.md:44]
|
||||
|
||||
## 与其他概念的关系
|
||||
|
||||
- [[元气]] — 生气主要补充的就是元气[raw:第一编 从身体入手.md:54]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 道家修炼基础理论
|
||||
---END FILE---
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **不要生成空文件**
|
||||
2. **不要合并不同的概念**
|
||||
3. **每个页面保持边界清晰**
|
||||
4. **Frontmatter 字段必须完整**
|
||||
5. **所有来源引用必须标注行号**
|
||||
@@ -0,0 +1,14 @@
|
||||
# 清理脚本
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$experimentDir = "tools/experiments/wiki-generation-compare/output"
|
||||
|
||||
Write-Host "=== 清理实验环境 ===" -ForegroundColor Cyan
|
||||
|
||||
if (Test-Path $experimentDir) {
|
||||
Write-Host "删除输出目录: $experimentDir" -ForegroundColor Yellow
|
||||
Remove-Item -Path $experimentDir -Recurse -Force
|
||||
Write-Host "✓ 清理完成" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "输出目录不存在,无需清理" -ForegroundColor Yellow
|
||||
}
|
||||
@@ -0,0 +1,466 @@
|
||||
# 评估脚本
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# 配置
|
||||
$goldStandardFile = "tools/experiments/wiki-generation-compare/gold-standard.json"
|
||||
$groupADir = "tools/experiments/wiki-generation-compare/output/group-a/wiki"
|
||||
$groupBDir = "tools/experiments/wiki-generation-compare/output/group-b/wiki"
|
||||
$reportFile = "tools/experiments/wiki-generation-compare/output/report.md"
|
||||
|
||||
Write-Host "=== 开始评估 ===" -ForegroundColor Cyan
|
||||
|
||||
# 检查金标准文件
|
||||
if (!(Test-Path $goldStandardFile)) {
|
||||
Write-Host "✗ 金标准文件不存在: $goldStandardFile" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 加载金标准
|
||||
$goldStandard = Get-Content $goldStandardFile -Raw | ConvertFrom-Json
|
||||
|
||||
# 定义权重
|
||||
$weights = @{
|
||||
contentCompleteness = 0.4
|
||||
technicalCompliance = 0.3
|
||||
maintainability = 0.2
|
||||
efficiency = 0.1
|
||||
}
|
||||
|
||||
# 辅助函数:计算术语覆盖度
|
||||
function Calculate-TermCoverage {
|
||||
param (
|
||||
[string]$wikiDir,
|
||||
[hashtable]$goldTerms
|
||||
)
|
||||
|
||||
# 获取所有生成的 Wiki 文件
|
||||
$wikiFiles = Get-ChildItem -Path $wikiDir -Recurse -Filter "*.md" -ErrorAction SilentlyContinue
|
||||
$generatedTerms = @{}
|
||||
|
||||
if ($wikiFiles) {
|
||||
foreach ($file in $wikiFiles) {
|
||||
$termName = $file.BaseName
|
||||
$generatedTerms[$termName] = @{
|
||||
file = $file.FullName
|
||||
hasDefinition = $false
|
||||
hasSourceLink = $false
|
||||
hasLineNumber = $false
|
||||
}
|
||||
|
||||
# 检查内容
|
||||
$content = Get-Content $file.FullName -Raw -Encoding UTF8
|
||||
|
||||
# 检查是否有定义
|
||||
if ($content -match "> \*\*一句话定义\*\*") {
|
||||
$generatedTerms[$termName].hasDefinition = $true
|
||||
}
|
||||
|
||||
# 检查是否有来源链接
|
||||
if ($content -match "\[\[raw/呼吸之间_李谨伯") {
|
||||
$generatedTerms[$termName].hasSourceLink = $true
|
||||
}
|
||||
|
||||
# 检查是否有行号标注
|
||||
if ($content -match "\[raw:.*:\d+\]") {
|
||||
$generatedTerms[$termName].hasLineNumber = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 计算覆盖度
|
||||
$coveredCount = 0
|
||||
$totalTerms = $goldTerms.Count
|
||||
|
||||
foreach ($term in $goldTerms.Keys) {
|
||||
if ($generatedTerms.ContainsKey($term)) {
|
||||
$coveredCount++
|
||||
}
|
||||
}
|
||||
|
||||
$coverageRate = if ($totalTerms -gt 0) { $coveredCount / $totalTerms } else { 0 }
|
||||
|
||||
@{
|
||||
totalGoldTerms = $totalTerms
|
||||
coveredTerms = $coveredCount
|
||||
coverageRate = $coverageRate
|
||||
generatedTerms = $generatedTerms
|
||||
missedTerms = $goldTerms.Keys | Where-Object { -not $generatedTerms.ContainsKey($_) }
|
||||
}
|
||||
}
|
||||
|
||||
# 辅助函数:评估 Frontmatter 规范性
|
||||
function Evaluate-Frontmatter {
|
||||
param (
|
||||
[string]$wikiDir
|
||||
)
|
||||
|
||||
$wikiFiles = Get-ChildItem -Path $wikiDir -Recurse -Filter "*.md" -ErrorAction SilentlyContinue
|
||||
$results = @()
|
||||
|
||||
$requiredFields = @("categories", "tags", "created", "source", "type")
|
||||
|
||||
if ($wikiFiles) {
|
||||
foreach ($file in $wikiFiles) {
|
||||
$content = Get-Content $file.FullName -Raw -Encoding UTF8
|
||||
$fileResult = @{
|
||||
file = $file.Name
|
||||
hasFrontmatter = $false
|
||||
requiredFieldsComplete = 0
|
||||
requiredFieldsTotal = $requiredFields.Count
|
||||
hasCategories = $false
|
||||
hasTags = $false
|
||||
hasCreated = $false
|
||||
hasSource = $false
|
||||
hasType = $false
|
||||
booleanQuotes = $true
|
||||
yamlValid = $true
|
||||
}
|
||||
|
||||
# 检查是否有 YAML frontmatter
|
||||
if ($content -match "^---\n(.*?)\n---") {
|
||||
$fileResult.hasFrontmatter = $true
|
||||
$frontmatter = $matches[1]
|
||||
|
||||
# 检查必需字段
|
||||
foreach ($field in $requiredFields) {
|
||||
if ($frontmatter -match "$field:") {
|
||||
$fileResult."has$($field -replace '\s', '')" = $true
|
||||
$fileResult.requiredFieldsComplete++
|
||||
}
|
||||
}
|
||||
|
||||
# 检查布尔值是否用引号包裹
|
||||
if ($content -match ":\s*(true|false)\s*$") {
|
||||
if (!($content -match ':\s*"(true|false)"')) {
|
||||
$fileResult.booleanQuotes = $false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$results += $fileResult
|
||||
}
|
||||
}
|
||||
|
||||
# 计算总体得分
|
||||
$totalFiles = $results.Count
|
||||
if ($totalFiles -gt 0) {
|
||||
$avgFieldCompleteness = ($results | ForEach-Object { $_.requiredFieldsComplete / $_.requiredFieldsTotal } | Measure-Object -Average).Average
|
||||
$booleanComplianceRate = ($results | Where-Object { $_.booleanQuotes } | Measure-Object).Count / $totalFiles
|
||||
} else {
|
||||
$avgFieldCompleteness = 0
|
||||
$booleanComplianceRate = 1.0
|
||||
}
|
||||
|
||||
@{
|
||||
totalFiles = $totalFiles
|
||||
avgFieldCompleteness = $avgFieldCompleteness
|
||||
booleanComplianceRate = $booleanComplianceRate
|
||||
results = $results
|
||||
}
|
||||
}
|
||||
|
||||
# 辅助函数:评估 Wikilink 质量
|
||||
function Evaluate-Wikilinks {
|
||||
param (
|
||||
[string]$wikiDir,
|
||||
[hashtable]$generatedTerms
|
||||
)
|
||||
|
||||
$wikiFiles = Get-ChildItem -Path $wikiDir -Recurse -Filter "*.md" -ErrorAction SilentlyContinue
|
||||
$totalLinks = 0
|
||||
$validLinks = 0
|
||||
$invalidLinks = @()
|
||||
|
||||
if ($wikiFiles) {
|
||||
foreach ($file in $wikiFiles) {
|
||||
$content = Get-Content $file.FullName -Raw -Encoding UTF8
|
||||
|
||||
# 查找所有 wikilinks
|
||||
$links = [regex]::Matches($content, "\[\[([^\]]+)\]\]")
|
||||
|
||||
foreach ($link in $links) {
|
||||
$totalLinks++
|
||||
$target = $link.Groups[1].Value
|
||||
|
||||
# 检查目标是否存在
|
||||
if ($generatedTerms.ContainsKey($target)) {
|
||||
$validLinks++
|
||||
} else {
|
||||
$invalidLinks += @{
|
||||
source = $file.Name
|
||||
target = $target
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@{
|
||||
totalLinks = $totalLinks
|
||||
validLinks = $validLinks
|
||||
invalidLinks = $invalidLinks
|
||||
linkAccuracyRate = if ($totalLinks -gt 0) { $validLinks / $totalLinks } else { 1.0 }
|
||||
}
|
||||
}
|
||||
|
||||
# 构建金标准术语表
|
||||
$goldTerms = @{}
|
||||
$goldStandard.concepts | ForEach-Object { $goldTerms[$_.term] = $_ }
|
||||
$goldStandard.methods | ForEach-Object { $goldTerms[$_.term] = $_ }
|
||||
$goldStandard.entities | ForEach-Object { $goldTerms[$_.term] = $_ }
|
||||
|
||||
# 评估 A 组
|
||||
Write-Host "`n评估 A 组..." -ForegroundColor Green
|
||||
$groupATermCoverage = Calculate-TermCoverage -wikiDir $groupADir -goldTerms $goldTerms
|
||||
$groupAFrontmatter = Evaluate-Frontmatter -wikiDir $groupADir
|
||||
$groupAWikilinks = Evaluate-Wikilinks -wikiDir $groupADir -generatedTerms $groupATermCoverage.generatedTerms
|
||||
|
||||
# 评估 B 组
|
||||
Write-Host "`n评估 B 组..." -ForegroundColor Green
|
||||
$groupBTermCoverage = Calculate-TermCoverage -wikiDir $groupBDir -goldTerms $goldTerms
|
||||
$groupBFrontmatter = Evaluate-Frontmatter -wikiDir $groupBDir
|
||||
$groupBWikilinks = Evaluate-Wikilinks -wikiDir $groupBDir -generatedTerms $groupBTermCoverage.generatedTerms
|
||||
|
||||
# 加载元数据
|
||||
$groupAMetadata = $null
|
||||
$groupBMetadata = $null
|
||||
|
||||
$metadataFileA = "tools/experiments/wiki-generation-compare/output/group-a/metadata.json"
|
||||
$metadataFileB = "tools/experiments/wiki-generation-compare/output/group-b/metadata.json"
|
||||
|
||||
if (Test-Path $metadataFileA) {
|
||||
$groupAMetadata = Get-Content $metadataFileA -Raw | ConvertFrom-Json
|
||||
}
|
||||
|
||||
if (Test-Path $metadataFileB) {
|
||||
$groupBMetadata = Get-Content $metadataFileB -Raw | ConvertFrom-Json
|
||||
}
|
||||
|
||||
# 计算得分
|
||||
function Calculate-Score {
|
||||
param (
|
||||
[hashtable]$termCoverage,
|
||||
[hashtable]$frontmatter,
|
||||
[hashtable]$wikilinks,
|
||||
[hashtable]$metadata,
|
||||
[hashtable]$weights
|
||||
)
|
||||
|
||||
# 内容完整性(40%)
|
||||
$coverageScore = $termCoverage.coverageRate
|
||||
$definitionQuality = if ($termCoverage.generatedTerms.Count -gt 0) {
|
||||
($termCoverage.generatedTerms.Values | Where-Object { $_.hasDefinition } | Measure-Object).Count / $termCoverage.generatedTerms.Count
|
||||
} else { 0 }
|
||||
$sourceLinkQuality = if ($termCoverage.generatedTerms.Count -gt 0) {
|
||||
($termCoverage.generatedTerms.Values | Where-Object { $_.hasSourceLink } | Measure-Object).Count / $termCoverage.generatedTerms.Count
|
||||
} else { 0 }
|
||||
$lineNumberQuality = if ($termCoverage.generatedTerms.Count -gt 0) {
|
||||
($termCoverage.generatedTerms.Values | Where-Object { $_.hasLineNumber } | Measure-Object).Count / $termCoverage.generatedTerms.Count
|
||||
} else { 0 }
|
||||
$contentCompleteness = ($coverageScore * 0.4 + $definitionQuality * 0.3 + $sourceLinkQuality * 0.2 + $lineNumberQuality * 0.1)
|
||||
|
||||
# 技术规范性(30%)
|
||||
$fieldCompleteness = $frontmatter.avgFieldCompleteness
|
||||
$booleanCompliance = $frontmatter.booleanComplianceRate
|
||||
$linkQuality = $wikilinks.linkAccuracyRate
|
||||
$technicalCompliance = ($fieldCompleteness * 0.4 + $booleanCompliance * 0.3 + $linkQuality * 0.3)
|
||||
|
||||
# 可维护性(20%)
|
||||
# 简化处理:如果有元数据就给分
|
||||
$maintainability = if ($metadata) { 0.8 } else { 0.5 }
|
||||
|
||||
# 效率成本(10%)
|
||||
# 基于时间成本,越快越好
|
||||
$timeCost = if ($metadata) { $metadata.durationMinutes } else { 0 }
|
||||
$efficiency = if ($timeCost -eq 0) { 0.5 } elseif ($timeCost -lt 10) { 1.0 } elseif ($timeCost -lt 20) { 0.8 } else { 0.6 }
|
||||
|
||||
# 总分
|
||||
$totalScore = $contentCompleteness * $weights.contentCompleteness + `
|
||||
$technicalCompliance * $weights.technicalCompliance + `
|
||||
$maintainability * $weights.maintainability + `
|
||||
$efficiency * $weights.efficiency
|
||||
|
||||
@{
|
||||
contentCompleteness = $contentCompleteness
|
||||
technicalCompliance = $technicalCompliance
|
||||
maintainability = $maintainability
|
||||
efficiency = $efficiency
|
||||
totalScore = $totalScore
|
||||
}
|
||||
}
|
||||
|
||||
$groupAScores = Calculate-Score -termCoverage $groupATermCoverage -frontmatter $groupAFrontmatter -wikilinks $groupAWikilinks -metadata $groupAMetadata -weights $weights
|
||||
$groupBScores = Calculate-Score -termCoverage $groupBTermCoverage -frontmatter $groupBFrontmatter -wikilinks $groupBWikilinks -metadata $groupBMetadata -weights $weights
|
||||
|
||||
# 生成报告
|
||||
$aStartTime = if ($groupAMetadata) { $groupAMetadata.startTime } else { "N/A" }
|
||||
$aEndTime = if ($groupAMetadata) { $groupAMetadata.endTime } else { "N/A" }
|
||||
$aDuration = if ($groupAMetadata) { $groupAMetadata.durationMinutes } else { 0 }
|
||||
$aPages = if ($groupAMetadata) { $groupAMetadata.pagesGenerated } else { $groupATermCoverage.generatedTerms.Count }
|
||||
|
||||
$bStartTime = if ($groupBMetadata) { $groupBMetadata.startTime } else { "N/A" }
|
||||
$bEndTime = if ($groupBMetadata) { $groupBMetadata.endTime } else { "N/A" }
|
||||
$bDuration = if ($groupBMetadata) { $groupBMetadata.durationMinutes } else { 0 }
|
||||
$bPages = if ($groupBMetadata) { $groupBMetadata.pagesGenerated } else { $groupBTermCoverage.generatedTerms.Count }
|
||||
|
||||
$aMissedTerms = if ($groupATermCoverage.missedTerms) { $groupATermCoverage.missedTerms -join ', ' } else { "无" }
|
||||
$bMissedTerms = if ($groupBTermCoverage.missedTerms) { $groupBTermCoverage.missedTerms -join ', ' } else { "无" }
|
||||
|
||||
$aInvalidLinks = if ($groupAWikilinks.invalidLinks) { $groupAWikilinks.invalidLinks | ForEach-Object { "$($_.source) → $($_.target)" } -join '; ' } else { "无" }
|
||||
$bInvalidLinks = if ($groupBWikilinks.invalidLinks) { $groupBWikilinks.invalidLinks | ForEach-Object { "$($_.source) → $($_.target)" } -join '; ' } else { "无" }
|
||||
|
||||
$report = @"
|
||||
# Wiki 生成质量对比实验报告
|
||||
|
||||
## 实验概览
|
||||
|
||||
- **测试文件**: raw/呼吸之间_李谨伯/第一编 从身体入手.md
|
||||
- **金标准术语数**: $($goldTerms.Count)
|
||||
- **A 组模式**: Two-Step(分析 + 生成)
|
||||
- **B 组模式**: Single-Step(直接生成)
|
||||
- **权重配置**: 40% 内容完整性 + 30% 技术规范性 + 20% 可维护性 + 10% 效率成本
|
||||
|
||||
## 执行时间
|
||||
|
||||
| 组别 | 模式 | 开始时间 | 结束时间 | 耗时(分钟) | 生成页面数 |
|
||||
|------|------|----------|----------|-------------|-----------|
|
||||
| A 组 | Two-Step | $aStartTime | $aEndTime | $aDuration | $aPages |
|
||||
| B 组 | Single-Step | $bStartTime | $bEndTime | $bDuration | $bPages |
|
||||
|
||||
## 详细得分
|
||||
|
||||
### A 组(Two-Step)
|
||||
|
||||
| 维度 | 得分 | 权重 | 加权得分 |
|
||||
|------|------|------|---------|
|
||||
| 内容完整性 | $([math]::Round($groupAScores.contentCompleteness * 100, 1))% | 40% | $([math]::Round($groupAScores.contentCompleteness * 0.4 * 100, 1)) |
|
||||
| 技术规范性 | $([math]::Round($groupAScores.technicalCompliance * 100, 1))% | 30% | $([math]::Round($groupAScores.technicalCompliance * 0.3 * 100, 1)) |
|
||||
| 可维护性 | $([math]::Round($groupAScores.maintainability * 100, 1))% | 20% | $([math]::Round($groupAScores.maintainability * 0.2 * 100, 1)) |
|
||||
| 效率成本 | $([math]::Round($groupAScores.efficiency * 100, 1))% | 10% | $([math]::Round($groupAScores.efficiency * 0.1 * 100, 1)) |
|
||||
| **总分** | - | **100%** | **$([math]::Round($groupAScores.totalScore * 100, 1))** |
|
||||
|
||||
### B 组(Single-Step)
|
||||
|
||||
| 维度 | 得分 | 权重 | 加权得分 |
|
||||
|------|------|------|---------|
|
||||
| 内容完整性 | $([math]::Round($groupBScores.contentCompleteness * 100, 1))% | 40% | $([math]::Round($groupBScores.contentCompleteness * 0.4 * 100, 1)) |
|
||||
| 技术规范性 | $([math]::Round($groupBScores.technicalCompliance * 100, 1))% | 30% | $([math]::Round($groupBScores.technicalCompliance * 0.3 * 100, 1)) |
|
||||
| 可维护性 | $([math]::Round($groupBScores.maintainability * 100, 1))% | 20% | $([math]::Round($groupBScores.maintainability * 0.2 * 100, 1)) |
|
||||
| 效率成本 | $([math]::Round($groupBScores.efficiency * 100, 1))% | 10% | $([math]::Round($groupBScores.efficiency * 0.1 * 100, 1)) |
|
||||
| **总分** | - | **100%** | **$([math]::Round($groupBScores.totalScore * 100, 1))** |
|
||||
|
||||
## 详细对比
|
||||
|
||||
### 1. 术语覆盖度
|
||||
|
||||
| 组别 | 金标准术语数 | 覆盖术语数 | 覆盖率 | 未覆盖术语 |
|
||||
|------|-------------|-----------|--------|-----------|
|
||||
| A 组 | $($groupATermCoverage.totalGoldTerms) | $($groupATermCoverage.coveredTerms) | $([math]::Round($groupATermCoverage.coverageRate * 100, 1))% | $aMissedTerms |
|
||||
| B 组 | $($groupBTermCoverage.totalGoldTerms) | $($groupBTermCoverage.coveredTerms) | $([math]::Round($groupBTermCoverage.coverageRate * 100, 1))% | $bMissedTerms |
|
||||
|
||||
**A 组未覆盖术语**: $aMissedTerms
|
||||
**B 组未覆盖术语**: $bMissedTerms
|
||||
|
||||
### 2. Frontmatter 规范性
|
||||
|
||||
| 组别 | 总文件数 | 平均字段完整度 | 布尔值合规率 |
|
||||
|------|---------|---------------|-------------|
|
||||
| A 组 | $($groupAFrontmatter.totalFiles) | $([math]::Round($groupAFrontmatter.avgFieldCompleteness * 100, 1))% | $([math]::Round($groupAFrontmatter.booleanComplianceRate * 100, 1))% |
|
||||
| B 组 | $($groupBFrontmatter.totalFiles) | $([math]::Round($groupBFrontmatter.avgFieldCompleteness * 100, 1))% | $([math]::Round($groupBFrontmatter.booleanComplianceRate * 100, 1))% |
|
||||
|
||||
### 3. Wikilink 质量
|
||||
|
||||
| 组别 | 总链接数 | 有效链接数 | 无效链接数 | 链接准确率 |
|
||||
|------|---------|-----------|-----------|-----------|
|
||||
| A 组 | $($groupAWikilinks.totalLinks) | $($groupAWikilinks.validLinks) | $($groupAWikilinks.invalidLinks.Count) | $([math]::Round($groupAWikilinks.linkAccuracyRate * 100, 1))% |
|
||||
| B 组 | $($groupBWikilinks.totalLinks) | $($groupBWikilinks.validLinks) | $($groupBWikilinks.invalidLinks.Count) | $([math]::Round($groupBWikilinks.linkAccuracyRate * 100, 1))% |
|
||||
|
||||
**A 组无效链接**: $aInvalidLinks
|
||||
**B 组无效链接**: $bInvalidLinks
|
||||
|
||||
### 4. 内容质量细节
|
||||
|
||||
| 组别 | 有定义 | 有来源链接 | 有行号标注 |
|
||||
|------|--------|-----------|-----------|
|
||||
| A 组 | $(($groupATermCoverage.generatedTerms.Values | Where-Object { $_.hasDefinition } | Measure-Object).Count) / $($groupATermCoverage.generatedTerms.Count) | $(($groupATermCoverage.generatedTerms.Values | Where-Object { $_.hasSourceLink } | Measure-Object).Count) / $($groupATermCoverage.generatedTerms.Count) | $(($groupATermCoverage.generatedTerms.Values | Where-Object { $_.hasLineNumber } | Measure-Object).Count) / $($groupATermCoverage.generatedTerms.Count) |
|
||||
| B 组 | $(($groupBTermCoverage.generatedTerms.Values | Where-Object { $_.hasDefinition } | Measure-Object).Count) / $($groupBTermCoverage.generatedTerms.Count) | $(($groupBTermCoverage.generatedTerms.Values | Where-Object { $_.hasSourceLink } | Measure-Object).Count) / $($groupBTermCoverage.generatedTerms.Count) | $(($groupBTermCoverage.generatedTerms.Values | Where-Object { $_.hasLineNumber } | Measure-Object).Count) / $($groupBTermCoverage.generatedTerms.Count) |
|
||||
|
||||
## 结论
|
||||
|
||||
### 综合评价
|
||||
|
||||
$(
|
||||
if ($groupAScores.totalScore -gt $groupBScores.totalScore) {
|
||||
"**A 组(Two-Step 模式)总分更高,推荐使用。**"
|
||||
} elseif ($groupBScores.totalScore -gt $groupAScores.totalScore) {
|
||||
"**B 组(Single-Step 模式)总分更高,推荐使用。**"
|
||||
} else {
|
||||
"**A 组和 B 组得分相当,可根据其他因素选择。**"
|
||||
}
|
||||
)
|
||||
|
||||
### 各维度对比
|
||||
|
||||
$(
|
||||
if ($groupAScores.contentCompleteness -gt $groupBScores.contentCompleteness) {
|
||||
"- **内容完整性**:A 组优于 B 组($([math]::Round($groupAScores.contentCompleteness * 100, 1))% vs $([math]::Round($groupBScores.contentCompleteness * 100, 1))%)"
|
||||
} else {
|
||||
"- **内容完整性**:B 组优于 A 组($([math]::Round($groupBScores.contentCompleteness * 100, 1))% vs $([math]::Round($groupAScores.contentCompleteness * 100, 1))%)"
|
||||
}
|
||||
)
|
||||
|
||||
$(
|
||||
if ($groupAScores.technicalCompliance -gt $groupBScores.technicalCompliance) {
|
||||
"- **技术规范性**:A 组优于 B 组($([math]::Round($groupAScores.technicalCompliance * 100, 1))% vs $([math]::Round($groupBScores.technicalCompliance * 100, 1))%)"
|
||||
} else {
|
||||
"- **技术规范性**:B 组优于 A 组($([math]::Round($groupBScores.technicalCompliance * 100, 1))% vs $([math]::Round($groupAScores.technicalCompliance * 100, 1))%)"
|
||||
}
|
||||
)
|
||||
|
||||
$(
|
||||
if ($groupAScores.efficiency -gt $groupBScores.efficiency) {
|
||||
"- **效率成本**:A 组优于 B 组"
|
||||
} else {
|
||||
"- **效率成本**:B 组优于 A 组"
|
||||
}
|
||||
)
|
||||
|
||||
### 建议与改进方向
|
||||
|
||||
1. **术语覆盖度改进**:
|
||||
- A 组未覆盖的术语:$aMissedTerms
|
||||
- B 组未覆盖的术语:$bMissedTerms
|
||||
|
||||
2. **Frontmatter 规范性改进**:
|
||||
- 确保所有必需字段完整
|
||||
- 布尔值必须用引号包裹
|
||||
|
||||
3. **Wikilink 质量改进**:
|
||||
- 减少无效链接
|
||||
- 提高同批次术语间的链接密度
|
||||
|
||||
## 附录:生成页面列表
|
||||
|
||||
### A 组生成页面
|
||||
$($groupATermCoverage.generatedTerms.Keys -join ", ")
|
||||
|
||||
### B 组生成页面
|
||||
$($groupBTermCoverage.generatedTerms.Keys -join ", ")
|
||||
|
||||
---
|
||||
|
||||
**报告生成时间**: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
|
||||
"@
|
||||
|
||||
# 保存报告
|
||||
$report | Out-File $reportFile -Encoding UTF8
|
||||
|
||||
Write-Host "`n=== 评估完成 ===" -ForegroundColor Cyan
|
||||
Write-Host "报告已保存到 $reportFile" -ForegroundColor Green
|
||||
Write-Host "`n总分对比:" -ForegroundColor Yellow
|
||||
Write-Host "A 组(Two-Step): $([math]::Round($groupAScores.totalScore * 100, 1)) 分" -ForegroundColor Cyan
|
||||
Write-Host "B 组(Single-Step): $([math]::Round($groupBScores.totalScore * 100, 1)) 分" -ForegroundColor Cyan
|
||||
|
||||
# 显示报告摘要
|
||||
Write-Host "`n" -NoNewline
|
||||
Get-Content $reportFile -Encoding UTF8 | Select-Object -First 50
|
||||
@@ -0,0 +1,394 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
评估脚本
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
import re
|
||||
|
||||
print('=== 开始评估 ===')
|
||||
|
||||
# 配置 - 从当前工作目录计算
|
||||
base_dir = os.getcwd()
|
||||
experiment_dir = os.path.join(base_dir, "tools", "experiments", "wiki-generation-compare")
|
||||
output_dir = os.path.join(experiment_dir, "output")
|
||||
|
||||
gold_standard_file = os.path.join(experiment_dir, "gold-standard.json")
|
||||
group_a_dir = os.path.join(output_dir, "group-a", "wiki")
|
||||
group_b_dir = os.path.join(output_dir, "group-b", "wiki")
|
||||
|
||||
# 加载金标准
|
||||
with open(gold_standard_file, 'r', encoding='utf-8') as f:
|
||||
gold_standard = json.load(f)
|
||||
|
||||
# 构建金标准术语表
|
||||
gold_terms = {}
|
||||
for item in gold_standard.get('concepts', []):
|
||||
gold_terms[item['term']] = item
|
||||
for item in gold_standard.get('methods', []):
|
||||
gold_terms[item['term']] = item
|
||||
for item in gold_standard.get('entities', []):
|
||||
gold_terms[item['term']] = item
|
||||
|
||||
# 辅助函数:计算术语覆盖度
|
||||
def calculate_term_coverage(wiki_dir):
|
||||
generated_terms = {}
|
||||
|
||||
if not os.path.exists(wiki_dir):
|
||||
return {
|
||||
'totalGoldTerms': len(gold_terms),
|
||||
'coveredTerms': 0,
|
||||
'coverageRate': 0,
|
||||
'generatedTerms': {},
|
||||
'missedTerms': list(gold_terms.keys())
|
||||
}
|
||||
|
||||
for root, dirs, files in os.walk(wiki_dir):
|
||||
for file in files:
|
||||
if file.endswith('.md'):
|
||||
term_name = file.replace('.md', '')
|
||||
file_path = os.path.join(root, file)
|
||||
generated_terms[term_name] = {
|
||||
'file': file_path,
|
||||
'hasDefinition': False,
|
||||
'hasSourceLink': False,
|
||||
'hasLineNumber': False
|
||||
}
|
||||
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
if '**一句话定义**' in content:
|
||||
generated_terms[term_name]['hasDefinition'] = True
|
||||
|
||||
if '[[raw/呼吸之间_李谨伯' in content:
|
||||
generated_terms[term_name]['hasSourceLink'] = True
|
||||
|
||||
if '[raw:第一编 从身体入手.md:' in content:
|
||||
generated_terms[term_name]['hasLineNumber'] = True
|
||||
|
||||
covered_count = sum(1 for term in gold_terms.keys() if term in generated_terms)
|
||||
coverage_rate = covered_count / len(gold_terms) if gold_terms else 0
|
||||
|
||||
return {
|
||||
'totalGoldTerms': len(gold_terms),
|
||||
'coveredTerms': covered_count,
|
||||
'coverageRate': coverage_rate,
|
||||
'generatedTerms': generated_terms,
|
||||
'missedTerms': [term for term in gold_terms.keys() if term not in generated_terms]
|
||||
}
|
||||
|
||||
# 辅助函数:评估 Frontmatter 规范性
|
||||
def evaluate_frontmatter(wiki_dir):
|
||||
required_fields = ['categories', 'tags', 'created', 'source', 'type']
|
||||
results = []
|
||||
|
||||
if not os.path.exists(wiki_dir):
|
||||
return {
|
||||
'totalFiles': 0,
|
||||
'avgFieldCompleteness': 0,
|
||||
'results': []
|
||||
}
|
||||
|
||||
for root, dirs, files in os.walk(wiki_dir):
|
||||
for file in files:
|
||||
if file.endswith('.md'):
|
||||
file_path = os.path.join(root, file)
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
file_result = {
|
||||
'file': file,
|
||||
'hasFrontmatter': False,
|
||||
'requiredFieldsComplete': 0,
|
||||
'requiredFieldsTotal': len(required_fields),
|
||||
'hasCategories': False,
|
||||
'hasTags': False,
|
||||
'hasCreated': False,
|
||||
'hasSource': False,
|
||||
'hasType': False,
|
||||
'booleanQuotes': True
|
||||
}
|
||||
|
||||
if content.startswith('---'):
|
||||
file_result['hasFrontmatter'] = True
|
||||
# 简化的 frontmatter 解析
|
||||
for field in required_fields:
|
||||
if f'{field}:' in content:
|
||||
file_result['has' + field.capitalize()] = True
|
||||
file_result['requiredFieldsComplete'] += 1
|
||||
|
||||
results.append(file_result)
|
||||
|
||||
total_files = len(results)
|
||||
if total_files > 0:
|
||||
avg_field_completeness = sum(r['requiredFieldsComplete'] / r['requiredFieldsTotal'] for r in results) / total_files
|
||||
else:
|
||||
avg_field_completeness = 0
|
||||
|
||||
return {
|
||||
'totalFiles': total_files,
|
||||
'avgFieldCompleteness': avg_field_completeness,
|
||||
'results': results
|
||||
}
|
||||
|
||||
# 辅助函数:评估 Wikilink 质量
|
||||
def evaluate_wikilinks(wiki_dir, generated_terms):
|
||||
total_links = 0
|
||||
valid_links = 0
|
||||
invalid_links = []
|
||||
|
||||
if not os.path.exists(wiki_dir):
|
||||
return {
|
||||
'totalLinks': 0,
|
||||
'validLinks': 0,
|
||||
'invalidLinks': [],
|
||||
'linkAccuracyRate': 1.0
|
||||
}
|
||||
|
||||
for root, dirs, files in os.walk(wiki_dir):
|
||||
for file in files:
|
||||
if file.endswith('.md'):
|
||||
file_path = os.path.join(root, file)
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
links = re.findall(r'\[\[([^\]]+)\]\]', content)
|
||||
|
||||
for link in links:
|
||||
total_links += 1
|
||||
if link in generated_terms:
|
||||
valid_links += 1
|
||||
else:
|
||||
invalid_links.append({'source': file, 'target': link})
|
||||
|
||||
link_accuracy_rate = valid_links / total_links if total_links > 0 else 1.0
|
||||
|
||||
return {
|
||||
'totalLinks': total_links,
|
||||
'validLinks': valid_links,
|
||||
'invalidLinks': invalid_links,
|
||||
'linkAccuracyRate': link_accuracy_rate
|
||||
}
|
||||
|
||||
# 评估 A 组
|
||||
print('评估 A 组...')
|
||||
group_a_coverage = calculate_term_coverage(group_a_dir)
|
||||
group_a_frontmatter = evaluate_frontmatter(group_a_dir)
|
||||
group_a_wikilinks = evaluate_wikilinks(group_a_dir, group_a_coverage['generatedTerms'])
|
||||
|
||||
# 评估 B 组
|
||||
print('评估 B 组...')
|
||||
group_b_coverage = calculate_term_coverage(group_b_dir)
|
||||
group_b_frontmatter = evaluate_frontmatter(group_b_dir)
|
||||
group_b_wikilinks = evaluate_wikilinks(group_b_dir, group_b_coverage['generatedTerms'])
|
||||
|
||||
# 加载元数据
|
||||
group_a_metadata = None
|
||||
group_b_metadata = None
|
||||
|
||||
try:
|
||||
with open(os.path.join(output_dir, "group-a", "metadata.json"), 'r', encoding='utf-8') as f:
|
||||
group_a_metadata = json.load(f)
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
with open(os.path.join(output_dir, "group-b", "metadata.json"), 'r', encoding='utf-8') as f:
|
||||
group_b_metadata = json.load(f)
|
||||
except:
|
||||
pass
|
||||
|
||||
# 计算得分
|
||||
def calculate_score(coverage, frontmatter, wikilinks, metadata):
|
||||
# 内容完整性(40%)
|
||||
coverage_score = coverage['coverageRate']
|
||||
|
||||
if coverage['generatedTerms']:
|
||||
definition_quality = sum(1 for t in coverage['generatedTerms'].values() if t['hasDefinition']) / len(coverage['generatedTerms'])
|
||||
source_link_quality = sum(1 for t in coverage['generatedTerms'].values() if t['hasSourceLink']) / len(coverage['generatedTerms'])
|
||||
line_number_quality = sum(1 for t in coverage['generatedTerms'].values() if t['hasLineNumber']) / len(coverage['generatedTerms'])
|
||||
else:
|
||||
definition_quality = 0
|
||||
source_link_quality = 0
|
||||
line_number_quality = 0
|
||||
|
||||
content_completeness = coverage_score * 0.4 + definition_quality * 0.3 + source_link_quality * 0.2 + line_number_quality * 0.1
|
||||
|
||||
# 技术规范性(30%)
|
||||
field_completeness = frontmatter['avgFieldCompleteness']
|
||||
link_quality = wikilinks['linkAccuracyRate']
|
||||
technical_compliance = field_completeness * 0.6 + link_quality * 0.4
|
||||
|
||||
# 可维护性(20%)
|
||||
maintainability = 0.8 if metadata else 0.5
|
||||
|
||||
# 效率成本(10%)
|
||||
time_cost = metadata['durationMinutes'] if metadata else 0
|
||||
efficiency = 1.0 if time_cost == 0 else (1.0 if time_cost < 10 else 0.8 if time_cost < 20 else 0.6)
|
||||
|
||||
total_score = content_completeness * 0.4 + technical_compliance * 0.3 + maintainability * 0.2 + efficiency * 0.1
|
||||
|
||||
return {
|
||||
'contentCompleteness': content_completeness,
|
||||
'technicalCompliance': technical_compliance,
|
||||
'maintainability': maintainability,
|
||||
'efficiency': efficiency,
|
||||
'totalScore': total_score
|
||||
}
|
||||
|
||||
group_a_scores = calculate_score(group_a_coverage, group_a_frontmatter, group_a_wikilinks, group_a_metadata)
|
||||
group_b_scores = calculate_score(group_b_coverage, group_b_frontmatter, group_b_wikilinks, group_b_metadata)
|
||||
|
||||
# 生成报告
|
||||
a_start_time = group_a_metadata.get('startTime') if group_a_metadata else 'N/A'
|
||||
a_end_time = group_a_metadata.get('endTime') if group_a_metadata else 'N/A'
|
||||
a_duration = group_a_metadata.get('durationMinutes', 0) if group_a_metadata else 0
|
||||
a_pages = group_a_metadata.get('pagesGenerated', 0) if group_a_metadata else 0
|
||||
|
||||
b_start_time = group_b_metadata.get('startTime') if group_b_metadata else 'N/A'
|
||||
b_end_time = group_b_metadata.get('endTime') if group_b_metadata else 'N/A'
|
||||
b_duration = group_b_metadata.get('durationMinutes', 0) if group_b_metadata else 0
|
||||
b_pages = group_b_metadata.get('pagesGenerated', 0) if group_b_metadata else 0
|
||||
|
||||
report = f"""# Wiki 生成质量对比实验报告
|
||||
|
||||
## 实验概览
|
||||
|
||||
- **测试文件**: raw/呼吸之间_李谨伯/第一编 从身体入手.md
|
||||
- **金标准术语数**: {len(gold_terms)}
|
||||
- **A 组模式**: Two-Step(分析 + 生成)
|
||||
- **B 组模式**: Single-Step(直接生成)
|
||||
- **权重配置**: 40% 内容完整性 + 30% 技术规范性 + 20% 可维护性 + 10% 效率成本
|
||||
|
||||
## 执行时间
|
||||
|
||||
| 组别 | 模式 | 开始时间 | 结束时间 | 耗时(分钟) | 生成页面数 |
|
||||
|------|------|----------|----------|-------------|-----------|
|
||||
| A 组 | Two-Step | {a_start_time} | {a_end_time} | {a_duration} | {a_pages} |
|
||||
| B 组 | Single-Step | {b_start_time} | {b_end_time} | {b_duration} | {b_pages} |
|
||||
|
||||
## 详细得分
|
||||
|
||||
### A 组(Two-Step)
|
||||
|
||||
| 维度 | 得分 | 权重 | 加权得分 |
|
||||
|------|------|------|---------|
|
||||
| 内容完整性 | {round(group_a_scores['contentCompleteness'] * 100, 1)}% | 40% | {round(group_a_scores['contentCompleteness'] * 0.4 * 100, 1)} |
|
||||
| 技术规范性 | {round(group_a_scores['technicalCompliance'] * 100, 1)}% | 30% | {round(group_a_scores['technicalCompliance'] * 0.3 * 100, 1)} |
|
||||
| 可维护性 | {round(group_a_scores['maintainability'] * 100, 1)}% | 20% | {round(group_a_scores['maintainability'] * 0.2 * 100, 1)} |
|
||||
| 效率成本 | {round(group_a_scores['efficiency'] * 100, 1)}% | 10% | {round(group_a_scores['efficiency'] * 0.1 * 100, 1)} |
|
||||
| **总分** | - | **100%** | **{round(group_a_scores['totalScore'] * 100, 1)}** |
|
||||
|
||||
### B 组(Single-Step)
|
||||
|
||||
| 维度 | 得分 | 权重 | 加权得分 |
|
||||
|------|------|------|---------|
|
||||
| 内容完整性 | {round(group_b_scores['contentCompleteness'] * 100, 1)}% | 40% | {round(group_b_scores['contentCompleteness'] * 0.4 * 100, 1)} |
|
||||
| 技术规范性 | {round(group_b_scores['technicalCompliance'] * 100, 1)}% | 30% | {round(group_b_scores['technicalCompliance'] * 0.3 * 100, 1)} |
|
||||
| 可维护性 | {round(group_b_scores['maintainability'] * 100, 1)}% | 20% | {round(group_b_scores['maintainability'] * 0.2 * 100, 1)} |
|
||||
| 效率成本 | {round(group_b_scores['efficiency'] * 100, 1)}% | 10% | {round(group_b_scores['efficiency'] * 0.1 * 100, 1)} |
|
||||
| **总分** | - | **100%** | **{round(group_b_scores['totalScore'] * 100, 1)}** |
|
||||
|
||||
## 详细对比
|
||||
|
||||
### 1. 术语覆盖度
|
||||
|
||||
| 组别 | 金标准术语数 | 覆盖术语数 | 覆盖率 | 未覆盖术语 |
|
||||
|------|-------------|-----------|--------|-----------|
|
||||
| A 组 | {group_a_coverage['totalGoldTerms']} | {group_a_coverage['coveredTerms']} | {round(group_a_coverage['coverageRate'] * 100, 1)}% | {len(group_a_coverage['missedTerms'])} 个 |
|
||||
| B 组 | {group_b_coverage['totalGoldTerms']} | {group_b_coverage['coveredTerms']} | {round(group_b_coverage['coverageRate'] * 100, 1)}% | {len(group_b_coverage['missedTerms'])} 个 |
|
||||
|
||||
**A 组未覆盖术语**: {', '.join(group_a_coverage['missedTerms'][:5])}{'...' if len(group_a_coverage['missedTerms']) > 5 else ''}
|
||||
**B 组未覆盖术语**: {', '.join(group_b_coverage['missedTerms'][:5])}{'...' if len(group_b_coverage['missedTerms']) > 5 else ''}
|
||||
|
||||
### 2. Frontmatter 规范性
|
||||
|
||||
| 组别 | 总文件数 | 平均字段完整度 |
|
||||
|------|---------|---------------|
|
||||
| A 组 | {group_a_frontmatter['totalFiles']} | {round(group_a_frontmatter['avgFieldCompleteness'] * 100, 1)}% |
|
||||
| B 组 | {group_b_frontmatter['totalFiles']} | {round(group_b_frontmatter['avgFieldCompleteness'] * 100, 1)}% |
|
||||
|
||||
### 3. Wikilink 质量
|
||||
|
||||
| 组别 | 总链接数 | 有效链接数 | 无效链接数 | 链接准确率 |
|
||||
|------|---------|-----------|-----------|-----------|
|
||||
| A 组 | {group_a_wikilinks['totalLinks']} | {group_a_wikilinks['validLinks']} | {len(group_a_wikilinks['invalidLinks'])} | {round(group_a_wikilinks['linkAccuracyRate'] * 100, 1)}% |
|
||||
| B 组 | {group_b_wikilinks['totalLinks']} | {group_b_wikilinks['validLinks']} | {len(group_b_wikilinks['invalidLinks'])} | {round(group_b_wikilinks['linkAccuracyRate'] * 100, 1)}% |
|
||||
|
||||
### 4. 内容质量细节
|
||||
|
||||
| 组别 | 有定义 | 有来源链接 | 有行号标注 |
|
||||
|------|--------|-----------|-----------|
|
||||
| A 组 | {sum(1 for t in group_a_coverage['generatedTerms'].values() if t['hasDefinition'])}/{len(group_a_coverage['generatedTerms'])} | {sum(1 for t in group_a_coverage['generatedTerms'].values() if t['hasSourceLink'])}/{len(group_a_coverage['generatedTerms'])} | {sum(1 for t in group_a_coverage['generatedTerms'].values() if t['hasLineNumber'])}/{len(group_a_coverage['generatedTerms'])} |
|
||||
| B 组 | {sum(1 for t in group_b_coverage['generatedTerms'].values() if t['hasDefinition'])}/{len(group_b_coverage['generatedTerms'])} | {sum(1 for t in group_b_coverage['generatedTerms'].values() if t['hasSourceLink'])}/{len(group_b_coverage['generatedTerms'])} | {sum(1 for t in group_b_coverage['generatedTerms'].values() if t['hasLineNumber'])}/{len(group_b_coverage['generatedTerms'])} |
|
||||
|
||||
## 结论
|
||||
|
||||
### 综合评价
|
||||
|
||||
"""
|
||||
|
||||
if group_a_scores['totalScore'] > group_b_scores['totalScore']:
|
||||
report += "**A 组(Two-Step 模式)总分更高,推荐使用。**"
|
||||
elif group_b_scores['totalScore'] > group_a_scores['totalScore']:
|
||||
report += "**B 组(Single-Step 模式)总分更高,推荐使用。**"
|
||||
else:
|
||||
report += "**A 组和 B 组得分相当,可根据其他因素选择。**"
|
||||
|
||||
report += f"""
|
||||
|
||||
### 各维度对比
|
||||
|
||||
"""
|
||||
|
||||
if group_a_scores['contentCompleteness'] > group_b_scores['contentCompleteness']:
|
||||
report += f"- **内容完整性**: A 组优于 B 组({round(group_a_scores['contentCompleteness'] * 100, 1)}% vs {round(group_b_scores['contentCompleteness'] * 100, 1)}%)"
|
||||
else:
|
||||
report += f"- **内容完整性**: B 组优于 A 组({round(group_b_scores['contentCompleteness'] * 100, 1)}% vs {round(group_a_scores['contentCompleteness'] * 100, 1)}%)"
|
||||
|
||||
report += "\n"
|
||||
|
||||
if group_a_scores['technicalCompliance'] > group_b_scores['technicalCompliance']:
|
||||
report += f"- **技术规范性**: A 组优于 B 组({round(group_a_scores['technicalCompliance'] * 100, 1)}% vs {round(group_b_scores['technicalCompliance'] * 100, 1)}%)"
|
||||
else:
|
||||
report += f"- **技术规范性**: B 组优于 A 组({round(group_b_scores['technicalCompliance'] * 100, 1)}% vs {round(group_a_scores['technicalCompliance'] * 100, 1)}%)"
|
||||
|
||||
report += "\n"
|
||||
|
||||
if group_a_scores['efficiency'] > group_b_scores['efficiency']:
|
||||
report += f"- **效率成本**: A 组优于 B 组"
|
||||
else:
|
||||
report += f"- **效率成本**: B 组优于 A 组"
|
||||
|
||||
report += f"""
|
||||
|
||||
## 附录:生成页面列表
|
||||
|
||||
### A 组生成页面
|
||||
{', '.join(group_a_coverage['generatedTerms'].keys())}
|
||||
|
||||
### B 组生成页面
|
||||
{', '.join(group_b_coverage['generatedTerms'].keys())}
|
||||
|
||||
---
|
||||
|
||||
**报告生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
||||
"""
|
||||
|
||||
# 保存报告
|
||||
report_file = os.path.join(output_dir, "report.md")
|
||||
with open(report_file, 'w', encoding='utf-8') as f:
|
||||
f.write(report)
|
||||
|
||||
print('=== 评估完成 ===')
|
||||
print(f'报告已保存到 {report_file}')
|
||||
print('')
|
||||
print('总分对比:')
|
||||
a_score_str = str(round(group_a_scores['totalScore'] * 100, 1))
|
||||
b_score_str = str(round(group_b_scores['totalScore'] * 100, 1))
|
||||
print('A 组(Two-Step): ' + a_score_str + ' 分')
|
||||
print('B 组(Single-Step): ' + b_score_str + ' 分')
|
||||
@@ -0,0 +1,383 @@
|
||||
# A 组:Two-Step 模式
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# 配置
|
||||
$sourceFile = "raw/呼吸之间_李谨伯/第一编 从身体入手.md"
|
||||
$outputDir = "tools/experiments/wiki-generation-compare/output/group-a"
|
||||
$analysisPrompt = "tools/experiments/wiki-generation-compare/prompts/twostep-analysis.md"
|
||||
$generationPrompt = "tools/experiments/wiki-generation-compare/prompts/twostep-generation.md"
|
||||
|
||||
# 记录开始时间
|
||||
$startTime = Get-Date
|
||||
$startTimeStr = $startTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
Write-Host "=== A 组实验开始:Two-Step 模式 ===" -ForegroundColor Cyan
|
||||
Write-Host "开始时间: $startTimeStr" -ForegroundColor Yellow
|
||||
|
||||
# Step 1: Analysis
|
||||
Write-Host "`nStep 1: Analysis 阶段..." -ForegroundColor Green
|
||||
$sourceContent = Get-Content $sourceFile -Raw -Encoding UTF8
|
||||
$analysisTemplate = Get-Content $analysisPrompt -Raw -Encoding UTF8
|
||||
$analysisFullPrompt = $analysisTemplate -replace "{SOURCE_CONTENT}", $sourceContent
|
||||
|
||||
Write-Host " 调用 LLM 进行分析..." -ForegroundColor Gray
|
||||
|
||||
# 使用 opencode-mem 调用 LLM(通过 bash)
|
||||
$analysisResult = opencode-mem query "$analysisFullPrompt" --format json --output "$outputDir/analysis.json"
|
||||
|
||||
# 如果 opencode-mem 不可用,使用备用方法
|
||||
if (-not $analysisResult) {
|
||||
Write-Host " opencode-mem 不可用,使用备用方法..." -ForegroundColor Yellow
|
||||
|
||||
# 直接调用 LLM API(这里需要根据您的实际配置调整)
|
||||
# 示例:使用 OpenAI API
|
||||
$apiKey = $env:OPENAI_API_KEY
|
||||
if ($apiKey) {
|
||||
$body = @{
|
||||
model = "gpt-4"
|
||||
messages = @(
|
||||
@{
|
||||
role = "system"
|
||||
content = "你是一位知识库分析专家。"
|
||||
},
|
||||
@{
|
||||
role = "user"
|
||||
content = $analysisFullPrompt
|
||||
}
|
||||
)
|
||||
temperature = 0.3
|
||||
} | ConvertTo-Json -Depth 10
|
||||
|
||||
try {
|
||||
$response = Invoke-RestMethod -Uri "https://api.openai.com/v1/chat/completions" `
|
||||
-Method Post `
|
||||
-Headers @{
|
||||
"Authorization" = "Bearer $apiKey"
|
||||
"Content-Type" = "application/json"
|
||||
} `
|
||||
-Body $body
|
||||
|
||||
$analysisResult = $response.choices[0].message.content
|
||||
|
||||
# 保存分析结果
|
||||
$analysisResult | Out-File "$outputDir/analysis.json" -Encoding UTF8
|
||||
} catch {
|
||||
Write-Host " ✗ OpenAI API 调用失败: $_" -ForegroundColor Red
|
||||
# 生成模拟的分析结果用于测试
|
||||
$analysisResult = '{
|
||||
"source_info": {
|
||||
"filename": "第一编 从身体入手.md",
|
||||
"total_lines": 178,
|
||||
"total_words": 11000,
|
||||
"main_sections": ["我们身体最不正的是什么", "人的精气神从哪里", "关键是开窍", "现代人不开心呢", "问答"]
|
||||
},
|
||||
"concepts": [
|
||||
{
|
||||
"term": "精气神",
|
||||
"definition": "天有三宝日、月、星;地有三宝水、火、风;人也有三宝,精、气、神",
|
||||
"line_number": 44,
|
||||
"occurrences": 8,
|
||||
"summary": "道家修炼的三大基本要素"
|
||||
},
|
||||
{
|
||||
"term": "天人感应",
|
||||
"definition": "星体间产生的引力波互相作用,产生类似星系的漩涡能量场",
|
||||
"line_number": 48,
|
||||
"occurrences": 3,
|
||||
"summary": "天体对人产生影响的机制"
|
||||
},
|
||||
{
|
||||
"term": "玄空造化场",
|
||||
"definition": "星体间产生的引力波互相作用形成的漩涡能量场",
|
||||
"line_number": 48,
|
||||
"occurrences": 3,
|
||||
"summary": "影响初生婴儿的能量场"
|
||||
},
|
||||
{
|
||||
"term": "生气",
|
||||
"definition": "玄空造化场里产生的对生命界影响很大的能量",
|
||||
"line_number": 54,
|
||||
"occurrences": 6,
|
||||
"summary": "补充元气的关键能量"
|
||||
},
|
||||
{
|
||||
"term": "元气",
|
||||
"definition": "生气主要补充的能量,真元之气",
|
||||
"line_number": 54,
|
||||
"occurrences": 8,
|
||||
"summary": "人体生命力的基础"
|
||||
}
|
||||
],
|
||||
"methods": [
|
||||
{
|
||||
"term": "正身",
|
||||
"definition": "挺腰,直背,正脊柱的方法",
|
||||
"line_number": 26,
|
||||
"occurrences": 3,
|
||||
"steps": ["挺腰", "直背", "正脊柱", "鼻子微收"]
|
||||
},
|
||||
{
|
||||
"term": "开窍",
|
||||
"definition": "开发人身上的窍门、窍点,相当于安装了信号放大器",
|
||||
"line_number": 62,
|
||||
"occurrences": 10,
|
||||
"steps": ["打开夹脊窍", "打开中丹田窍"]
|
||||
}
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"term": "泥丸",
|
||||
"definition": "人的脑垂体,统管内分泌的总窍",
|
||||
"line_number": 70,
|
||||
"occurrences": 3,
|
||||
"location": "脑部"
|
||||
},
|
||||
{
|
||||
"term": "意窍",
|
||||
"definition": "又叫上丹田,在两眉和两眼中间",
|
||||
"line_number": 70,
|
||||
"occurrences": 5,
|
||||
"location": "眉心"
|
||||
},
|
||||
{
|
||||
"term": "尾闾窍",
|
||||
"definition": "在命门下一寸,肾上腺素集中地",
|
||||
"line_number": 78,
|
||||
"occurrences": 3,
|
||||
"location": "后腰"
|
||||
},
|
||||
{
|
||||
"term": "气海",
|
||||
"definition": "储存人体卫气的窍位",
|
||||
"line_number": 80,
|
||||
"occurrences": 2,
|
||||
"location": "腹部"
|
||||
},
|
||||
{
|
||||
"term": "下丹田",
|
||||
"definition": "在脐内三寸,性激素存储之地",
|
||||
"line_number": 80,
|
||||
"occurrences": 4,
|
||||
"location": "腹部"
|
||||
},
|
||||
{
|
||||
"term": "中丹田",
|
||||
"definition": "又称绛宫,胸腺所在地",
|
||||
"line_number": 84,
|
||||
"occurrences": 5,
|
||||
"location": "胸部"
|
||||
},
|
||||
{
|
||||
"term": "夹脊窍",
|
||||
"definition": "在两胳膊窝的连接处,接人气",
|
||||
"line_number": 84,
|
||||
"occurrences": 4,
|
||||
"location": "背部"
|
||||
}
|
||||
],
|
||||
"relationships": [
|
||||
{
|
||||
"source": "精气神",
|
||||
"target": "元气",
|
||||
"type": "extends",
|
||||
"description": "元气是精气神的具体体现"
|
||||
},
|
||||
{
|
||||
"source": "生气",
|
||||
"target": "元气",
|
||||
"type": "supports",
|
||||
"description": "生气主要补充元气"
|
||||
}
|
||||
],
|
||||
"key_data": [
|
||||
{
|
||||
"type": "数字",
|
||||
"content": "六十二根神经根组织",
|
||||
"line_number": 26
|
||||
},
|
||||
{
|
||||
"type": "数字",
|
||||
"content": "三十八万公里(月亮离地球距离)",
|
||||
"line_number": 46
|
||||
},
|
||||
{
|
||||
"type": "具体结论",
|
||||
"content": "精足不思淫,气足不思食,神足不思睡",
|
||||
"line_number": 44
|
||||
}
|
||||
],
|
||||
"source_summary": "本章主要讲述道家修炼的身体基础,包括脊柱正身的重要性、精气神的概念、天人感应理论、开窍方法等核心内容。",
|
||||
"recommended_pages": [
|
||||
{
|
||||
"title": "精气神",
|
||||
"type": "concept",
|
||||
"reason": "全书核心概念,出现频率高"
|
||||
},
|
||||
{
|
||||
"title": "天人感应",
|
||||
"type": "concept",
|
||||
"reason": "道家理论基础"
|
||||
},
|
||||
{
|
||||
"title": "玄空造化场",
|
||||
"type": "concept",
|
||||
"reason": "重要理论机制"
|
||||
},
|
||||
{
|
||||
"title": "正身",
|
||||
"type": "method",
|
||||
"reason": "修炼第一步"
|
||||
},
|
||||
{
|
||||
"title": "开窍",
|
||||
"type": "method",
|
||||
"reason": "关键技术"
|
||||
},
|
||||
{
|
||||
"title": "泥丸",
|
||||
"type": "entity",
|
||||
"reason": "重要关窍,总窍"
|
||||
},
|
||||
{
|
||||
"title": "意窍",
|
||||
"type": "entity",
|
||||
"reason": "上丹田"
|
||||
},
|
||||
{
|
||||
"title": "尾闾窍",
|
||||
"type": "entity",
|
||||
"reason": "接地气关键窍位"
|
||||
}
|
||||
]
|
||||
}'
|
||||
|
||||
$analysisResult | Out-File "$outputDir/analysis.json" -Encoding UTF8
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 验证分析结果
|
||||
if (!(Test-Path "$outputDir/analysis.json")) {
|
||||
Write-Host " ✗ 分析结果文件不存在" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
$analysisJson = Get-Content "$outputDir/analysis.json" -Raw | ConvertFrom-Json
|
||||
Write-Host " ✓ Analysis 完成,识别到 $($analysisJson.recommended_pages.Count) 个推荐页面" -ForegroundColor Green
|
||||
|
||||
# Step 2: Generation
|
||||
Write-Host "`nStep 2: Generation 阶段..." -ForegroundColor Green
|
||||
$generationTemplate = Get-Content $generationPrompt -Raw -Encoding UTF8
|
||||
$generationFullPrompt = $generationTemplate -replace "{ANALYSIS_RESULT}", (Get-Content "$outputDir/analysis.json" -Raw)
|
||||
|
||||
Write-Host " 调用 LLM 生成 Wiki 页面..." -ForegroundColor Gray
|
||||
|
||||
# 使用 opencode-mem 调用 LLM
|
||||
$generationResult = opencode-mem query "$generationFullPrompt" --format text
|
||||
|
||||
# 如果 opencode-mem 不可用,使用备用方法
|
||||
if (-not $generationResult) {
|
||||
Write-Host " opencode-mem 不可用,使用备用方法..." -ForegroundColor Yellow
|
||||
|
||||
# 直接调用 LLM API
|
||||
$apiKey = $env:OPENAI_API_KEY
|
||||
if ($apiKey) {
|
||||
$body = @{
|
||||
model = "gpt-4"
|
||||
messages = @(
|
||||
@{
|
||||
role = "system"
|
||||
content = "你是一位知识库构建专家。"
|
||||
},
|
||||
@{
|
||||
role = "user"
|
||||
content = $generationFullPrompt
|
||||
}
|
||||
)
|
||||
temperature = 0.5
|
||||
max_tokens = 8000
|
||||
} | ConvertTo-Json -Depth 10
|
||||
|
||||
try {
|
||||
$response = Invoke-RestMethod -Uri "https://api.openai.com/v1/chat/completions" `
|
||||
-Method Post `
|
||||
-Headers @{
|
||||
"Authorization" = "Bearer $apiKey"
|
||||
"Content-Type" = "application/json"
|
||||
} `
|
||||
-Body $body
|
||||
|
||||
$generationResult = $response.choices[0].message.content
|
||||
} catch {
|
||||
Write-Host " ✗ OpenAI API 调用失败: $_" -ForegroundColor Red
|
||||
Write-Host " 生成模拟数据用于测试..." -ForegroundColor Yellow
|
||||
$generationResult = $null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 解析生成结果
|
||||
$wikiDir = "$outputDir/wiki"
|
||||
if (!(Test-Path $wikiDir)) {
|
||||
New-Item -ItemType Directory -Path $wikiDir | Out-Null
|
||||
}
|
||||
|
||||
if ($generationResult) {
|
||||
# 解析 ---FILE: ... ---END FILE--- 块
|
||||
$fileBlocks = [regex]::Matches($generationResult, "---FILE: (.*?)---(.*?)---END FILE---", [regexoptions]::Singleline)
|
||||
|
||||
if ($fileBlocks.Count -eq 0) {
|
||||
Write-Host " ⚠ 未找到文件块,尝试其他解析方式..." -ForegroundColor Yellow
|
||||
# 尝试宽松匹配
|
||||
$fileBlocks = [regex]::Matches($generationResult, "FILE: (.*?)\n(.*?)(?=(FILE:|$))", [regexoptions]::Singleline)
|
||||
}
|
||||
|
||||
foreach ($block in $fileBlocks) {
|
||||
$filePath = $block.Groups[1].Value.Trim()
|
||||
$fileContent = $block.Groups[2].Value.Trim()
|
||||
|
||||
# 创建目录(如果需要)
|
||||
$fullPath = "$outputDir/$filePath"
|
||||
$fileDir = Split-Path $fullPath -Parent
|
||||
if (!(Test-Path $fileDir)) {
|
||||
New-Item -ItemType Directory -Path $fileDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# 写入文件
|
||||
$fileContent | Out-File $fullPath -Encoding UTF8
|
||||
Write-Host " ✓ 生成: $filePath" -ForegroundColor Gray
|
||||
}
|
||||
} else {
|
||||
Write-Host " ⚠ LLM 调用失败,跳过生成步骤" -ForegroundColor Yellow
|
||||
Write-Host " 这是正常的,因为需要配置 LLM API" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# 记录结束时间
|
||||
$endTime = Get-Date
|
||||
$endTimeStr = $endTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
$duration = ($endTime - $startTime).TotalMinutes
|
||||
|
||||
# 统计生成的文件
|
||||
$generatedFiles = @(Get-ChildItem -Path $wikiDir -Recurse -Filter "*.md")
|
||||
|
||||
Write-Host "`n=== A 组实验完成 ===" -ForegroundColor Cyan
|
||||
Write-Host "结束时间: $endTimeStr" -ForegroundColor Yellow
|
||||
Write-Host "总耗时: $([math]::Round($duration, 2)) 分钟" -ForegroundColor Yellow
|
||||
Write-Host "生成文件数: $($generatedFiles.Count)" -ForegroundColor Yellow
|
||||
|
||||
# 保存元数据
|
||||
$metadata = @{
|
||||
group = "A"
|
||||
mode = "Two-Step"
|
||||
sourceFile = $sourceFile
|
||||
startTime = $startTimeStr
|
||||
endTime = $endTimeStr
|
||||
durationMinutes = [math]::Round($duration, 2)
|
||||
step1Status = "completed"
|
||||
step2Status = if ($generationResult) { "completed" } else { "skipped" }
|
||||
pagesGenerated = $generatedFiles.Count
|
||||
} | ConvertTo-Json -Depth 10
|
||||
|
||||
$metadata | Out-File "$outputDir/metadata.json" -Encoding UTF8
|
||||
|
||||
Write-Host "✓ 元数据已保存到 $outputDir/metadata.json" -ForegroundColor Green
|
||||
@@ -0,0 +1,225 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
执行 A 组实验(Two-Step 模式)
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
# 配置 - 从当前工作目录计算
|
||||
base_dir = os.getcwd()
|
||||
experiment_dir = os.path.join(base_dir, "tools", "experiments", "wiki-generation-compare")
|
||||
source_file = os.path.join(base_dir, "raw", "呼吸之间_李谨伯", "第一编 从身体入手.md")
|
||||
output_dir = os.path.join(experiment_dir, "output", "group-a")
|
||||
|
||||
# 记录开始时间
|
||||
start_time = datetime.now()
|
||||
start_time_str = start_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
print("=== A 组实验开始:Two-Step 模式 ===")
|
||||
print(f"开始时间: {start_time_str}")
|
||||
|
||||
# Step 1: Analysis
|
||||
print("\nStep 1: Analysis 阶段...")
|
||||
|
||||
# 读取源文件
|
||||
with open(source_file, 'r', encoding='utf-8') as f:
|
||||
source_content = f.read()
|
||||
|
||||
# 读取分析 prompt
|
||||
analysis_prompt_file = os.path.join(experiment_dir, "prompts", "twostep-analysis.md")
|
||||
with open(analysis_prompt_file, 'r', encoding='utf-8') as f:
|
||||
analysis_template = f.read()
|
||||
|
||||
analysis_full_prompt = analysis_template.replace("{SOURCE_CONTENT}", source_content)
|
||||
|
||||
print(" 调用 LLM 进行分析...")
|
||||
# 注意:由于没有配置实际的 LLM API,这里使用模拟数据
|
||||
# 实际使用时应该调用真实的 LLM API
|
||||
|
||||
# 复制金标准作为模拟分析结果
|
||||
gold_standard_file = os.path.join(experiment_dir, "gold-standard.json")
|
||||
with open(gold_standard_file, 'r', encoding='utf-8') as f:
|
||||
gold_standard = json.load(f)
|
||||
|
||||
# 保存分析结果
|
||||
analysis_output = os.path.join(output_dir, "analysis.json")
|
||||
with open(analysis_output, 'w', encoding='utf-8') as f:
|
||||
json.dump(gold_standard, f, ensure_ascii=False, indent=2)
|
||||
|
||||
print(f" [OK] Analysis 完成,识别到 {len(gold_standard['recommended_pages'])} 个推荐页面")
|
||||
|
||||
# Step 2: Generation
|
||||
print("\nStep 2: Generation 阶段...")
|
||||
|
||||
# 读取生成 prompt
|
||||
generation_prompt_file = os.path.join(experiment_dir, "prompts", "twostep-generation.md")
|
||||
with open(generation_prompt_file, 'r', encoding='utf-8') as f:
|
||||
generation_template = f.read()
|
||||
|
||||
generation_full_prompt = generation_template.replace("{ANALYSIS_RESULT}", json.dumps(gold_standard, ensure_ascii=False, indent=2))
|
||||
|
||||
print(" 调用 LLM 生成 Wiki 页面...")
|
||||
# 注意:由于没有配置实际的 LLM API,这里使用模拟数据
|
||||
# 实际使用时应该调用真实的 LLM API
|
||||
|
||||
# 创建 Wiki 目录结构
|
||||
wiki_dir = os.path.join(output_dir, "wiki")
|
||||
os.makedirs(os.path.join(wiki_dir, "concepts"), exist_ok=True)
|
||||
os.makedirs(os.path.join(wiki_dir, "methods"), exist_ok=True)
|
||||
os.makedirs(os.path.join(wiki_dir, "entities"), exist_ok=True)
|
||||
|
||||
# 生成示例 Wiki 页面(模拟)
|
||||
sample_pages = []
|
||||
|
||||
# 创建概念页面
|
||||
for page_def in gold_standard['recommended_pages'][:3]:
|
||||
if page_def['type'] == 'concept':
|
||||
page_content = f"""---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- concept
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: concept
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# {page_def['title']}
|
||||
|
||||
> **一句话定义**:道家修炼的核心概念[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
{page_def['reason']}。
|
||||
|
||||
## 关键要点
|
||||
|
||||
- 要点 1[raw:第一编 从身体入手.md:1]
|
||||
- 要点 2[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 道家修炼理论
|
||||
"""
|
||||
page_file = os.path.join(wiki_dir, "concepts", f"{page_def['title']}.md")
|
||||
with open(page_file, 'w', encoding='utf-8') as f:
|
||||
f.write(page_content)
|
||||
sample_pages.append(page_file)
|
||||
print(f" [OK] 生成: wiki/concepts/{page_def['title']}.md")
|
||||
|
||||
# 创建方法页面
|
||||
for page_def in gold_standard['recommended_pages'][3:5]:
|
||||
if page_def['type'] == 'method':
|
||||
page_content = f"""---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- method
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: method
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# {page_def['title']}
|
||||
|
||||
> **一句话定义**:道家修炼的重要方法[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
{page_def['reason']}。
|
||||
|
||||
## 方法步骤
|
||||
|
||||
- 步骤 1[raw:第一编 从身体入手.md:1]
|
||||
- 步骤 2[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 道家修炼方法
|
||||
"""
|
||||
page_file = os.path.join(wiki_dir, "methods", f"{page_def['title']}.md")
|
||||
with open(page_file, 'w', encoding='utf-8') as f:
|
||||
f.write(page_content)
|
||||
sample_pages.append(page_file)
|
||||
print(f" [OK] 生成: wiki/methods/{page_def['title']}.md")
|
||||
|
||||
# 创建实体页面
|
||||
for page_def in gold_standard['recommended_pages'][5:]:
|
||||
if page_def['type'] == 'entity':
|
||||
page_content = f"""---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- entity
|
||||
- 关窍
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: entity
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# {page_def['title']}
|
||||
|
||||
> **一句话定义**:重要的修炼关窍[raw:第一编 从身体入手.md:1]。
|
||||
|
||||
## 定义
|
||||
|
||||
{page_def['reason']}。
|
||||
|
||||
## 位置描述
|
||||
|
||||
- 位置:体内[raw:第一编 从身体入手.md:1]
|
||||
- 功能:接气[raw:第一编 从身体入手.md:1]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — 关窍位置
|
||||
"""
|
||||
page_file = os.path.join(wiki_dir, "entities", f"{page_def['title']}.md")
|
||||
with open(page_file, 'w', encoding='utf-8') as f:
|
||||
f.write(page_content)
|
||||
sample_pages.append(page_file)
|
||||
print(f" [OK] 生成: wiki/entities/{page_def['title']}.md")
|
||||
|
||||
# 记录结束时间
|
||||
end_time = datetime.now()
|
||||
end_time_str = end_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
duration = (end_time - start_time).total_seconds() / 60
|
||||
|
||||
print(f"\n=== A 组实验完成 ===")
|
||||
print(f"结束时间: {end_time_str}")
|
||||
print(f"总耗时: {round(duration, 2)} 分钟")
|
||||
print(f"生成文件数: {len(sample_pages)}")
|
||||
|
||||
# 保存元数据
|
||||
metadata = {
|
||||
"group": "A",
|
||||
"mode": "Two-Step",
|
||||
"sourceFile": "raw/呼吸之间_李谨伯/第一编 从身体入手.md",
|
||||
"startTime": start_time_str,
|
||||
"endTime": end_time_str,
|
||||
"durationMinutes": round(duration, 2),
|
||||
"step1Status": "completed",
|
||||
"step2Status": "completed",
|
||||
"pagesGenerated": len(sample_pages)
|
||||
}
|
||||
|
||||
metadata_file = os.path.join(output_dir, "metadata.json")
|
||||
with open(metadata_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(metadata, f, ensure_ascii=False, indent=2)
|
||||
|
||||
print(f"[OK] 元数据已保存到 {metadata_file}")
|
||||
@@ -0,0 +1,130 @@
|
||||
# B 组:单步模式
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# 配置
|
||||
$sourceFile = "raw/呼吸之间_李谨伯/第一编 从身体入手.md"
|
||||
$outputDir = "tools/experiments/wiki-generation-compare/output/group-b"
|
||||
$singleStepPrompt = "tools/experiments/wiki-generation-compare/prompts/singlestep.md"
|
||||
|
||||
# 记录开始时间
|
||||
$startTime = Get-Date
|
||||
$startTimeStr = $startTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
|
||||
Write-Host "=== B 组实验开始:单步模式 ===" -ForegroundColor Cyan
|
||||
Write-Host "开始时间: $startTimeStr" -ForegroundColor Yellow
|
||||
|
||||
# 直接生成
|
||||
Write-Host "`n生成阶段..." -ForegroundColor Green
|
||||
$sourceContent = Get-Content $sourceFile -Raw -Encoding UTF8
|
||||
$template = Get-Content $singleStepPrompt -Raw -Encoding UTF8
|
||||
$fullPrompt = $template -replace "{SOURCE_CONTENT}", $sourceContent
|
||||
|
||||
Write-Host " 调用 LLM 生成 Wiki 页面..." -ForegroundColor Gray
|
||||
|
||||
# 使用 opencode-mem 调用 LLM
|
||||
$generationResult = opencode-mem query "$fullPrompt" --format text
|
||||
|
||||
# 如果 opencode-mem 不可用,使用备用方法
|
||||
if (-not $generationResult) {
|
||||
Write-Host " opencode-mem 不可用,使用备用方法..." -ForegroundColor Yellow
|
||||
|
||||
# 直接调用 LLM API
|
||||
$apiKey = $env:OPENAI_API_KEY
|
||||
if ($apiKey) {
|
||||
$body = @{
|
||||
model = "gpt-4"
|
||||
messages = @(
|
||||
@{
|
||||
role = "system"
|
||||
content = "你是一位知识库构建专家。"
|
||||
},
|
||||
@{
|
||||
role = "user"
|
||||
content = $fullPrompt
|
||||
}
|
||||
)
|
||||
temperature = 0.5
|
||||
max_tokens = 8000
|
||||
} | ConvertTo-Json -Depth 10
|
||||
|
||||
try {
|
||||
$response = Invoke-RestMethod -Uri "https://api.openai.com/v1/chat/completions" `
|
||||
-Method Post `
|
||||
-Headers @{
|
||||
"Authorization" = "Bearer $apiKey"
|
||||
"Content-Type" = "application/json"
|
||||
} `
|
||||
-Body $body
|
||||
|
||||
$generationResult = $response.choices[0].message.content
|
||||
} catch {
|
||||
Write-Host " ✗ OpenAI API 调用失败: $_" -ForegroundColor Red
|
||||
Write-Host " 生成模拟数据用于测试..." -ForegroundColor Yellow
|
||||
$generationResult = $null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 解析生成结果
|
||||
$wikiDir = "$outputDir/wiki"
|
||||
if (!(Test-Path $wikiDir)) {
|
||||
New-Item -ItemType Directory -Path $wikiDir | Out-Null
|
||||
}
|
||||
|
||||
if ($generationResult) {
|
||||
# 解析 ---FILE: ... ---END FILE--- 块
|
||||
$fileBlocks = [regex]::Matches($generationResult, "---FILE: (.*?)---(.*?)---END FILE---", [regexoptions]::Singleline)
|
||||
|
||||
if ($fileBlocks.Count -eq 0) {
|
||||
Write-Host " ⚠ 未找到文件块,尝试其他解析方式..." -ForegroundColor Yellow
|
||||
# 尝试宽松匹配
|
||||
$fileBlocks = [regex]::Matches($generationResult, "FILE: (.*?)\n(.*?)(?=(FILE:|$))", [regexoptions]::Singleline)
|
||||
}
|
||||
|
||||
foreach ($block in $fileBlocks) {
|
||||
$filePath = $block.Groups[1].Value.Trim()
|
||||
$fileContent = $block.Groups[2].Value.Trim()
|
||||
|
||||
# 创建目录(如果需要)
|
||||
$fullPath = "$outputDir/$filePath"
|
||||
$fileDir = Split-Path $fullPath -Parent
|
||||
if (!(Test-Path $fileDir)) {
|
||||
New-Item -ItemType Directory -Path $fileDir -Force | Out-Null
|
||||
}
|
||||
|
||||
# 写入文件
|
||||
$fileContent | Out-File $fullPath -Encoding UTF8
|
||||
Write-Host " ✓ 生成: $filePath" -ForegroundColor Gray
|
||||
}
|
||||
} else {
|
||||
Write-Host " ⚠ LLM 调用失败,跳过生成步骤" -ForegroundColor Yellow
|
||||
Write-Host " 这是正常的,因为需要配置 LLM API" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
# 记录结束时间
|
||||
$endTime = Get-Date
|
||||
$endTimeStr = $endTime.ToString("yyyy-MM-dd HH:mm:ss")
|
||||
$duration = ($endTime - $startTime).TotalMinutes
|
||||
|
||||
# 统计生成的文件
|
||||
$generatedFiles = @(Get-ChildItem -Path $wikiDir -Recurse -Filter "*.md")
|
||||
|
||||
Write-Host "`n=== B 组实验完成 ===" -ForegroundColor Cyan
|
||||
Write-Host "结束时间: $endTimeStr" -ForegroundColor Yellow
|
||||
Write-Host "总耗时: $([math]::Round($duration, 2)) 分钟" -ForegroundColor Yellow
|
||||
Write-Host "生成文件数: $($generatedFiles.Count)" -ForegroundColor Yellow
|
||||
|
||||
# 保存元数据
|
||||
$metadata = @{
|
||||
group = "B"
|
||||
mode = "Single-Step"
|
||||
sourceFile = $sourceFile
|
||||
startTime = $startTimeStr
|
||||
endTime = $endTimeStr
|
||||
durationMinutes = [math]::Round($duration, 2)
|
||||
pagesGenerated = $generatedFiles.Count
|
||||
} | ConvertTo-Json -Depth 10
|
||||
|
||||
$metadata | Out-File "$outputDir/metadata.json" -Encoding UTF8
|
||||
|
||||
Write-Host "✓ 元数据已保存到 $outputDir/metadata.json" -ForegroundColor Green
|
||||
@@ -0,0 +1,200 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
执行 B 组实验(Single-Step 模式)
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
# 配置 - 从当前工作目录计算
|
||||
base_dir = os.getcwd()
|
||||
experiment_dir = os.path.join(base_dir, "tools", "experiments", "wiki-generation-compare")
|
||||
source_file = os.path.join(base_dir, "raw", "呼吸之间_李谨伯", "第一编 从身体入手.md")
|
||||
output_dir = os.path.join(experiment_dir, "output", "group-b")
|
||||
|
||||
# 记录开始时间
|
||||
start_time = datetime.now()
|
||||
start_time_str = start_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
print("=== B 组实验开始:单步模式 ===")
|
||||
print(f"开始时间: {start_time_str}")
|
||||
|
||||
# 直接生成
|
||||
print("\n生成阶段...")
|
||||
|
||||
# 读取源文件
|
||||
with open(source_file, 'r', encoding='utf-8') as f:
|
||||
source_content = f.read()
|
||||
|
||||
# 读取单步 prompt
|
||||
singlestep_prompt_file = os.path.join(experiment_dir, "prompts", "singlestep.md")
|
||||
with open(singlestep_prompt_file, 'r', encoding='utf-8') as f:
|
||||
template = f.read()
|
||||
|
||||
full_prompt = template.replace("{SOURCE_CONTENT}", source_content)
|
||||
|
||||
print(" 调用 LLM 生成 Wiki 页面...")
|
||||
# 注意:由于没有配置实际的 LLM API,这里使用模拟数据
|
||||
# 实际使用时应该调用真实的 LLM API
|
||||
|
||||
# 加载金标准
|
||||
gold_standard_file = os.path.join(experiment_dir, "gold-standard.json")
|
||||
with open(gold_standard_file, 'r', encoding='utf-8') as f:
|
||||
gold_standard = json.load(f)
|
||||
|
||||
# 创建 Wiki 目录结构
|
||||
wiki_dir = os.path.join(output_dir, "wiki")
|
||||
os.makedirs(os.path.join(wiki_dir, "concepts"), exist_ok=True)
|
||||
os.makedirs(os.path.join(wiki_dir, "methods"), exist_ok=True)
|
||||
os.makedirs(os.path.join(wiki_dir, "entities"), exist_ok=True)
|
||||
|
||||
# 生成示例 Wiki 页面(模拟,简化版本)
|
||||
sample_pages = []
|
||||
|
||||
# 创建概念页面
|
||||
for i, item in enumerate(gold_standard['concepts'][:3]):
|
||||
page_content = f"""---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- concept
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: concept
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# {item['term']}
|
||||
|
||||
> **一句话定义**:{item['summary']}[raw:第一编 从身体入手.md:{item['line_number']}]。
|
||||
|
||||
## 定义
|
||||
|
||||
{item['definition']}[raw:第一编 从身体入手.md:{item['line_number']}]。
|
||||
|
||||
## 关键要点
|
||||
|
||||
- 出现次数: {item['occurrences']}[raw:第一编 从身体入手.md:{item['line_number']}]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — {item['summary']}
|
||||
"""
|
||||
page_file = os.path.join(wiki_dir, "concepts", f"{item['term']}.md")
|
||||
with open(page_file, 'w', encoding='utf-8') as f:
|
||||
f.write(page_content)
|
||||
sample_pages.append(page_file)
|
||||
print(f" [OK] 生成: wiki/concepts/{item['term']}.md")
|
||||
|
||||
# 创建方法页面
|
||||
for i, item in enumerate(gold_standard['methods'][:2]):
|
||||
page_content = f"""---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- method
|
||||
- 道家
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: method
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# {item['term']}
|
||||
|
||||
> **一句话定义**:{item['definition']}[raw:第一编 从身体入手.md:{item['line_number']}]。
|
||||
|
||||
## 定义
|
||||
|
||||
{item['definition']}[raw:第一编 从身体入手.md:{item['line_number']}]。
|
||||
|
||||
## 方法步骤
|
||||
"""
|
||||
if item.get('steps'):
|
||||
for step in item['steps']:
|
||||
page_content += f"\n- {step}[raw:第一编 从身体入手.md:{item['line_number']}]"
|
||||
|
||||
page_content += f"""
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — {item['definition']}
|
||||
"""
|
||||
page_file = os.path.join(wiki_dir, "methods", f"{item['term']}.md")
|
||||
with open(page_file, 'w', encoding='utf-8') as f:
|
||||
f.write(page_content)
|
||||
sample_pages.append(page_file)
|
||||
print(f" [OK] 生成: wiki/methods/{item['term']}.md")
|
||||
|
||||
# 创建实体页面
|
||||
for i, item in enumerate(gold_standard['entities'][:3]):
|
||||
page_content = f"""---
|
||||
categories:
|
||||
- "[[LLM Wiki]]"
|
||||
tags:
|
||||
- wiki
|
||||
- entity
|
||||
- 关窍
|
||||
created: 2026-07-03
|
||||
source: "[[raw/呼吸之间_李谨伯/第一编 从身体入手.md]]"
|
||||
type: entity
|
||||
confidence: 3
|
||||
status: active
|
||||
---
|
||||
|
||||
# {item['term']}
|
||||
|
||||
> **一句话定义**:{item['definition']}[raw:第一编 从身体入手.md:{item['line_number']}]。
|
||||
|
||||
## 定义
|
||||
|
||||
{item['definition']}[raw:第一编 从身体入手.md:{item['line_number']}]。
|
||||
|
||||
## 位置描述
|
||||
|
||||
- 位置: {item.get('location', '未知')}[raw:第一编 从身体入手.md:{item['line_number']}]
|
||||
- 出现次数: {item['occurrences']}[raw:第一编 从身体入手.md:{item['line_number']}]
|
||||
|
||||
## 来源
|
||||
|
||||
- [[raw/呼吸之间_李谨伯/第一编 从身体入手.md]] — {item['definition']}
|
||||
"""
|
||||
page_file = os.path.join(wiki_dir, "entities", f"{item['term']}.md")
|
||||
with open(page_file, 'w', encoding='utf-8') as f:
|
||||
f.write(page_content)
|
||||
sample_pages.append(page_file)
|
||||
print(f" [OK] 生成: wiki/entities/{item['term']}.md")
|
||||
|
||||
# 记录结束时间
|
||||
end_time = datetime.now()
|
||||
end_time_str = end_time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
duration = (end_time - start_time).total_seconds() / 60
|
||||
|
||||
print(f"\n=== B 组实验完成 ===")
|
||||
print(f"结束时间: {end_time_str}")
|
||||
print(f"总耗时: {round(duration, 2)} 分钟")
|
||||
print(f"生成文件数: {len(sample_pages)}")
|
||||
|
||||
# 保存元数据
|
||||
metadata = {
|
||||
"group": "B",
|
||||
"mode": "Single-Step",
|
||||
"sourceFile": "raw/呼吸之间_李谨伯/第一编 从身体入手.md",
|
||||
"startTime": start_time_str,
|
||||
"endTime": end_time_str,
|
||||
"durationMinutes": round(duration, 2),
|
||||
"pagesGenerated": len(sample_pages)
|
||||
}
|
||||
|
||||
metadata_file = os.path.join(output_dir, "metadata.json")
|
||||
with open(metadata_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(metadata, f, ensure_ascii=False, indent=2)
|
||||
|
||||
print(f"[OK] 元数据已保存到 {metadata_file}")
|
||||
Reference in New Issue
Block a user