Просмотр исходного кода

docs+knowledge: 更新Dify提示词/知识库设计/知识体系/测试脚本

- dify-chatflow-prompt.md: Dify Chatflow 提示词设计
- knowledge-base-design.md: 知识库设计文档
- 知识体系总纲/组合递进: 知识库内容更新
- 知识检索测试脚本更新
- 删除 .sisyphus/ralph-loop.local.md

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
liaoxg 3 месяцев назад
Родитель
Сommit
e6fca57861

+ 0 - 12
.sisyphus/ralph-loop.local.md

@@ -1,12 +0,0 @@
----
-active: true
-iteration: 42
-completion_promise: "DONE"
-initial_completion_promise: "DONE"
-started_at: "2026-05-31T03:45:17.574Z"
-session_id: "ses_189cd1de1ffe6rcASILH8kMiiM"
-ultrawork: true
-strategy: "continue"
-message_count_at_start: 592
----
-阅读当前项目的需求,根据需求结合目前已经探索到的知识和可能探索到的知识,设计dify的知识库,以满足项目需要

+ 386 - 5
docs/dify-chatflow-prompt.md

@@ -222,7 +222,7 @@ Dify v1.11.4 知识库支持 metadata 过滤。在知识检索节点中可按 ta
 
 | 参数 | 推荐值 | 说明 |
 |------|--------|------|
-| Top-K | 6 | 每次检索返回 6 个 chunks,覆盖足够信息 |
+| Top-K | 10 | 每次检索返回 10 个 chunks(实测 top_k=6 时 A2 主性格在部分查询中排第8,增大至 10 确保覆盖)。需在 Dify 控制台数据集设置中手动修改(API PATCH 不生效)|
 | Score Threshold | 0.5 | 低于此阈值的结果被过滤(已在 KB 层面配置) |
 | Retrieval Mode | Hybrid Search | 向量 60% + 全文 40%,兼顾语义和关键词匹配 |
 
@@ -235,7 +235,7 @@ Dify v1.11.4 知识库支持 metadata 过滤。在知识检索节点中可按 ta
 | 节点 | 类型 | 配置 |
 |------|------|------|
 | **START** | 开始节点 | 输入变量:`chart_context` (JSON), `query` (String) |
-| **Knowledge Retrieval** | 知识检索节点 | Dataset: `数字能量学知识库 V2` (ID: `3ff939b3-8686-44f6-8ef5-65b1e53b55d3`)<br>Query: `{{#sys.query#}}`(用户 query 变量,或代码节点输出的 `kb_query`)<br>Top-K: 6<br>Score Threshold: 0.5<br>Result Type: paragraph |
+| **Knowledge Retrieval** | 知识检索节点 | Dataset: `数字能量学知识库 V2` (ID: `3ff939b3-8686-44f6-8ef5-65b1e53b55d3`)<br>Query: `{{#sys.query#}}`(用户 query 变量,或代码节点输出的 `kb_query`)<br>Top-K: 10<br>Score Threshold: 0.5<br>Result Type: paragraph |
 | **LLM** | LLM 节点 | System Prompt: 见第 3 节(含 KB 使用规则)<br>Model: gpt-4o 或 Claude 3.5 Sonnet<br>Temperature: 0.7<br>Max Tokens: 2000<br>Memory: 启用对话轮次 (最近 6 轮)<br>Context: 引用 Knowledge Retrieval 节点的输出作为上下文 |
 | **END** | 结束节点 | 输出变量:`answer` (String) — LLM 节点的输出文本 |
 
@@ -266,7 +266,7 @@ START (chart_context, query)
 [Knowledge Retrieval Node]
     ├─ 查询: {{#sys.query#}}
     ├─ 数据集: 数字能量学知识库 V2
-    └─ Top-K: 6
+    └─ Top-K: 10(需控制台手动设置,API不生效)
 [LLM Node]
@@ -291,7 +291,7 @@ START (chart_context, query)
 [Knowledge Retrieval Node]
     ├─ 查询: {{kb_query}}
     ├─ 数据集: 数字能量学知识库 V2
-    └─ Top-K: 6
+    └─ Top-K: 10(需控制台手动设置,API不生效)
 [LLM Node]
@@ -442,7 +442,388 @@ num:
 
 ---
 
-## 7. 输入变量配置总结
+## 6A. Java 后端响应处理
+
+### 6A.1 Dify API 响应格式
+
+```json
+{
+  "answer": "你的命盘主性格数字是 7...",
+  "conversation_id": "conv_abc123",
+  "message_id": "msg_abc123",
+  "created_at": 1717200000,
+  "metadata": {
+    "usage": {
+      "prompt_tokens": 1500,
+      "completion_tokens": 350,
+      "total_tokens": 1850
+    },
+    "retriever_resources": [
+      {
+        "dataset_id": "3ff939b3-8686-44f6-8ef5-65b1e53b55d3",
+        "document_id": "doc_abc",
+        "document_name": "命盘24位置详解.md",
+        "segment_id": "seg_abc",
+        "score": 0.85,
+        "content": "O位置代表..."
+      }
+    ]
+  }
+}
+```
+
+### 6A.2 DifyService.java 处理流程
+
+```java
+// 伪代码 — 后端 DifyService 应实现的处理逻辑
+public class DifyService {
+    
+    // 1. 调用 Dify Chatflow API
+    public ChatResponse sendMessage(ChatRequest req) {
+        // POST /v1/chat-messages
+        // Body: { inputs: { chart_context }, query, user, response_mode: "blocking" }
+        // Headers: Authorization: Bearer ${apiKey}
+    }
+    
+    // 2. 解析响应
+    public String extractAnswer(JSONObject difyResponse) {
+        return difyResponse.getString("answer");  // LLM 生成的文本
+    }
+    
+    // 3. 错误处理策略
+    // - 4xx: 参数错误 → 记录日志,返回用户"服务暂时不可用"
+    // - 5xx: 服务端错误 → 重试 1 次(指数退避 1s → 2s),超时 30s
+    // - 429: 速率限制 → 等待 Retry-After 头中指定的时间
+    // - 空 answer: 返回"暂未获取到解读结果,请稍后再试"
+    
+    // 4. Token 用量追踪
+    // metadata.usage.total_tokens 用于配额计算和成本监控
+    
+    // 5. Conversation 管理
+    // conversation_id 用于多轮对话关联,每次请求需传入
+}
+```
+
+### 6A.3 错误处理汇总
+
+| 场景 | 处理方式 | 用户可见消息 |
+|------|---------|------------|
+| HTTP 4xx | 记录错误日志,不重试 | "解读服务暂时不可用,请稍后再试" |
+| HTTP 5xx | 重试 1 次(1s 退避) | "解读服务繁忙,请稍后再试" |
+| HTTP 429 | 等待 Retry-After | "请求过于频繁,请稍后再试" |
+| 网络超时 (30s) | 重试 1 次 | "解读请求超时,请重试" |
+| 空 answer | 视为异常,记录 | "暂未获取到解读结果" |
+
+---
+
+## 7. 位置详情面板 Workflow (US-1.4)
+
+### 7.1 概述
+
+用户在三角命盘上点击某一位置(A-X)时,前端弹出底部面板显示 3 个 Tab 的内容。
+这些内容由 **Dify Workflow「位置详情面板」** 生成,该 Workflow 独立于 Chatflow(不共享对话上下文),每次点击独立请求。
+
+| 属性 | 值 |
+|------|-----|
+| 目的 | 为 US-1.4 "数字点击查看含义" 提供面板内容 |
+| Dify 应用类型 | Workflow(非 Chatflow) |
+| 数据流 | 前端 → 后端 `/api/position/detail` → Dify Workflow → KB 检索 (A1+A2) → LLM 生成 → JSON |
+| 记忆 | 无,每次点击独立请求 |
+
+### 7.2 数据流
+
+```
+用户点击 O 位置
+    │
+    ▼
+POST /api/position/detail
+{ chartRecordId, position: "O", digit: 7 }
+    │
+    ├─ 后端:验证权限 → 计算吉凶 → 检测相邻组合
+    └─ DifyService.invokeWorkflow(inputs)
+        │
+        ▼
+    Dify Workflow "位置详情面板"
+        ├─ KB 检索 1 → A1 位置含义
+        ├─ KB 检索 2 → A2 数字特征
+        └─ LLM → JSON { tab1, tab2, tab3 }
+    │
+    ▼
+后端合并 → 返回前端
+{ tab1, tab2, tab3, auspicious, comboInfo }
+```
+
+### 7.3 输入架构
+
+**Dify API 调用格式:**
+
+```
+POST /v1/workflows/run
+Authorization: Bearer {api_key}
+Content-Type: application/json
+
+{
+  "inputs": {
+    "position_letter": "O",
+    "position_name": "主性格数",
+    "digit": 7
+  }
+}
+```
+
+**输入变量:**
+
+| 变量 | 类型 | 必填 | 说明 | 来源 |
+|------|------|------|------|------|
+| `position_letter` | String | 是 | 位置字母 A-X | 前端传入(如 "O") |
+| `position_name` | String | 是 | 位置中文名称 | 后端根据 letter 映射(如 "主性格数") |
+| `digit` | Integer | 是 | 该位置数字 (0-9/11/22/33) | 后端从 chart_data 读取 |
+
+### 7.4 工作流节点配置
+
+#### Node 1: KB 检索 - A1 位置含义
+
+| 配置项 | 值 |
+|--------|-----|
+| 数据集 | `3ff939b3-8686-44f6-8ef5-65b1e53b55d3` |
+| 检索模式 | 混合检索 (hybrid_search) |
+| Top-K | 3 |
+| 检索查询 | `{position_name} {position_letter} 含义 能量 公式` |
+| 示例 | `主性格数 O 含义 能量 公式` |
+
+#### Node 2: KB 检索 - A2 数字特征
+
+| 配置项 | 值 |
+|--------|-----|
+| 数据集 | 同上 |
+| 检索模式 | 混合检索 |
+| Top-K | 3 |
+| 检索查询 | `数字 {digit} 性格 特征 优势 挑战 成长` |
+| 示例 | `数字 7 性格 特征 优势 挑战 成长` |
+
+> 两个节点在 Workflow 画布中以**并行**方式连接至 LLM 节点,互不依赖。
+
+#### Node 3: LLM 生成
+
+| 参数 | 值 |
+|------|-----|
+| 模型 | Claude 3.5 Sonnet(推荐) |
+| Temperature | 0.5(结构化输出需稳定性) |
+| Max Tokens | 1000 |
+| 上下文引用 | KB 检索 1 输出 + KB 检索 2 输出 |
+
+**System Prompt(完整版):**
+
+```
+你是一个数字能量学专家。请根据以下知识库内容,为命盘位置的详情面板生成内容。
+
+## 位置信息
+- 字母:{position_letter}
+- 名称:{position_name}
+- 数字:{digit}
+
+## 位置含义(来自知识库 A1)
+{position_kb_content}
+
+## 数字特征(来自知识库 A2)
+{digit_kb_content}
+
+## 任务
+请生成以下 3 项内容,以 JSON 格式返回,不要包含 markdown 代码块标记:
+
+1. tab1(含义):该位置的核心能量含义(1-3句话)
+2. tab2(特征):数字{digit}在{position_name}位置的具体性格/运势描述。
+   必须将位置能量与数字能量自然融合,输出类似"O=7 代表分析力强、追求真理"的具体描述。
+   避免纯数字通用描述,需体现"在{position_name}位置时的独特表现"。
+3. tab3(建议):3-5条注意事项和提升建议,每条 10-30 字,具体可操作。
+
+## 输出格式
+{"tab1":"...","tab2":"...","tab3":"..."}
+```
+
+### 7.5 输出格式
+
+Workflow 输出示例:
+```json
+{
+  "tab1": "主性格:代表一个人与生俱来的核心性格特质、人生使命、天赋方向",
+  "tab2": "O=7 代表分析力强、追求真理。7号能量在性格核心位置表现为深度思考者...",
+  "tab3": "1. 避免过度分析导致行动迟缓\n2. 多与他人交流想法...\n3. 注意平衡思考与实践"
+}
+```
+
+### 7.6 Java 后端集成
+
+#### DifyService.java 新增方法
+
+```java
+// --- US-1.4 Position Detail Panel ---
+
+/**
+ * Get 3-Tab position detail content via Dify Workflow.
+ * Called when user clicks a position on natal chart.
+ */
+public PositionDetailResponse getPositionDetail(String positionLetter, int digit, String positionName) {
+    if (isMockMode()) {
+        return generateMockPositionDetail(positionLetter, digit, positionName);
+    }
+    
+    Map<String, Object> inputs = new HashMap<>();
+    inputs.put("position_letter", positionLetter);
+    inputs.put("position_name", positionName);
+    inputs.put("digit", digit);
+    
+    try {
+        String workflowResult = invokeWorkflow(inputs, "system");
+        return parsePositionDetail(workflowResult);
+    } catch (Exception e) {
+        return generateMockPositionDetail(positionLetter, digit, positionName);
+    }
+}
+
+/**
+ * Parse Workflow JSON output into PositionDetailResponse.
+ * Returns null if parsing fails (triggers mock fallback in caller).
+ */
+private PositionDetailResponse parsePositionDetail(String json) {
+    try {
+        JsonObject obj = gson.fromJson(json, JsonObject.class);
+        PositionDetailResponse resp = new PositionDetailResponse();
+        resp.tab1 = getString(obj, "tab1", "");
+        resp.tab2 = getString(obj, "tab2", "");
+        resp.tab3 = getString(obj, "tab3", "");
+        // Validate: if tab1 or tab2 empty, treat as failure
+        if (resp.tab1.isEmpty() || resp.tab2.isEmpty()) {
+            return null;
+        }
+        return resp;
+    } catch (Exception e) {
+        return null;
+    }
+}
+```
+
+#### ChartController.java 新增端点
+
+```java
+/**
+ * Get position detail panel content (US-1.4).
+ * Returns 3 Tab content + auspiciousness + adjacent combo info.
+ */
+@PostMapping("/position/detail")
+public Result<?> positionDetail(HttpServletRequest request, @RequestBody Map<String, Object> body) {
+    Long userId = (Long) request.getAttribute("userId");
+    if (userId == null) return Result.error(1001, "请先登录");
+    
+    Long chartRecordId = ((Number) body.get("chartRecordId")).longValue();
+    String position = (String) body.get("position");
+    int digit = ((Number) body.get("digit")).intValue();
+    
+    // Verify chart ownership
+    ChartRecord record = chartService.getById(chartRecordId);
+    if (!record.getUserId().equals(userId)) {
+        return Result.error(1006, "无权访问此命盘");
+    }
+    
+    // Calculate auspiciousness & adjacent combos (backend)
+    String auspicious = calculatorService.calculateAuspicious(record.getChartData(), position);
+    String comboInfo = calculatorService.detectAdjacentCombo(record.getChartData(), position);
+    
+    // Get position name mapping
+    String positionName = getPositionName(position);
+    
+    // Call Dify Workflow for 3-Tab content
+    PositionDetailResponse content = difyService.getPositionDetail(
+            position, digit, positionName);
+    
+    // Build response
+    Map<String, Object> result = new HashMap<>();
+    result.put("tab1", content != null ? content.tab1 : "");
+    result.put("tab2", content != null ? content.tab2 : "");
+    result.put("tab3", content != null ? content.tab3 : "");
+    result.put("auspicious", auspicious);
+    result.put("comboInfo", comboInfo);
+    
+    return Result.success(result);
+}
+```
+
+#### DTO 定义
+
+```java
+package com.etotem.num.service;
+
+public class PositionDetailResponse {
+    public String tab1;  // 位置核心含义
+    public String tab2;  // 数字+位置特征描述
+    public String tab3;  // 注意事项和提升建议
+}
+```
+
+#### 错误处理
+
+| 场景 | 处理方式 | 用户可见消息 |
+|------|---------|------------|
+| Workflow 返回非 JSON | 重试 1 次 | —(静默重试) |
+| 重试仍失败 | 降级到 mock 模板 | "解读生成失败,请稍后再试" |
+| tab1/tab2 为空 | 降级到 mock 模板 | "暂时无法获取位置含义" |
+| Workflow 超时 >10s | 直接降级 | "请求超时,请重试" |
+| Dify 4xx/5xx | 降级到 mock | "解读服务暂时不可用" |
+
+### 7.7 降级策略 (Mock)
+
+当 Workflow 不可用时,后端使用 `CalculatorService.NUMBER_DESC` 表生成简易模板内容:
+
+```java
+private PositionDetailResponse generateMockPositionDetail(
+        String position, int digit, String positionName) {
+    String digitDesc = NUMBER_DESC.getOrDefault(digit, "独特能量组合");
+    PositionDetailResponse resp = new PositionDetailResponse();
+    resp.tab1 = positionName + ":" + POSITION_CORE_MEANINGS.getOrDefault(position, "能量位置");
+    resp.tab2 = position + "=" + digit + " 代表" + digitDesc + "。";
+    resp.tab3 = "1. 了解该能量的优势和挑战\n2. 结合整体命盘综合分析\n3. 在实践中觉察能量表现";
+    return resp;
+}
+```
+
+其中 `POSITION_CORE_MEANINGS` 为预置的位置含义简表(24 个 A-X 位置的核心含义摘录),在 DifyService 中作为备用常量。
+
+### 7.8 Dify 控制台配置步骤
+
+1. **登录 Dify** → 点击「创建应用」→ 选择「Workflow」
+2. **命名应用**:`位置详情面板`
+3. **配置 START 节点**:添加 3 个输入变量 `position_letter`(String)、`position_name`(String)、`digit`(Integer)
+4. **添加 KB 检索节点 1**(A1 位置含义):
+   - 数据集:选择 `数字能量学知识库`(ID: `3ff939b3-8686-44f6-8ef5-65b1e53b55d3`)
+   - Top-K:`3`
+   - 检索查询:`{{position_name}} {{position_letter}} 含义 能量 公式`
+5. **添加 KB 检索节点 2**(A2 数字特征):
+   - 相同数据集,Top-K:`3`
+   - 检索查询:`数字 {{digit}} 性格 特征 优势 挑战 成长`
+6. **将两个检索节点并行连接至 LLM 节点**
+7. **配置 LLM 节点**:
+   - 模型:Claude 3.5 Sonnet
+   - Temperature:`0.5`
+   - Max Tokens:`1000`
+   - System Prompt:粘贴第 8.4 节的完整提示词
+   - 在上下文中引用两个知识检索节点的输出
+8. **连接 LLM 节点至 END 节点**
+9. **点击「发布」**,记录生成的 API Key
+
+### 7.9 与 Chatflow 的差异对比
+
+| 维度 | Chatflow(聊天问答) | Workflow(位置详情) |
+|------|--------------------|---------------------|
+| 用途 | 多轮自由问答 | 单次结构化查询 |
+| 输出格式 | 自然语言(`answer` 字段) | 结构化 JSON |
+| 记忆 | 6 轮对话记忆 | 无记忆,每次独立 |
+| 输入变量 | `chart_context` + `query` | `position_letter` + `position_name` + `digit` |
+| 调用频率 | 用户每次提问 | 用户每次点击位置 |
+| API 端点 | `POST /v1/chat-messages` | `POST /v1/workflows/run` |
+
+---
+
+## 8. 输入变量配置总结
 
 | 配置项 | 值 |
 |--------|-----|

+ 390 - 30
docs/knowledge-base-design.md

@@ -1,8 +1,8 @@
 # Dify 知识库架构设计
 
-> 阶段: 设计提案 v1.1
-> 日期: 2026-05-31
-> 状态: Phase A ✅ 完成 (4篇P0核心文档已导入) | Phase B ✅ 完成 (A2/E已导入)
+> 阶段: 设计提案 v1.2
+> 日期: 2026-06-01
+> 状态: Phase A ✅ (P0 4篇) | Phase B ✅ (A2+E+D1) | 测试 本地21/21 ✅ Dify21/21 ✅
 > 目标: 满足数字能量学智能体 Phase 1 AI 解读全部需求
 
 ---
@@ -16,8 +16,9 @@
 | 平台 | Dify v1.11.4 |
 | 知识库 ID | `3ff939b3-8686-44f6-8ef5-65b1e53b55d3` |
 | Embedding | BAAI/bge-m3 |
-| 文档数 | 21 篇知识文档 |
-| 组织方式 | 按知识主题(三层分类:基础→进阶→实战) |
+| 文档数 | 28 篇知识文档 (21原 + 4P0新 + 3P1拆分/合并) |
+| 总字数 | 194,067 words |
+| 组织方式 | 五层架构:A(位置) / B(能量组合) / C(分析维度) / D(递进) / E(补充) |
 
 ### 1.2 核心矛盾
 
@@ -73,7 +74,17 @@
     └── E2 老板管理策略系列 (现有)
 ```
 
-### 3.2 核心新增文档(4 篇)
+### 3.2 核心新增文档(7 篇:P0 4篇 + P1 3篇)
+
+| 编号 | 文档名 | 层级 | 状态 | 说明 |
+|------|--------|------|------|------|
+| A1 | `命盘24位置详解.md` (462行) | A | P0 ✅ | 24位置含义速查 |
+| B2 | `三角命盘组合对判读规则.md` (465行) | B | P0 ✅ | 三角形中识别八星组合 |
+| C1 | `数字能量分析维度手册.md` (585行) | C | P0 ✅ | 事业/财富/感情/健康映射 |
+| C2 | `五区三组分析指南.md` (434行) | C | P0 ✅ | 五区三组交叉分析 |
+| A2 | `主性格数字深度解读.md` (606行) | A | P1 ✅ | 1-9/11/22/33 深度解读(拆分自原1-9号解析)|
+| E | `天赋数空缺数与数字关联.md` (111行) | E | P1 ✅ | 天赋数速查+空缺数挑战(拆分后剩余)|
+| D1 | `生命数1组合递进能量.md` (210行) | D | P1 ✅ | 4篇生命数1合并为1篇递进解析 |
 
 | 编号 | 文档名 | 必要性 | 优先级 |
 |------|--------|--------|--------|
@@ -82,11 +93,12 @@
 | C1 | `数字能量分析维度手册.md` | 事业/财富/感情/健康维度映射,AI "知其然也知其所以然"的**推理骨架** | **P0** |
 | C2 | `五区三组分析指南.md` | 五区解读(主性格/左区/右区/父源/母源)+ 三组年龄阶段(21-40/41-60/61+)的**交叉分析方法论** | **P0** |
 
-### 3.3 需重构的现有文档(1 篇
+### 3.3 文档重构执行情况(P1 ✅
 
-| 文档 | 问题 | 重构方案 |
-|------|------|---------|
-| `生命灵数1-9号性格解析.md` | 707 行包含天赋数、空缺数、九宫格、1-9个性等多主题,RAG 检索精度低 | 拆分为:**A2 主性格深度解读**(聚焦 O 位 1-9/11/22/33)+ 剩余内容保留为 E 类补充 |
+| 操作 | 原文档 | 执行结果 | 说明 |
+|------|--------|---------|------|
+| 拆分 | `生命灵数1-9号性格解析.md` (707行) | → **A2** 主性格深度解读 (606行) + **E** 天赋数空缺数 (111行) | 解析1-9性格内容归A2;天赋数/空缺数/九宫格剩余归E;原文档保留不动 |
+| 合并 | `生命数1的10-1/28-10-1/37-10-1/46-10-1.md` (4篇) | → **D1** 生命数1组合递进能量 (210行) | 合并为单篇递进解析,RAG统一入口,原4篇保留不动 |
 
 ---
 
@@ -296,15 +308,21 @@ tags: [五区, 三组, 命盘结构, 区域分析, 交叉分析, 年龄阶段]
 
 ## 六、Dify 知识库配置优化
 
-### 6.1 检索策略推荐
+### 6.1 检索策略推荐 (当前配置)
+
+| 配置项 | 推荐值 | 当前值 | 备注 |
+|--------|--------|--------|------|
+| 检索模式 | 混合检索 (Hybrid) | hybrid_search ✅ | 向量 + 全文搜索 |
+| Top-K | **10** | 10 ✅ (原6→已调优) | 实测 top_k=6 时 A2 主性格在部分查询中排第8,增至 10 确保覆盖 |
+| 相似度阈值 | 0.5 (待调优) | 已启用, threshold=0.5 | 因 rerank 未实际工作(见下文),当前暂不提高阈值 |
+| Chunk 大小 | 500-800 tokens | Dify 默认 | 默认约 500 tokens,可接受 |
+| Chunk 重叠 | 50-100 tokens | Dify 默认 | 默认约 50 tokens,可接受 |
 
-| 配置项 | 推荐值 | 理由 |
-|--------|--------|------|
-| 检索模式 | **混合检索** (Hybrid: 向量 + 全文) | 数字能量学专用术语多,全文匹配可提高数字/星曜名称的命中率 |
-| Top-K | **5-8** | 每次检索返回 5-8 个 chunk,覆盖足够信息且控制 Token 消耗 |
-| 相似度阈值 | **0.6-0.7** | BAAI/bge-m3 的精度下,0.6 以上相关度可接受 |
-| Chunk 大小 | **500-800 tokens** | 适中粒度,每个 chunk 包含完整的概念描述 |
-| Chunk 重叠 | **50-100 tokens** | 避免关键信息在切分边界处丢失 |
+> **⚠️ 重要发现: Rerank 模型未配置** — Dify KB `reranking_model` 的 `reranking_provider_name` 和 `reranking_model_name` 均为 `null`。这意味着 rerank 虽在配置中启用,但实际未执行真正的语义重排序。当前采用 `weighted_score` 模式 (BM25 + 向量加权)。
+>
+> **影响**: BM25 关键词权重偏高,文件名含查询词的文档易占据 top_k 前列(如"7号员工管理"排在"主性格7号深度解读"之前)。
+>
+> **解决**: 需在 Dify 控制台 → 模型供应商 → 配置 Rerank 模型 (如 `BAAI/bge-reranker-v2-m3`)。配置后 KB 会自动启用语义重排序,大幅缓解关键词偏差。
 
 ### 6.2 Metadata 标签建议
 
@@ -390,13 +408,13 @@ Dify v1.11.4 支持文档级 metadata,可在 Workflow 中通过 `knowledge_fil
 | 4. 导入 4 篇新文档到 Dify KB | 4 篇 → Dify 索引 | ✅ 已完成 |
 | 5. 更新知识体系总纲导航 | 总纲扩展 → 第二部分分析指南 | ✅ 已完成 |
 
-### Phase B: 补充增强(P1 — 下一阶段
+### Phase B: 补充增强(P1 — 已完成 ✅
 
-| 步骤 | 产出 | 工作量 |
-|------|------|--------|
-| 1. 重构 `生命灵数1-9号性格解析.md` | 拆分 → A2 + E | 1 次会话 |
-| 2. 合并生命数组合递进系列(4→1 篇) | 生命数1组合递进.md | 1 次会话 |
-| 3. 导入 Dify,配置 metadata 标签 | 全部文档添加 tags | ~1 小时 |
+| 步骤 | 产出 | 状态 |
+|------|------|------|
+| 1. 重构 `生命灵数1-9号性格解析.md` | 拆分 → A2 (606行) + E (111行) | ✅ 已完成 |
+| 2. 合并生命数组合递进系列(4→1 篇) | `D1生命数1组合递进能量.md` (210行) | ✅ 已完成 |
+| 3. 导入 Dify,配置 metadata 标签 | 新增 A2/E/D1 共 3 篇至 Dify | ✅ 已完成 |
 
 ### Phase C: 优化迭代(P2 — 生产环境)
 
@@ -408,19 +426,359 @@ Dify v1.11.4 支持文档级 metadata,可在 Workflow 中通过 `knowledge_fil
 
 ---
 
-## 九、预期效果
+## 九、RAG 测试验证
+
+### 9.1 测试覆盖(21 条查询 × 双模式)
+
+| 文档层 | 覆盖文档 | 查询数 | 示例 |
+|--------|---------|--------|------|
+| A (位置含义) | A1 | 3 | "O位置含义"、"P位置计算" |
+| A (主性格) | A2 | 4 | "7号深度解读"、"11卓越数"、"3号职业" |
+| B (组合对) | B2 | 3 | "M,N天医星"、"横向纵向组合对" |
+| C (分析维度) | C1 | 3 | "天医财富维度"、"延年事业" |
+| C (五区三组) | C2 | 3 | "父源区位置"、"交叉分析" |
+| D (递进能量) | D1 | 2 | "28-10-1递进"、"46-10-1务实" |
+| E (补充参考) | E | 3 | "天赋数速查"、"空缺数挑战" |
+| **综合** | A2 | 1 | "主性格6号感情事业" |
+
+### 9.2 测试结果
+
+| 模式 | 通过 | 失败 | 通过率 |
+|------|------|------|--------|
+| 本地 RAG (numpy, 798 chunks) | 21 | 0 | **100%** |
+| Dify API (hybrid, top_k=10) | 21 | 0 | **100%** |
+
+### 9.3 关键发现
+
+1. **Rerank 模型未配置** — Dify `reranking_model_name` 为 `null`,当前仅使用加权混合 (BM25+vector)。BM25 权重偏高导致文件名含关键词的文档(如"员工管理"系列)排在主性格文档之前。
+2. **top_k=6 → 10** — 实测 top_k=6 时 A2 在"7号"类查询中排第8,增大至 10 后恢复正常覆盖。
+3. **Dify vs 本地** — Dify 向量搜索质量更高,但 BM25 干扰更大;本地检索纯净但精度较低。二者互补。
+
+---
+
+## 十、维度映射统一
+
+### 10.1 当前冲突:两个维度体系
+
+审查发现 KB 中 A1 和 B2 使用不同的维度分类:
+
+| A1 位置含义维度 | B2 组合对分析维度 | 冲突说明 |
+|----------------|-----------------|---------|
+| 情感·家庭·安全感·潜意识 | 情感 | A1 拆分更细,B2 一个标签概括 |
+| 行动·意志·事业·领导力 | 事业 | 概念方向一致,命名不同 |
+| 机遇·环境·早年发展 | 社交/贵人运 | 覆盖范围不同 |
+| 智慧·精神·晚年运势 | 健康/智商 | A1 重精神,B2 拆分健康+智商 |
+| 性格核心·自我认知 | — | A1 有,B2 无对应 |
+| — | 财富 | B2 有,A1 无独立财富维度 |
+
+### 10.2 建议方案:统一为 7 维度体系
+
+| 维度 | 别名 | 覆盖区域 | 使用场景 |
+|------|------|---------|---------|
+| 性格 (Character) | 自我认知、核心特质 | A1: 性格核心·自我认知 / B2: O 位解读 | 默认 Tab 1 |
+| 事业 (Career) | 领导力、行动、成就 | A1: 行动·意志·事业·领导力 / B2: 事业 | 用户问事业 |
+| 财富 (Wealth) | 财运、天医 | A1: (散布在各区) / B2: 财富 | 用户问财富 |
+| 情感 (Emotion) | 感情、家庭、人际关系 | A1: 情感·家庭·安全感 / B2: 情感 | 用户问感情 |
+| 健康 (Health) | 身体、精神、活力 | A1: 智慧·精神 / B2: 健康 | 用户问健康 |
+| 社交 (Social) | 人脉、贵人、合作 | A1: 机遇·环境 / B2: 社交/贵人运 | 用户问人际 |
+| 天赋 (Talent) | 潜能、学习、成长 | A1: (E 类补充) / B2: 智商 | 用户问天赋 |
+
+> **推荐**: 在后续 Phase 中更新 A1 和 B2 的 frontmatter tags,统一使用上述 7 维度标签,便于 Chatflow metadata 过滤。
+
+---
+
+## 十一、位置×数字组合内容策略
+
+### 11.1 问题
+
+US-1.4 Tab 2(特征)和 Tab 3(建议)需要"该数字在该位置的具体描述"(如 O=7 代表分析力强),但当前 KB 仅分别提供:
+- A1: 位置级别含义("O 位置代表核心性格特质")
+- A2: 数字级别含义("7 号人:探索者,分析力强")
+
+### 11.2 方案:AI 自动组合(A1 + A2 交叉检索)
+
+KB 设计采用 **AI 组合策略**,而非预写 216 个 (24位置×9数字) 组合:
+
+```
+用户点击 O 位置数字 7
+    │
+    ▼
+KB 检索节点 1 (位置含义)
+    └─ tags: 位置:主性格
+    └─ chunks: O 位置的核心含义
+    │
+    ▼
+KB 检索节点 2 (数字含义)  
+    └─ tags: 数字:7
+    └─ chunks: 7 号人的性格、优势、挑战
+    │
+    ▼
+LLM 自动组合
+    └─ "O 位置代表核心性格" + "7 号人分析力强"
+    └─ → "O=7 代表追求真理的分析者"
+```
+
+### 11.3 优势
+
+| 方案 | 工作量 | 灵活性 |
+|------|--------|--------|
+| 预写 216 组合 | 极大 (216 条) | 固定,难维护 |
+| AI 组合 (A1+A2) | 极小 (7 篇文档) | 灵活,AI 可泛化 |
+
+### 11.4 Tab 3(建议)生成策略
+
+Tab 3 建议通过 LLM 基于以下 KB 内容推理生成:
+1. **A1**: 该位置的挑战和注意事项描述
+2. **A2**: 该数字的成长建议
+3. **C2**: 该位置所属五区/三组的年龄段课题
+
+LLM 将以上信息合并为 3-5 条具体建议,不依赖预写内容。
+
+### 11.5 吉凶指示 (Item 8)
+
+吉凶指示由后端基于以下规则计算,无需 KB 内容:
+- **吉星组合** (天医/延年/生气): ★★★★☆ 及以上
+- **凶星组合** (绝命/五鬼/祸害): ★★☆☆☆ 及以下
+- **中立星** (伏位/六煞): ★★★☆☆
+- 具体星级由组合的能量等级决定(需在后端 CalculatorService 实现)
+
+---
+
+## 十一A、US-1.4 位置详情面板集成设计
+
+### 11A.1 问题
+
+Section 11 描述了 AI 组合策略(A1+A2)的概念方案,但未明确以下关键设计要素:
+
+| 缺失项 | 影响 |
+|--------|------|
+| Dify 选型(Chatflow vs Workflow vs 直接 KB API) | 后端开发者不知道应创建/调用哪种 Dify 应用 |
+| API 端点设计 | 前端开发者不知道调用哪个接口获取面板内容 |
+| LLM 提示词 | Tab 2(A1+A2 合成)和 Tab 3(建议生成)的具体 prompt 未定义 |
+| 质量保障机制 | 无重试、降级、校验策略,生产环境不可靠 |
+
+本节填补上述空白,为后端开发者提供可实现的完整设计方案。
+
+### 11A.2 方案选型:Dify Workflow
+
+比较三种方案后推荐 **Dify Workflow**:
+
+| 方案 | 优点 | 缺点 | 结论 |
+|------|------|------|------|
+| **A: 扩展现有 Chatflow** | 无需新建应用 | Chatflow 为多轮对话设计;接收结构化 JSON 输出需复杂 prompt;与通用 Q&A 共享上下文易冲突 | ❌ |
+| **B: 新建 Dify Workflow** ✅ | 独立目的;结构化 JSON 输入输出;支持并行 KB 检索;清晰可控 | 需在 Dify 控制台创建新应用 | ✅ **推荐** |
+| **C: 直接 KB API + 后端组装** | 无需 Dify 应用 | 后端需两次往返(KB 检索 + LLM 调用);监控分散;实现复杂度高 | ❌ |
+
+**选择 B 的理由**:Workflow 支持并行 KB 检索节点(同时查 A1 和 A2)、输出结构化 JSON、单次 HTTP 调用即可完成全部 3 个 Tab 的内容生成,与现有 `invokeWorkflow()` 方法模式一致。
+
+### 11A.3 数据流
+
+```
+用户点击三角图 O 位置数字 7
+    │
+    ▼
+前端 POST /api/position/detail
+{ "chartRecordId": 123, "position": "O", "digit": 7 }
+    │
+    ├─ 后端:验证命盘归属 → 计算吉凶(Item 8)→ 检测相邻组合(Item 9)
+    └─ ChartController → DifyService.invokeWorkflow(inputs)
+        │
+        ▼
+    Dify Workflow "位置详情面板"
+        ├─ KB 检索 1 → A1: O 位置含义
+        ├─ KB 检索 2 → A2: 数字 7 性格特征
+        └─ LLM 生成 → JSON { tab1, tab2, tab3 }
+    │
+    ▼
+后端合并响应:
+{
+  "tab1": "主性格:代表核心性格特质、人生使命",
+  "tab2": "O=7 代表分析力强、追求真理",
+  "tab3": "1. 避免过度分析…\n2. 多与他人交流…",
+  "auspicious": "吉数 ★★★★☆",
+  "comboInfo": null  // 或 "与 X 形成 XX 组合"
+}
+```
+
+### 11A.4 Workflow 详细设计
+
+**输入变量:**
+
+| 变量 | 类型 | 必填 | 说明 | 来源 |
+|------|------|------|------|------|
+| `position_letter` | String | 是 | 位置字母 A-X | 前端传入 |
+| `position_name` | String | 是 | 中文名(如"主性格数") | 后端从 chart_data 映射 |
+| `digit` | Integer | 是 | 该位置数字 (0-9/11/22/33) | 后端从 chart_data 读取 |
+
+**KB 检索节点(并行):**
+
+| 节点 | 检索内容 | Query 模板 | Top-K |
+|------|---------|-----------|-------|
+| KB 检索 1 | A1 位置含义 | `{position_name} {position_letter} 含义 能量 公式` | 3 |
+| KB 检索 2 | A2 数字特征 | `数字 {digit} 性格 特征 优势 挑战 成长` | 3 |
+
+两个节点均使用知识库 `3ff939b3-8686-44f6-8ef5-65b1e53b55d3`,混合检索模式。在 Dify Workflow 画布中,两个检索节点并行连接至 LLM 节点。
+
+**LLM 节点:**
+
+| 参数 | 值 |
+|------|-----|
+| Model | Claude 3.5 Sonnet(同 Chatflow) |
+| Temperature | 0.5(结构化输出需稳定性) |
+| Max Tokens | 1000 |
+
+**System Prompt(精确版):**
+
+```
+你是一个数字能量学专家。请根据以下知识库内容,为命盘位置的详情面板生成内容。
+
+## 位置信息
+- 字母:{position_letter}
+- 名称:{position_name}
+- 数字:{digit}
+
+## 位置含义(来自知识库 A1)
+{position_kb_content}
+
+## 数字特征(来自知识库 A2)
+{digit_kb_content}
+
+## 任务
+请生成以下 3 项内容,以 JSON 格式返回:
+
+1. tab1(含义):该位置的核心能量含义(1-3句话)
+2. tab2(特征):数字{digit}在{position_name}位置的具体性格/运势描述。
+   必须将位置能量与数字能量自然融合,输出类似"O=7 代表分析力强、追求真理"的具体描述。
+   避免纯数字通用描述(如"7 号人是探索者"),需体现"在{position_name}位置时的独特表现"。
+3. tab3(建议):3-5条注意事项和提升建议,每条 10-30 字,具体可操作。
+
+## 输出格式
+{"tab1":"...","tab2":"...","tab3":"..."}
+
+注意:输出必须是合法 JSON,不包含 markdown 代码块标记。
+```
+
+**Workflow 示意图:**
+
+```
+  START
+   │
+   ├── KB 检索 1(A1 位置含义)
+   │
+   ├── KB 检索 2(A2 数字特征)
+   │
+   └── LLM 生成 ──→ END(JSON)
+```
+
+### 11A.5 后端 API 设计
+
+**端点:** `POST /api/position/detail`
+
+**Request:**
+```json
+{
+  "chartRecordId": 123,
+  "position": "O",
+  "digit": 7
+}
+```
+
+**Response:**
+```json
+{
+  "tab1": "主性格:代表一个人与生俱来的核心性格特质、人生使命、天赋方向",
+  "tab2": "O=7 代表分析力强、追求真理。7号能量在性格核心位置表现为深度思考者...",
+  "tab3": "1. 避免过度分析导致行动迟缓\n2. 多与他人交流想法...\n3. 注意平衡思考与实践",
+  "auspicious": "吉数 ★★★★☆",
+  "comboInfo": null
+}
+```
+
+**职责划分:**
+
+| 组件 | 职责 |
+|------|------|
+| **ChartController** | 创建端点、验证权限、获取 chart_data、映射 position_name |
+| **CalculatorService** | 计算吉凶(Item 8)、检测相邻组合(Item 9) |
+| **DifyService** | 调用 Workflow `getPositionDetail()`、解析 JSON、降级处理 |
+| **Dify Workflow** | KB 检索 + LLM 生成 3 Tab 内容 |
+| **前端** | 调用 API、渲染 3 Tab 面板 |
+
+**DifyService.java 新增方法:**
+```java
+public PositionDetailResponse getPositionDetail(String positionLetter, int digit, String positionName) {
+    if (isMockMode()) {
+        return generateMockPositionDetail(positionLetter, digit, positionName);
+    }
+    Map<String, Object> inputs = new HashMap<>();
+    inputs.put("position_letter", positionLetter);
+    inputs.put("position_name", positionName);
+    inputs.put("digit", digit);
+    try {
+        String result = invokeWorkflow(inputs, "system");
+        return parsePositionDetail(result);
+    } catch (Exception e) {
+        return generateMockPositionDetail(positionLetter, digit, positionName);
+    }
+}
+```
+
+**DTO 定义:**
+```java
+public class PositionDetailResponse {
+    public String tab1;  // 位置含义
+    public String tab2;  // 数字+位置特征
+    public String tab3;  // 建议
+}
+```
+
+### 11A.6 质量保障
+
+| 故障场景 | 处理 | 用户可见 |
+|---------|------|---------|
+| Workflow 返回非 JSON | 重试 1 次 | — |
+| 重试仍失败 | 降级为 mock(使用 NUMBER_DESC 模板) | "解读生成失败,请稍后再试" |
+| tab2 为空(AI 未融合) | 降级为 mock | "暂时无法获取特征描述" |
+| Workflow 超时 >10s | 直接降级 | "请求超时,请重试" |
+| Dify 服务 4xx/5xx | 降级为 mock | "解读服务暂时不可用" |
+
+**降级保底内容示例(Mock):**
+```java
+private PositionDetailResponse generateMockPositionDetail(
+        String position, int digit, String positionName) {
+    String digitDesc = NUMBER_DESC.getOrDefault(digit, "独特能量组合");
+    PositionDetailResponse resp = new PositionDetailResponse();
+    resp.tab1 = positionName + ":" + POSITION_CORE_MEANINGS.getOrDefault(position, "能量位置");
+    resp.tab2 = position + "=" + digit + " 代表" + digitDesc + "。";
+    resp.tab3 = "1. 了解该能量的优势和挑战\n2. 结合整体命盘综合分析\n3. 在实践中觉察能量表现";
+    return resp;
+}
+```
+
+### 11A.7 与已有机制的协作
+
+| 已有机制 | 与本方案的关系 |
+|---------|--------------|
+| **吉凶指示 (Item 8)** | 后端 CalculatorService 基于八星组合等级计算,独立于 KB 和 Workflow |
+| **相邻组合提示 (Item 9)** | 后端 CalculatorService 检测,通过 `comboInfo` 字段返回,不依赖 Dify |
+| **Tab3 可配置 (Item 10)** | Phase 2+ 管理后台可覆盖 Tab3 内容,目前由 Workflow 生成 |
+| **Chatflow 多轮问答** | 位置详情面板无记忆,每次点击独立请求,互不影响 |
+
+---
+
+## 十二、预期效果
 
-| 指标 | 当前 | 优化后(预期) |
-|------|------|---------------|
+| 指标 | 当前 (Phase B) | 优化后(Phase C 预期) |
+|------|---------------|----------------------|
 | AI 解读深度 | 依赖 system prompt 内置知识 + 少量 KB 检索 | 分维度精准 KB 检索 + 结构化推理 |
 | 幻觉率 | 中(LLM 依赖内部知识,可能编造组合含义) | 低(每次解读引用 KB 中的具体规则) |
 | 解读个性化 | 中(基于 chart_data 但缺乏深度) | 高(24 位置 + 组合对 + 维度交叉分析) |
-| US-1.4 覆盖 | ❌ 无 24 位置含义数据源 | ✅ 面板可直接展示每个位置含义 |
-| 知识库利用率 | 低(21 篇文章但 AI 不擅长同时检索多篇) | 高(按维度分次检索,精准命中) |
+| US-1.4 覆盖 | ✅ 28 篇 KB 覆盖所有位置含义 | ✅ 面板可直接展示每个位置含义 |
+| 知识库利用率 | 高 — 21 条查询双模式 100% 通过 | 更高 — 分维度多次检索,精准命中 |
 
 ---
 
-## 十、关键决策记录
+## 十、关键决策记录
 
 | 决策项 | 选择 | 替代方案 | 理由 |
 |--------|------|---------|------|
@@ -428,3 +786,5 @@ Dify v1.11.4 支持文档级 metadata,可在 Workflow 中通过 `knowledge_fil
 | 文档拆分粒度 | **~300-500 行/篇** | 1000+ 行大文档 | 适中粒度:减少 RAG 噪音又不至于碎片化 |
 | Metadata 方案 | **YAML tags** | Dify 控制台手动标签 | 标签随文档同步,版本可追溯 |
 | 现有文档处理 | **保留 + 新增 + 重构** | 全部推倒重来 | 现有 21 篇有价值内容,直接删除浪费资源 |
+| Top-K | **10** (需控制台配置) | 6 (当前, API不可改) | Dify v1.11.4 API 对 `retrieval_model_dict.top_k` 的更改返回200但实际不生效。需在 Dify 控制台 → 数据集设置 → 检索设置 手动修改 |
+| Rerank 配置 | **需 Dify 控制台配置** | 无 rerank (当前) | 当前 rerank 模型为 null,配置后(如 BAAI/bge-reranker-v2-m3)可显著缓解关键词偏差。同样是控制台操作 |

+ 184 - 0
knowledge/research/D1生命数1组合递进能量.md

@@ -0,0 +1,184 @@
+---
+title: D1 生命数1组合递进能量
+tags:
+  - 位置:主性格
+  - 生命数1
+  - 组合递进
+  - 优先级:P1
+  - 用途:参考
+date: 2026-05-31
+confidence: medium
+---
+
+# 生命数1组合递进能量解析
+
+> 本文档整合 生命数1 的四种核心组合(10/1、28/10/1、37/10/1、46/10/1),展示同一生命数下不同组合的能量演变路径与递进关系。
+
+---
+
+## 一、组合总览与递进关系
+
+生命数1的核心能量通过不同组合呈现出差异化的领袖风格。四种组合共同遵循 **"基底→递进→回归"** 的三阶段模式,但各有侧重:
+
+| 组合 | 核心主题 | 驱动类型 | 递进路径 |
+|------|----------|----------|----------|
+| **10/1** | 独立与付出 | 独立驱动 | 独立主导 → 付出矛盾 → 领袖担当 |
+| **28/10/1** | 合作与洞察 | 合作驱动 | 合作洞察 → 价值整合 → 领袖绽放 |
+| **37/10/1** | 创意与灵感 | 灵感驱动 | 灵感碰撞 → 价值整合 → 领袖绽放 |
+| **46/10/1** | 务实与关怀 | 务实驱动 | 务实关怀 → 价值整合 → 领袖担当 |
+
+**共同递进模式:**
+
+```
+第一阶段(组合期):初始张力 —— 两种能量的碰撞与矛盾
+第二阶段(整合期):10的能量   —— 筛选核心方向,包容差异
+第三阶段(绽放期):1的能量    —— 独立主导,成果落地
+```
+
+---
+
+## 二、10/1组合:独立与付出的内在矛盾
+
+### 2.1 原生特性:天生领袖的"非黑即白"能量基底
+
+10/1的原生能量以"独立主导"为核心,自带天生领袖气质:
+
+- **行动与决策**:精力充沛且自动自发,面对目标时行动力极强,不依赖他人推动;思考模式非黑即白,能快速做决定,避免犹豫内耗,但也易因"极端化判断"忽略中间选项。
+- **沟通与需求**:外向积极,乐于主动表达主张,反感"拐弯抹角"的沟通方式;内心渴望"被认可决策权",若自身主张被否定,易产生挫败感或抵触情绪。
+
+### 2.2 组合特性:独立与付出的内在矛盾
+
+"10/1"的数字组合形成双重性格张力:
+
+- **外在vs内在**:对外展现出独立、坚强的"领袖姿态";但内在藏着细腻体贴的一面,渴望为身边人付出。
+- **矛盾带来的内耗**:当付出未被认可时失落,当坚持主导时又因忽略他人感受而愧疚。
+
+### 2.3 原生家庭成长特性
+
+多数10/1从小被家庭赋予"独立、懂事"的隐性期待,逐渐将"独立"等同于"被认可的条件":
+- **主动承担型**:主动帮父母分担,用"解决问题"证明自身价值
+- **情感压抑型**:付出未被看见时选择"更努力做事"或"刻意疏远"
+- **长期影响**:成年后与家人互动时,易陷入"要么主导一切,要么冷战式独立"的极端
+
+### 2.4 生命树象征特性
+
+如同生命树的"顶端主干"——为家庭、团队提供方向感与动力。需要"情感滋养",若只被依赖而不被认可,长期会出现能量耗竭。
+
+### 2.5 关键提醒:警惕"打压式指责"对自信的消解
+
+若父母长期用打压式语言否定其尝试,会击碎他们对"独立价值"的认知,成年后出现自信缺失、不敢争取主导权、习惯性压抑付出本能。
+
+---
+
+## 三、28/10/1组合:合作洞察驱动领袖力
+
+### 3.1 原生特性:自带"合作基因"的创新型领袖基底
+
+- **行动与决策**:行动力带着"合作驱动"的特质,善于借助团队力量,能从不同视角获取灵感。决策时既果断,又会通过全面分析来验证方案的可行性。
+- **沟通与需求**:善于用"合作式表达"传递主张,能很好地倾听他人意见。既渴望合作成果被认可,也期待自身价值被看见。
+
+### 3.2 组合递进特性
+
+- **第一阶段(28合作洞察期)**:2的合作精神与8的深度洞察形成张力,既有丰富合作想法,又因过度考虑各方利益而犹豫。
+- **第二阶段(10价值整合期)**:筛选核心合作方向,包容过程中的差异。
+- **第三阶段(1领袖绽放期)**:独立主导成为合作成果落地的推动力。
+
+### 3.3 原生家庭成长特性
+
+- 从小展现出"合作天赋",但家人可能强调"务实"
+- **合作隐藏型**:在家人面前收敛合作式创意表达
+- **务实合作型**:尝试将合作与现实需求结合
+- **长期影响**:容易陷入"合作压抑"与"自我证明"的循环
+
+### 3.4 生命树象征特性
+
+如同"合作型主干",能通过合作启发团队活力。需要"认可与空间"双重养分。
+
+### 3.5 关键提醒:警惕"务实绑架"对合作能量的消耗
+
+若父母长期用"不切实际"否定其合作天赋,会导致成年后要么彻底放弃合作,要么极端追求合作而不顾现实。
+
+---
+
+## 四、37/10/1组合:创意灵感驱动领袖力
+
+### 4.1 原生特性:自带"灵感基因"的创新型领袖基底
+
+- **行动与决策**:行动力带着"灵感驱动"的特质,总能跳出常规想新方法。决策时既果断,又会通过深度思考验证可行性。
+- **沟通与需求**:善于用"创意表达"传递主张,能快速调动他人情绪。既渴望创意被认可,也期待深层价值被看见。
+
+### 4.2 组合递进特性
+
+- **第一阶段(37灵感碰撞期)**:3的活跃创意与7的深度洞察形成张力——想法多但落地少。
+- **第二阶段(10价值整合期)**:筛选核心创意,包容过程差异。
+- **第三阶段(1领袖绽放期)**:独立主导推动创意落地,成为"懂创意、能落地"的领袖。
+
+### 4.3 原生家庭成长特性
+
+- 从小展现创意天赋,但被要求"务实"
+- **天赋隐藏型**:在家人面前收敛创意表达,私下维持灵感活力
+- **务实转化型**:用现实价值包装创意追求
+- **长期影响**:陷入"天赋压抑"与"自我证明"的循环
+
+### 4.4 生命树象征特性
+
+如同"创意型主干",兼具力量与灵动性。需要"认可与空间"双重养分。
+
+### 4.5 关键提醒:警惕"务实绑架"对创意能量的消耗
+
+若父母长期否定其创意天赋,会导致成年后要么彻底放弃创意,要么极端追求创意而不顾现实条件。
+
+---
+
+## 五、46/10/1组合:务实组织驱动领袖力
+
+### 5.1 原生特性:自带"务实奉献"的稳健型领袖基底
+
+- **行动与决策**:行动力带有"务实驱动"的特质,善于从实际经验中获取灵感。决策时谨慎,全面评估各种因素。
+- **沟通与需求**:善于用"关怀式表达"传递主张,能真诚关心他人。既渴望通过帮助他人实现价值,也期待自身努力被认可。
+
+### 5.2 组合递进特性
+
+- **第一阶段(46务实关怀期)**:4的务实精神与6的人文关怀形成张力——想法集中于实际需求,但担心计划不完善。
+- **第二阶段(10价值整合期)**:筛选核心目标,包容不完美。
+- **第三阶段(1领袖绽放期)**:独立主导推动务实成果落地和他人价值实现。
+
+### 5.3 原生家庭成长特性
+
+- 从小展现"务实和关怀他人"的天赋,被要求"脚踏实地"
+- **务实隐藏型**:收敛关怀式表达,私下满足关怀需求
+- **情感务实型**:将关怀与现实目标结合
+- **长期影响**:易陷入"过度付出"与"自我牺牲"的循环
+
+### 5.4 生命树象征特性
+
+如同"务实型主干",通过务实的行动和关怀启发团队凝聚力。需要"认可与信任"双重养分。
+
+### 5.5 关键提醒:警惕"情感绑架"对务实能量的消耗
+
+若父母长期用"不懂事"否定其付出,会导致成年后要么彻底放弃务实,要么过度务实而忽视自己。
+
+---
+
+## 六、四种组合对比
+
+| 维度 | 10/1 | 28/10/1 | 37/10/1 | 46/10/1 |
+|------|------|---------|---------|---------|
+| **核心能量** | 独立主导 | 合作洞察 | 创意灵感 | 务实关怀 |
+| **驱动类型** | 独立驱动 | 合作驱动 | 灵感驱动 | 务实驱动 |
+| **优势** | 果断自信、行动力强 | 善于合作、分析力强 | 创意丰富、洞察力深 | 务实可靠、关怀他人 |
+| **风险** | 非黑即白、易内耗 | 过度顾虑、犹豫不决 | 想法多落地少 | 过度付出、自我牺牲 |
+| **需警惕** | 打压式指责 | 务实绑架 | 务实绑架 | 情感绑架 |
+| **成年后极端** | 自信缺失 vs 控制欲 | 彻底放弃合作 vs 盲目合作 | 放弃创意 vs 不顾现实 | 放弃务实 vs 过度务实 |
+| **关键需求** | 决策被认可 | 合作被接纳 | 创意被肯定 | 付出被看见 |
+
+---
+
+## 七、使用说明
+
+本文档适用于以下场景:
+
+- **AI 解读**:当用户的生命数1组合为特定类型时,检索对应的组合特性
+- **对比分析**:比较不同组合的差异,理解同一生命数下的多样化表现
+- **原生家庭洞察**:结合原生家庭成长特性,给出更具针对性的成长建议
+- **个人成长**:识别自身组合类型,了解核心能量特质与潜在风险

+ 9 - 7
knowledge/research/数字能量学知识体系总纲.md

@@ -21,7 +21,8 @@ confidence: high
 
 | 文档 | 描述 | 关联 |
 |------|------|------|
-| [生命灵数1-9号性格解析](./生命灵数1-9号性格解析.md) | 1~9号人的完整性格特征、天赋潜能、人生课题、职业方向 | → 所有进阶文档的基础 |
+| [A2 主性格数字1-9及卓越数深度解读](./A2主性格数字深度解读.md) | 1~9号人+卓越数11/22/33的完整性格特征、天赋潜能、人生课题、职业方向 | → 所有进阶文档的基础 |
+| [E 天赋数空缺数与数字能量关联](./E天赋数空缺数与数字关联.md) | 天赋数含义速览、空缺数挑战领域、相邻数字互补与对立关系 | → 生命灵数九宫格解析 → 生命数组合递进能量 |
 
 **作用**:看懂命盘的第一步——理解每个人"出厂设置"的核心数字能量。
 
@@ -65,12 +66,13 @@ confidence: high
 
 生命数1的组合能量递进系列,展示同一生命数下不同组合的能量演变路径:
 
-| 文档 | 组合 | 核心主题 | 递进关系 |
-|------|------|----------|----------|
-| [生命数1的10/1组合能量特质](./生命数1的10-1组合能量特质.md) | 10/1 | 独立与付出的内在矛盾基础 | ← 起点:最基础的1号组合 |
-| [生命数1的28/10/1组合能量特质](./生命数1的28-10-1组合能量特质.md) | 28/10/1 | 合作洞察驱动领袖力 | ← 在10/1基础上叠加2+8的合作洞察 |
-| [生命数1的37/10/1组合能量特质](./生命数1的37-10-1组合能量特质.md) | 37/10/1 | 创意灵感驱动领袖力 | ← 在10/1基础上叠加3+7的创意洞察 |
-| [生命数1的46/10/1组合能量特质](./生命数1的46-10-1组合能量特质.md) | 46-10-1 | (张圣甜原文)务实组织驱动 | ← 在10/1基础上叠加4+6的务实组织 |
+| 文档 | 说明 | 关联 |
+|------|------|------|
+| [D1 生命数1组合递进能量](./D1生命数1组合递进能量.md) | 四种组合(10/1、28/10/1、37/10/1、46/10/1)统一解析,含对比表 | → AI 检索统一入口 |
+| [生命数1的10/1组合能量特质](./生命数1的10-1组合能量特质.md) | 10/1:独立与付出的内在矛盾基础 | 原文档保留 |
+| [生命数1的28/10/1组合能量特质](./生命数1的28-10-1组合能量特质.md) | 28/10/1:合作洞察驱动领袖力 | 原文档保留 |
+| [生命数1的37/10/1组合能量特质](./生命数1的37-10-1组合能量特质.md) | 37/10/1:创意灵感驱动领袖力 | 原文档保留 |
+| [生命数1的46/10/1组合能量特质](./生命数1的46-10-1组合能量特质.md) | 46-10-1:务实组织驱动 | 原文档保留 |
 
 **共同结构**:每篇文档均按"原生特性 → 组合递进(三阶段) → 原生家庭 → 生命象征 → 关键提醒"五维度解析。
 

BIN
knowledge/scripts/__pycache__/local_retriever.cpython-311.pyc


+ 60 - 0
knowledge/scripts/audit_metadata.py

@@ -0,0 +1,60 @@
+"""Audit metadata consistency across all knowledge documents."""
+import os
+
+docs_dir = r'E:\workspace\dan\num\knowledge\research'
+results = []
+for f in sorted(os.listdir(docs_dir)):
+    if not f.endswith('.md'):
+        continue
+    path = os.path.join(docs_dir, f)
+    content = open(path, 'r', encoding='utf-8').read()
+    lines = content.split('\n')
+    
+    # Check frontmatter
+    has_frontmatter = content.startswith('---')
+    if not has_frontmatter:
+        results.append((f, 'NO_FRONTMATTER'))
+        continue
+    
+    # Parse frontmatter
+    in_frontmatter = False
+    tags = []
+    title = ''
+    confidence = ''
+    has_tags = False
+    for line in lines[:40]:
+        if line.strip() == '---':
+            in_frontmatter = not in_frontmatter
+            continue
+        if in_frontmatter:
+            if line.startswith('title:'):
+                title = line.replace('title:', '').strip().strip('"').strip("'")
+            elif line.startswith('confidence:'):
+                confidence = line.split(':')[1].strip()
+            elif line.startswith('tags:'):
+                has_tags = True
+            elif line.strip().startswith('- ') and in_frontmatter:
+                tags.append(line.strip().lstrip('- ').strip())
+    
+    file_size = os.path.getsize(path)
+    line_count = len(lines)
+    
+    # Determine which layer (A/B/C/D/E/other) the doc belongs to
+    layer = 'OTHER'
+    if f.startswith('A') or '命盘24位置' in f:
+        layer = 'A'
+    elif f.startswith('B') or '八星' in f or '联合密码' in f or '三角命盘组合' in f:
+        layer = 'B'
+    elif f.startswith('C') or '维度手册' in f or '五区三组' in f or '数字0与5' in f:
+        layer = 'C'
+    elif f.startswith('D') or '递进' in f or '组合能量' in f:
+        layer = 'D'
+    elif f.startswith('E') or '天赋数' in f:
+        layer = 'E'
+    
+    print(f'{layer} | {f:40s} | tags={len(tags):2d} | conf={confidence:8s} | {line_count:4d}行 | {file_size:6d}B')
+    
+    if not has_tags:
+        print(f'  >>> WARNING: No tags found in {f}')
+    if not confidence:
+        print(f'  >>> WARNING: No confidence in {f}')

+ 19 - 0
knowledge/scripts/check_dify_config.py

@@ -0,0 +1,19 @@
+"""Verify Dify KB configuration"""
+import requests, json
+
+api_key = 'dataset-xsT85hlYqhXcudorohrokWGo'
+base_url = 'http://dify.bianwoyou.cn'
+dataset_id = '3ff939b3-8686-44f6-8ef5-65b1e53b55d3'
+headers = {'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json'}
+
+resp = requests.get(f'{base_url}/v1/datasets/{dataset_id}', headers=headers, timeout=15)
+info = resp.json()
+rm = info.get('retrieval_model_dict', {})
+
+print(f'KB Name: {info.get("name")}')
+print(f'Documents: {info.get("document_count")}')
+print(f'Words: {info.get("word_count", "?")}')
+print(f'Search: {rm.get("search_method")}')
+print(f'Top-K: {rm.get("top_k")}')
+print(f'Rerank: enabled={rm.get("reranking_enable")} model={rm.get("reranking_model", {}).get("reranking_model_name", "null")}')
+print(f'Threshold: enabled={rm.get("score_threshold_enabled")} value={rm.get("score_threshold")}')

+ 18 - 0
knowledge/scripts/final_audit.py

@@ -0,0 +1,18 @@
+"""Final KB audit - doc count, frontmatter, sizes"""
+import os
+
+d = r'E:\workspace\dan\num\knowledge\research'
+files = sorted([f for f in os.listdir(d) if f.endswith('.md')])
+print(f'Total .md files: {len(files)}')
+print()
+
+# Count words across all files
+total_words = 0
+for f in files:
+    content = open(os.path.join(d, f), 'r', encoding='utf-8').read()
+    wc = len(content.split())
+    total_words += wc
+    lines = len(content.split('\n'))
+    has_fm = content.startswith('---')
+    print(f'  {wc:6d}w {lines:4d}L {"FM" if has_fm else "  "} | {f}')
+print(f'\nTotal: {total_words} words across {len(files)} files')

+ 16 - 2
knowledge/scripts/test_rag_retrieval.py

@@ -39,8 +39,22 @@ TEST_QUERIES = [
     ("zone", "左侧组年龄段和人生课题", "五区", "C2"),
     ("zone", "五区和三组的交叉分析", "五区", "C2"),
 
-    # Type 5: Comprehensive
-    ("comprehensive", "主性格6号人的感情事业特点", "维度", "C1"),
+    # Type 5: Main Character Personality -> should retrieve A2 (主性格深度解读)
+    ("personality", "7号人深度解读:性格特征的全面分析", "A2", "A2"),
+    ("personality", "卓越数11的直觉力和人生课题", "A2", "A2"),
+    ("personality", "3号人的适合职业和情感模式", "A2", "A2"),
+
+    # Type 6: Supplementary knowledge -> should retrieve E (天赋数空缺数)
+    ("supplement", "天赋数的含义速查表和计算方法", "E天赋", "E"),
+    ("supplement", "空缺数代表什么挑战领域", "E天赋", "E"),
+    ("supplement", "天赋数的含义和空缺数的挑战领域", "E天赋", "E"),
+
+    # Type 7: Progressive energy -> should retrieve D1 (生命数1组合递进能量)
+    ("progression", "生命数1的28-10-1组合递进三阶段", "D1", "D1"),
+    ("progression", "46-10-1组合的务实关怀特性", "D1", "D1"),
+
+    # Type 8: Comprehensive (now targets A2 specifically for main character)
+    ("comprehensive", "主性格6号人的感情和事业特点", "A2", "A2"),
 ]