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

Merge branch 'main' of https://git.yishihui.com/howard/Agent

guantao 1 день назад
Родитель
Сommit
697ab1c3a3

+ 0 - 0
knowhub/docs/knowledge/00_research_plan.md → knowhub/docs/archive/knowledge/00_research_plan.md


+ 0 - 0
knowhub/docs/knowledge/01_mcp_ecosystem.md → knowhub/docs/archive/knowledge/01_mcp_ecosystem.md


+ 0 - 0
knowhub/docs/knowledge/02_agent_skills_ecosystem.md → knowhub/docs/archive/knowledge/02_agent_skills_ecosystem.md


+ 0 - 0
knowhub/docs/knowledge/03_discovery_channels.md → knowhub/docs/archive/knowledge/03_discovery_channels.md


+ 0 - 0
knowhub/docs/knowledge/04_top_mcp_curated.md → knowhub/docs/archive/knowledge/04_top_mcp_curated.md


+ 0 - 0
knowhub/docs/knowledge/05_final_report.md → knowhub/docs/archive/knowledge/05_final_report.md


+ 0 - 0
knowhub/docs/openclaw_integration.md → knowhub/docs/archive/openclaw/openclaw_integration.md


+ 0 - 0
knowhub/docs/openclaw_plugin_design.md → knowhub/docs/archive/openclaw/openclaw_plugin_design.md


+ 86 - 0
knowhub/docs/decisions.md

@@ -377,3 +377,89 @@ async def llm_rerank(query: str, candidates: List[dict], top_k: int):
 1. 从 SQLite 迁移需要一次性工作
 2. Milvus Lite 的标量查询不如 SQL 灵活(但够用)
 3. 存储空间增加(向量数据)
+
+---
+
+## 14. 知识去重机制:保存时关系判断
+
+**日期**:2026-03-25
+
+**背景**:知识库存在重复知识累积问题,导致检索质量下降和存储浪费。
+
+**决策**:采用保存时关系判断机制(已实现)
+
+**核心机制**:
+1. **向量召回**:检索 top-10 相似知识(status=approved/checked)
+2. **相似度预过滤**:过滤 COSINE score < 0.75 的候选
+3. **LLM 关系判断**:使用 LLM 判断关系类型和处理动作
+
+**关系类型**:
+- `duplicate`:完全重复 → 新知识 rejected,旧知识 helpful+1
+- `subset`:新知识被旧知识覆盖 → 新知识 rejected
+- `superset`:新知识更全面 → 两条都 approved,建立关系
+- `conflict`:结论矛盾 → 两条都 approved,标记冲突
+- `complement`:互补 → 两条都 approved,建立关系
+- `none`:无关系 → 直接 approved
+
+**数据结构**:
+- `status` 字段:pending/processing/approved/checked/rejected
+- `relationships` 字段:记录与其他知识的关系(双向写入)
+- 关系缓存表:独立存储,按关系类型索引知识 ID
+
+**成本**:约 $0.15/年(假设每天保存 50 条知识,10% 需要 LLM 判断)
+
+**实现位置**:
+- `knowhub/vector_store.py` - status/relationships 字段
+- `knowhub/server.py:KnowledgeProcessor` - 异步处理器
+- `knowhub/server.py:_llm_judge_relations` - LLM 关系判断
+
+**文档**:`knowhub/docs/dedup-design.md`
+
+---
+
+## 15. 知识反馈时机:自动评估机制
+
+**日期**:2026-03-25
+
+**背景**:知识注入后缺少使用状态追踪和评估反馈,无法判断知识的实际效果。
+
+**决策**:采用自动评估机制(已实现)
+
+**核心机制**:
+1. **知识注入日志**:每个 trace 维护 `knowledge_log.json`,记录注入的知识
+2. **三个触发点**:
+   - Goal 完成(completed/abandoned)
+   - 压缩前(必须先评估,否则上下文丢失)
+   - 任务结束(兜底)
+3. **侧分支评估**:使用 `knowledge_eval` 侧分支,LLM 直接输出 JSON 评估结果
+4. **即时写入**:每次 LLM 回复后立即解析并写入评估结果
+
+**评估分类**:
+- `irrelevant`:知识与任务无关
+- `unused`:相关但未使用
+- `helpful`:有实质帮助
+- `harmful`:产生负面作用
+- `neutral`:无明显影响
+
+**数据结构**:
+```json
+{
+  "knowledge_id": "...",
+  "goal_id": "...",
+  "injected_at_sequence": 42,
+  "eval_result": {
+    "eval_status": "helpful",
+    "reason": "..."
+  },
+  "evaluated_at_trigger": "goal_completion"
+}
+```
+
+**实现位置**:
+- `agent/trace/goal_tool.py:inject_knowledge_for_goal` - 写入日志
+- `agent/trace/store.py:update_goal` - Goal 完成触发
+- `agent/core/runner.py:_manage_context_usage` - 压缩前触发
+- `agent/core/runner.py:_agent_loop` - 任务结束触发
+- `agent/trace/store.py` - 日志管理
+
+**文档**:`knowhub/docs/feedback-timing-design.md`

+ 0 - 678
knowhub/docs/feedback-optimization-proposal.md

@@ -1,678 +0,0 @@
-# 知识库反馈与管理机制优化提案
-
-> 本文档记录知识库反馈机制和规模管理的优化方案
->
-> 讨论日期:2026-03-17
-> 状态:提案阶段,待审阅后实施
-
----
-
-## 一、背景与问题
-
-### 1.1 当前反馈机制
-
-**现有结构**:
-- `eval` 字段:score (1-5), helpful/harmful 计数, confidence, 历史记录
-- 工具:`knowledge_update`, `knowledge_batch_update`
-- 应用:`min_score` 过滤、知识进化(`evolve_feedback`)
-
-**存在的问题**:
-1. 反馈来源不区分(人类、Agent、任务结果混在一起)
-2. 评分更新逻辑简单(手动设置,未根据反馈历史自动调整)
-3. 缺少隐式反馈(使用频率、检索排名等)
-4. 缺少时间衰减机制(旧知识可能过时)
-
-### 1.2 规模控制问题
-
-**现有 slim 机制的问题**:
-- 一次性加载 10000 条知识到内存
-- 单次 LLM 调用处理全部(成本高 $1-5/次,质量差)
-- 每条只截取前 200 字符,信息不完整
-
-**知识库膨胀原因**:
-1. 重复提取:相似任务多次执行,每次都提取"新"知识
-2. 粒度不一致:同一经验被拆成多条或合并成粗粒度
-3. 版本演化:知识更新时创建新版本而非覆盖旧版本
-4. 低质量沉积:score=3 的"中等"知识大量累积
-
----
-
-## 二、核心优化方案
-
-### 2.1 保存时关系判断(P0 核心机制)
-
-#### 知识关系类型
-
-| 关系类型 | 说明 | 处理策略 |
-|---------|------|---------|
-| `duplicate` | 完全重复,只是表述略有差异 | 跳过保存 |
-| `subset` | 新知识是已有知识的特例或部分 | 跳过保存,或作为案例添加 |
-| `superset` | 新知识更全面,包含已有知识 | 保存新知识,废弃旧知识 |
-| `conflict` | 两条知识给出矛盾的建议 | 保存但标记冲突,需要人工审核 |
-| `complement` | 相关但不重复,可以互相补充 | 保存并建立关联关系 |
-| `independent` | 两条知识无关 | 直接保存 |
-
-#### 分层判断策略(降低成本)
-
-```
-Layer 1: 向量相似度检索(快速过滤)
-  ↓ 无相似知识 → 直接保存
-  ↓ 有相似知识
-Layer 2: 规则判断(免费)
-  - task 完全相同 + content 重叠 > 90% → 跳过
-  - content 完全相同 → 跳过
-  ↓ 规则无法判断
-Layer 3: LLM 判断(仅处理边界情况)
-  - 相似度 > 0.85 时才调用
-  - 使用 gemini-2.5-flash-lite
-```
-
-**成本估算**:
-- 假设每天保存 50 条知识
-- Layer 1 过滤 70%,Layer 2 过滤 20%,Layer 3 处理 10%
-- 每次 LLM 调用:1100 tokens
-- 年成本:50 × 10% × 1100 tokens × 365 天 ≈ **$0.15/年**
-
-#### 实现位置
-
-- `agent/tools/builtin/knowledge.py:knowledge_save` - 保存前检查
-- `knowhub/server.py:analyze_knowledge_relation` - 关系分析
-- `knowhub/server.py:handle_knowledge_relation` - 关系处理
-
----
-
-### 2.2 反馈来源区分与加权评分(P0)
-
-#### 数据结构变更
-
-```python
-{
-  "eval": {
-    "score": 4.2,  # 加权综合评分(自动计算)
-    "confidence": 0.9,
-
-    # 分来源统计
-    "feedback_by_source": {
-      "human": {
-        "helpful": 3,
-        "harmful": 0,
-        "weight": 1.0,  # 权重最高
-        "last_feedback": "2026-03-17"
-      },
-      "agent_explicit": {
-        "helpful": 12,
-        "harmful": 2,
-        "weight": 0.6,  # 中等权重
-        "last_feedback": "2026-03-17"
-      },
-      "task_outcome": {
-        "success": 45,
-        "failure": 5,
-        "weight": 0.3,  # 权重最低(归因不明确)
-        "last_feedback": "2026-03-17"
-      }
-    },
-
-    # 详细历史(保留来源标记)
-    "feedback_history": [
-      {
-        "source": "human",
-        "type": "helpful",
-        "comment": "非常准确",
-        "timestamp": "2026-03-17",
-        "user_id": "user@example.com"
-      }
-    ]
-  }
-}
-```
-
-#### 加权评分算法
-
-```python
-def calculate_weighted_score(feedback_by_source):
-    """根据来源加权计算综合评分"""
-
-    total_weight = 0
-    weighted_sum = 0
-
-    for source, data in feedback_by_source.items():
-        helpful = data["helpful"]
-        harmful = data["harmful"]
-        weight = data["weight"]
-
-        if helpful + harmful == 0:
-            continue
-
-        # 正向率
-        positive_ratio = helpful / (helpful + harmful)
-
-        # 置信度:反馈次数越多越可信(上限10次)
-        confidence = min(1.0, (helpful + harmful) / 10)
-
-        # 该来源的得分:3 + 2 * (正向率 - 0.5)
-        source_score = 3 + 2 * (positive_ratio - 0.5)
-
-        # 加权累加
-        weighted_sum += source_score * weight * confidence
-        total_weight += weight * confidence
-
-    return max(1.0, min(5.0, weighted_sum / total_weight)) if total_weight > 0 else 3.0
-```
-
-#### 实现位置
-
-- `knowhub/server.py:update_knowledge` - 更新评分逻辑
-- `knowhub/server.py:calculate_weighted_score` - 评分计算
-- `agent/tools/builtin/knowledge.py:knowledge_feedback` - 新增人类反馈工具
-
----
-
-### 2.3 分层存储(P0 必需)
-
-#### 知识状态机
-
-```
-active(活跃)→ stable(稳定)→ cold(冷藏)→ archived(归档)
-                                    ↓
-                              deprecated(废弃)
-```
-
-#### 状态转换规则
-
-```python
-def calculate_state(knowledge):
-    days_since_last_use = (now - knowledge["last_used"]).days
-    usage_count = knowledge["implicit_feedback"]["search_count"]
-
-    if days_since_last_use > 180 and usage_count < 5:
-        return "archived"  # 半年未用且使用少 → 归档
-    elif days_since_last_use > 90:
-        return "cold"      # 3个月未用 → 冷藏
-    elif usage_count > 20:
-        return "active"    # 使用频繁 → 活跃
-    else:
-        return "stable"    # 默认稳定
-```
-
-#### 检索策略
-
-- 默认只检索 `active` + `stable`
-- 可选参数 `include_cold=true` 扩展到冷藏知识
-- `archived` 和 `deprecated` 不参与检索,但可通过 ID 访问
-
-#### 数据结构
-
-```python
-{
-  "state": "active",  # active/stable/cold/archived/deprecated
-  "state_reason": "",  # 状态变更原因
-  "state_updated_at": "2026-03-17T12:00:00Z"
-}
-```
-
-#### 实现位置
-
-- `knowhub/server.py:update_knowledge_states` - 后台任务,每天更新
-- `knowhub/server.py:search_knowledge_api` - 检索时过滤状态
-- `knowhub/vector_store.py` - Milvus 查询添加状态过滤
-
----
-
-### 2.4 质量淘汰(P0 必需)
-
-#### 淘汰条件
-
-- `score < 2`
-- `harmful > helpful`
-- 存在超过 30 天
-
-#### 操作
-
-标记为 `deprecated`,不直接删除(可恢复)
-
-#### 实现
-
-```python
-async def prune_low_quality():
-    """定期清理低质量知识"""
-
-    low_quality = milvus_store.query(
-        filter_expr='eval["score"] < 2 and eval["harmful"] > eval["helpful"]'
-    )
-
-    for k in low_quality:
-        age_days = (now - k["created_at"]).days
-        if age_days > 30:
-            await knowledge_update(
-                knowledge_id=k["id"],
-                metadata={
-                    "state": "deprecated",
-                    "state_reason": "low_quality",
-                    "deprecated_at": now
-                }
-            )
-```
-
-#### 实现位置
-
-- `knowhub/server.py:prune_low_quality` - 后台任务,每天执行
-
----
-
-### 2.5 知识关系网络(P0)
-
-#### 数据结构
-
-```python
-{
-  "relations": [
-    {
-      "target_id": "knowledge-20260310-c3d4",
-      "relation_type": "complement",  # duplicate/subset/superset/conflict/complement
-      "direction": "bidirectional",   # bidirectional/outgoing/incoming
-      "confidence": 0.95,
-      "reason": "两条知识互补,分别覆盖不同场景",
-      "created_at": "2026-03-17T12:00:00Z",
-      "created_by": "system",  # system/human/agent
-      "action_taken": ""  # 可选:deprecated_target/merged/etc
-    }
-  ]
-}
-```
-
-#### 关系方向说明
-
-| 关系类型 | 方向性 | 说明 |
-|---------|--------|------|
-| `complement` | 双向 | 互补关系,建立双向链接 |
-| `duplicate` | 双向 | 完全重复 |
-| `subset` | 单向 | 本知识是目标的子集 |
-| `superset` | 单向 | 本知识是目标的超集 |
-| `conflict` | 双向 | 冲突关系 |
-
-#### 实现位置
-
-- `knowhub/server.py:create_knowledge_link` - 创建关系链接
-- `knowhub/server.py:get_related_knowledge` - 查询相关知识
-
----
-
-### 2.6 轻量级健康检查(P1 推荐)
-
-#### 目的
-
-检测保存时去重的漏判(兜底机制)
-
-#### 策略
-
-```python
-async def weekly_health_check():
-    """每周检查新增知识的重复情况"""
-
-    # 只检查最近7天新增的知识
-    recent = query(filter=f'created_at > "{seven_days_ago}"')
-
-    if len(recent) < 10:
-        return  # 新增太少,不值得检查
-
-    # 使用向量聚类检测明显重复(阈值 0.90)
-    clusters = await cluster_similar_knowledge(
-        knowledge_list=recent,
-        threshold=0.90
-    )
-
-    # 只报告,不自动处理
-    if clusters:
-        send_alert(f"发现 {len(clusters)} 组疑似重复,请人工审核")
-```
-
-#### 成本
-
-几乎为 0(只用向量聚类,不调用 LLM)
-
-#### 实现位置
-
-- `knowhub/server.py:weekly_health_check` - 后台任务,每周执行
-
----
-
-## 三、可选优化(P2)
-
-### 3.1 隐式反馈收集
-
-```python
-{
-  "implicit_feedback": {
-    "search_count": 156,      # 被检索次数
-    "click_count": 89,        # 被选中使用次数
-    "last_used": "2026-03-17",
-    "avg_rank": 2.3           # 平均检索排名
-  }
-}
-```
-
-**实现位置**:`knowhub/server.py:search_knowledge_api` - 返回结果时记录
-
-### 3.2 时间衰减机制
-
-```python
-def apply_time_decay(knowledge, current_time):
-    age_days = (current_time - knowledge["created_at"]).days
-
-    # 6个月后开始衰减,1年后降至50%
-    if age_days > 180:
-        decay_factor = max(0.5, 1 - (age_days - 180) / 365)
-        knowledge["_search_score"] *= decay_factor
-
-    return knowledge
-```
-
-**实现位置**:`knowhub/server.py:_llm_rerank` - 精排前应用衰减
-
-### 3.3 多维度反馈
-
-```python
-{
-  "eval": {
-    "dimensions": {
-      "accuracy": 5,      # 准确性
-      "completeness": 4,  # 完整性
-      "clarity": 4,       # 清晰度
-      "timeliness": 3     # 时效性
-    }
-  }
-}
-```
-
-### 3.4 归因置信度
-
-对于任务成功/失败反馈,计算"这个结果有多大程度归因于该知识":
-
-```python
-async def calculate_attribution_confidence(
-    knowledge_id: str,
-    task_result: dict
-) -> float:
-    """计算归因置信度"""
-
-    # 因素1:该知识在任务中的使用程度
-    usage_ratio = task_result["knowledge_usage"][knowledge_id] / task_result["total_steps"]
-
-    # 因素2:是否是唯一使用的知识
-    is_only_knowledge = len(task_result["used_knowledge_ids"]) == 1
-
-    # 因素3:失败时的错误类型
-    if task_result["status"] == "failed":
-        error_type = task_result["error_type"]
-        if error_type in ["network", "timeout", "rate_limit"]:
-            return 0.2  # 环境问题,归因置信度低
-        elif error_type in ["logic_error", "wrong_output"]:
-            return 0.9  # 逻辑问题,归因置信度高
-
-    # 综合计算
-    if is_only_knowledge:
-        return 0.9
-    else:
-        return 0.3 + 0.6 * usage_ratio
-```
-
-**实现位置**:`agent/core/runner.py` - 任务完成回调
-
-### 3.5 质量仪表盘
-
-```python
-@app.get("/api/knowledge/stats")
-async def knowledge_stats():
-    """知识库质量统计"""
-    return {
-        "total": 1234,
-        "by_score": {5: 234, 4: 567, 3: 345, 2: 67, 1: 21},
-        "by_state": {"active": 800, "stable": 300, "cold": 100, "archived": 34},
-        "low_quality": [...],      # score < 3 的知识列表
-        "stale": [...],            # 6个月未使用的知识
-        "top_helpful": [...],      # helpful 最多的知识
-        "needs_review": [...],     # harmful > helpful 的知识
-        "conflicts": [...]         # 标记为冲突的知识对
-    }
-```
-
-### 3.6 改进 slim v2(按需执行)
-
-使用聚类 + 分批处理,替换现有的一次性加载方案:
-
-```python
-@app.post("/api/knowledge/slim")
-async def slim_knowledge_v2(
-    batch_size: int = 100,
-    similarity_threshold: float = 0.85,
-    model: str = "google/gemini-2.5-flash-lite"
-):
-    """知识库瘦身 v2:分批聚类合并"""
-
-    # 1. 聚类相似知识(只用向量,不用 LLM)
-    clusters = await cluster_similar_knowledge(
-        similarity_threshold=similarity_threshold
-    )
-
-    # 2. 对每个聚类调用 LLM 判断(分批处理)
-    merged_count = 0
-    for cluster in clusters:
-        knowledge_list = [milvus_store.get_by_id(kid) for kid in cluster]
-
-        # 只处理这个聚类的 2-5 条知识
-        decision = await llm_merge_cluster(knowledge_list, model)
-
-        if decision["should_merge"]:
-            await execute_merge(decision)
-            merged_count += 1
-
-    return {"clusters_found": len(clusters), "merged": merged_count}
-```
-
-**成本**:~$0.5/次(按需执行)
-
----
-
-## 四、实施优先级与成本
-
-### P0(立即实施)
-
-| 机制 | 成本 | 实现位置 |
-|------|------|---------|
-| 保存时关系判断 | $0.15/年 | `agent/tools/builtin/knowledge.py:knowledge_save` |
-| 反馈来源区分 | $0 | `knowhub/server.py:update_knowledge` |
-| 分层存储 | $0 | `knowhub/server.py` + `knowhub/vector_store.py` |
-| 质量淘汰 | $0 | `knowhub/server.py:prune_low_quality` |
-| 知识关系网络 | $0 | `knowhub/server.py` |
-
-**P0 总成本**:~$0.15/年
-
-### P1(短期实施)
-
-| 机制 | 成本 | 实现位置 |
-|------|------|---------|
-| 轻量级健康检查 | ~$0 | `knowhub/server.py:weekly_health_check` |
-| 归因置信度 | $0 | `agent/core/runner.py` |
-
-### P2(按需实施)
-
-| 机制 | 成本 | 备注 |
-|------|------|------|
-| 隐式反馈收集 | $0 | 可选 |
-| 时间衰减机制 | $0 | 可选 |
-| 多维度反馈 | $0 | 可选 |
-| 质量仪表盘 | $0 | 可选 |
-| 改进 slim v2 | $0.5/次 | 按需执行 |
-| 定期全量去重 | $10-20/次 | 仅在保存时去重误判率 > 5% 时需要 |
-
----
-
-## 五、关键设计原则
-
-1. **实时防御优于事后清理**:保存时去重比定期去重更有效
-2. **分层判断降低成本**:向量 → 规则 → LLM,只在必要时用 LLM
-3. **反馈来源加权**:人类 (1.0) > Agent (0.6) > 任务结果 (0.3)
-4. **知识关系网络**:通过 `relations` 字段建立知识图谱
-5. **生命周期管理**:通过 `state` 字段管理知识的可见性
-6. **质量驱动淘汰**:基于反馈自动清理低质量知识
-
----
-
-## 六、完整数据结构
-
-```python
-{
-  # 现有字段
-  "id": "knowledge-20260317-a1b2",
-  "message_id": "msg-xxx",
-  "types": ["strategy", "tool"],
-  "task": "在什么场景下要完成什么目标",
-  "content": "核心知识内容",
-  "tags": {"category": "preference"},
-  "scopes": ["org:cybertogether"],
-  "owner": "agent:research_agent",
-  "resource_ids": ["code/selenium/login"],
-  "source": {
-    "name": "资源名称",
-    "category": "exp",
-    "urls": ["https://example.com"],
-    "agent_id": "research_agent",
-    "submitted_by": "user@example.com",
-    "timestamp": "2026-03-17T12:00:00Z",
-    "message_id": "msg-xxx"
-  },
-
-  # 改进的评估字段
-  "eval": {
-    "score": 4.2,  # 加权综合评分(自动计算)
-    "confidence": 0.9,
-    "feedback_by_source": {
-      "human": {"helpful": 3, "harmful": 0, "weight": 1.0, "last_feedback": "2026-03-17"},
-      "agent_explicit": {"helpful": 12, "harmful": 2, "weight": 0.6, "last_feedback": "2026-03-17"},
-      "task_outcome": {"success": 45, "failure": 5, "weight": 0.3, "last_feedback": "2026-03-17"}
-    },
-    "feedback_history": [
-      {
-        "source": "human",
-        "type": "helpful",
-        "comment": "非常准确",
-        "timestamp": "2026-03-17T12:00:00Z",
-        "user_id": "user@example.com"
-      }
-    ]
-  },
-
-  # 新增:隐式反馈(P2 可选)
-  "implicit_feedback": {
-    "search_count": 156,
-    "click_count": 89,
-    "last_used": "2026-03-17",
-    "avg_rank": 2.3
-  },
-
-  # 新增:知识关系(P0)
-  "relations": [
-    {
-      "target_id": "knowledge-xxx",
-      "relation_type": "complement",
-      "direction": "bidirectional",
-      "confidence": 0.95,
-      "reason": "两条知识互补,分别覆盖不同场景",
-      "created_at": "2026-03-17T12:00:00Z",
-      "created_by": "system",
-      "action_taken": ""
-    }
-  ],
-
-  # 新增:知识状态(P0)
-  "state": "active",  # active/stable/cold/archived/deprecated
-  "state_reason": "",
-  "state_updated_at": "2026-03-17T12:00:00Z",
-
-  "created_at": "2026-03-17T12:00:00Z",
-  "updated_at": "2026-03-17T12:00:00Z"
-}
-```
-
----
-
-## 七、实施路线图
-
-### 阶段 1:核心机制(1-2周)
-
-1. 修改知识数据结构(添加 `relations`, `state`, `feedback_by_source`)
-2. 实现保存时关系判断
-3. 实现反馈来源区分与加权评分
-4. 实现分层存储
-5. 实现质量淘汰
-
-### 阶段 2:监控与优化(1周)
-
-6. 实现轻量级健康检查
-7. 实现归因置信度
-8. 观察运行效果,调整参数
-
-### 阶段 3:增强功能(按需)
-
-9. 隐式反馈收集
-10. 时间衰减机制
-11. 多维度反馈
-12. 质量仪表盘
-13. 改进 slim v2
-
----
-
-## 八、风险与缓解
-
-### 风险 1:LLM 判断误判
-
-**影响**:可能误判为 duplicate 导致丢失有用知识
-
-**缓解**:
-- 使用分层判断,只在边界情况用 LLM
-- 设置置信度阈值,低于 0.8 时降级到更好的模型
-- 轻量级健康检查作为兜底
-
-### 风险 2:关系网络复杂度
-
-**影响**:知识关系可能形成复杂网络,难以维护
-
-**缓解**:
-- 初期只建立必要的关系(complement, conflict)
-- 提供可视化工具查看关系图
-- 定期清理无效关系
-
-### 风险 3:状态转换过于激进
-
-**影响**:有用的知识可能被过早归档
-
-**缓解**:
-- 保守的阈值设置(180天才归档)
-- 归档的知识仍可通过 ID 访问
-- 提供恢复接口
-
----
-
-## 九、成功指标
-
-### 定量指标
-
-- 知识库增长率:从当前 X 条/月降至 Y 条/月
-- 重复率:新增知识中重复率 < 5%
-- 低质量知识占比:score < 3 的知识 < 10%
-- 归档知识占比:archived 状态 < 20%
-
-### 定性指标
-
-- Agent 检索到的知识更相关
-- 知识质量反馈更准确
-- 知识库维护成本降低
-
----
-
-## 十、参考资料
-
-- 现有知识管理文档:`knowhub/docs/knowledge-management.md`
-- 决策记录:`knowhub/docs/decisions.md`
-- 资源存储文档:`knowhub/docs/resource-storage.md`

+ 37 - 1
knowhub/docs/knowledge-management.md

@@ -63,6 +63,37 @@ KnowHub 采用 Milvus Lite 单一存储架构(详见 `knowhub/docs/decisions.m
 
 ---
 
+## 知识质量保障
+
+### 去重机制
+
+新知识保存时自动进行去重检查,防止重复知识累积:
+
+1. **向量召回**:检索 top-10 相似知识(相似度 > 0.75)
+2. **LLM 关系判断**:判断关系类型(duplicate/subset/superset/conflict/complement)
+3. **自动处理**:
+   - duplicate/subset → 拒绝新知识,旧知识 helpful+1
+   - 其他关系 → 保存新知识,建立双向关系链接
+
+**数据字段**:
+- `status`: pending/processing/approved/checked/rejected
+- `relationships`: 与其他知识的关系列表
+
+详见:`knowhub/docs/dedup-design.md`
+
+### 反馈时机机制
+
+自动追踪知识使用效果,在合适时机触发评估:
+
+1. **知识注入日志**:每个 trace 维护 `knowledge_log.json`
+2. **三个触发点**:Goal 完成、压缩前、任务结束
+3. **侧分支评估**:使用 `knowledge_eval` 侧分支,LLM 输出评估结果
+4. **评估分类**:irrelevant/unused/helpful/harmful/neutral
+
+详见:`knowhub/docs/feedback-timing-design.md`
+
+---
+
 ## 知识结构
 
 单条知识的数据格式(基于 `agent/docs/knowledge.md` 定义):
@@ -620,6 +651,8 @@ return ToolResult(
 | Agent 工具 | `agent/tools/builtin/knowledge.py` |
 | goal 工具(知识注入) | `agent/trace/goal_tool.py:focus_goal` |
 | 调研 skill | `agent/skill/skills/research.md` |
+| 去重机制 | `knowhub/server.py:KnowledgeProcessor` → 详见 `dedup-design.md` |
+| 反馈时机 | `agent/trace/store.py`, `agent/core/runner.py` → 详见 `feedback-timing-design.md` |
 
 ---
 
@@ -631,4 +664,7 @@ return ToolResult(
 4. **分离关注点**:知识注入(自动)与调研决策(显式)分离
 5. **工具自治**:知识注入逻辑在 goal 工具中,不在 runner 中
 6. **精确溯源**:使用 message_id 而非 trace_id,可精确定位到具体消息
-7. **质量保证**:两阶段检索(语义路由 + 质量精排)确保准确性
+7. **质量保证**:
+   - 两阶段检索(向量召回 + LLM 精排)确保准确性
+   - 保存时去重防止重复知识累积
+   - 自动反馈追踪知识使用效果

+ 0 - 137
knowhub/docs/resource-storage-examples.md

@@ -1,137 +0,0 @@
-# Resource存储系统使用示例
-
-## 环境配置
-
-在`.env`文件中配置组织密钥:
-
-```bash
-# 生成密钥(Python)
-python -c "import os, base64; print(base64.b64encode(os.urandom(32)).decode())"
-
-# 配置到.env
-ORG_KEYS=test:生成的密钥base64,prod:另一个密钥base64
-```
-
-## 使用示例
-
-### 1. 存储代码片段
-
-```bash
-curl -X POST http://localhost:8000/api/resource \
-  -H "Content-Type: application/json" \
-  -d '{
-    "id": "test/code/selenium",
-    "title": "Selenium绕过检测",
-    "body": "import undetected_chromedriver as uc\ndriver = uc.Chrome()",
-    "content_type": "code",
-    "metadata": {"language": "python"},
-    "submitted_by": "user@example.com"
-  }'
-```
-
-### 2. 存储账号密码(加密)
-
-```bash
-curl -X POST http://localhost:8000/api/resource \
-  -H "Content-Type: application/json" \
-  -d '{
-    "id": "test/credentials/website",
-    "title": "某网站登录凭证",
-    "body": "使用方法:直接登录即可",
-    "secure_body": "账号:user@example.com\n密码:SecurePass123",
-    "content_type": "credential",
-    "metadata": {"acquired_at": "2026-03-06T10:00:00Z"},
-    "submitted_by": "user@example.com"
-  }'
-```
-
-### 3. 存储Cookie(加密)
-
-```bash
-curl -X POST http://localhost:8000/api/resource \
-  -H "Content-Type: application/json" \
-  -d '{
-    "id": "test/cookies/website",
-    "title": "某网站Cookie",
-    "body": "适用于:已登录状态的API调用",
-    "secure_body": "session_id=abc123; auth_token=xyz789",
-    "content_type": "cookie",
-    "metadata": {
-      "acquired_at": "2026-03-06T10:00:00Z",
-      "expires_at": "2026-03-07T10:00:00Z"
-    },
-    "submitted_by": "user@example.com"
-  }'
-```
-
-### 4. 获取资源(无密钥)
-
-```bash
-# 公开内容正常返回,敏感内容显示[ENCRYPTED]
-curl http://localhost:8000/api/resource/test/credentials/website
-```
-
-### 5. 获取资源(有密钥)
-
-```bash
-# 敏感内容解密返回
-curl http://localhost:8000/api/resource/test/credentials/website \
-  -H "X-Org-Key: 你的密钥base64"
-```
-
-### 6. 更新资源
-
-```bash
-curl -X PATCH http://localhost:8000/api/resource/test/credentials/website \
-  -H "Content-Type: application/json" \
-  -d '{
-    "title": "更新后的标题",
-    "metadata": {"acquired_at": "2026-03-06T11:00:00Z"}
-  }'
-```
-
-### 7. 列出所有资源
-
-```bash
-curl http://localhost:8000/api/resource
-```
-
-### 8. 按类型过滤
-
-```bash
-curl "http://localhost:8000/api/resource?content_type=credential"
-```
-
-## Knowledge引用Content
-
-在Knowledge中引用Content资源:
-
-```bash
-curl -X POST http://localhost:8000/api/knowledge \
-  -H "Content-Type: application/json" \
-  -d '{
-    "task": "登录某网站",
-    "content": "使用Selenium + undetected_chromedriver绕过检测,详见content资源",
-    "types": ["tool"],
-    "tags": {
-      "content_ref": "test/code/selenium",
-      "credential_ref": "test/credentials/website"
-    },
-    "owner": "agent:test",
-    "source": {
-      "submitted_by": "user@example.com"
-    }
-  }'
-```
-
-## 测试脚本
-
-运行测试脚本验证功能:
-
-```bash
-# 启动服务器
-uvicorn knowhub.server:app --reload
-
-# 运行测试(另一个终端)
-python test_content_storage.py
-```

+ 56 - 0
knowhub/docs/resource-storage.md

@@ -265,6 +265,62 @@ cookies/
 
 ---
 
+## 工具表(Tools)
+
+工具表是 Resource 的特殊应用,用于管理 MCP/Skills/Library 等工具资源。
+
+### 数据结构
+
+工具表使用特殊的 ID 格式和 metadata 结构:
+
+```json
+{
+  "id": "tools/plugin/ip_adapter",
+  "title": "IP-Adapter",
+  "body": "",
+  "content_type": "text",
+  "metadata": {
+    "category": "plugin",
+    "tool_slug": "ip_adapter",
+    "status": "未接入",
+    "version": "v1.0",
+    "description": "功能描述",
+    "usage": "使用方法",
+    "scenarios": ["应用场景1", "应用场景2"],
+    "input": "输入类型",
+    "output": "输出类型",
+    "source": "https://github.com/...",
+    "knowledge_ids": ["knowledge-xxx"]
+  }
+}
+```
+
+### metadata 字段说明
+
+| 字段 | 类型 | 说明 |
+|------|------|------|
+| `category` | string | 分类:image_gen/image_process/model/plugin/workflow/other |
+| `tool_slug` | string | 小写英文短名,如 controlnet、ip_adapter |
+| `status` | string | 接入状态:未接入/已接入/测试中 |
+| `knowledge_ids` | array | 关联的知识 ID 列表(双向索引) |
+
+### 双向索引
+
+工具表与 Knowledge 通过双向索引关联:
+
+```
+Resource(工具)                     Knowledge(知识)
+┌─────────────────────────┐         ┌──────────────────────────────┐
+│ id: tools/plugin/...    │◄────►│ id: knowledge-xxx            │
+│ metadata.knowledge_ids  │         │ resource_ids                 │
+└─────────────────────────┘         │ tags: {"tool": true}         │
+                                     └──────────────────────────────┘
+```
+
+**重要**:双向索引需要手动维护,没有自动同步机制。
+
+---
+
 ## 与 Knowledge 的关系
 
 | 维度 | Knowledge | Content |

+ 0 - 284
knowhub/docs/tool-table-integration.md

@@ -1,284 +0,0 @@
-# 工具表(Resource)与知识库对接文档
-
-## 文档维护规范
-
-0. **先改文档,再动代码** - 新功能或重大修改需先完成文档更新、并完成审阅后,再进行代码实现;除非改动较小、不被文档涵盖
-1. **文档分层,链接代码** - 重要或复杂设计可以另有详细文档;关键实现需标注代码文件路径;格式:`module/file.py:function_name`
-2. **简洁快照,日志分离** - 只记录最重要的、与代码准确对应的或者明确的已完成的设计的信息,避免推测、建议、决策历史、修改日志、大量代码;决策依据或修改日志若有必要,可在 `knowhub/docs/decisions.md` 另行记录
-
----
-
-## 一、核心概念
-
-知识库(KnowHub)中的工具表存储在 **Resource** 模块里,与 **Knowledge**(知识条目)通过双向索引关联。
-
-| 模块 | 存储后端 | 主键格式 |
-|------|----------|----------|
-| Resource(工具表) | SQLite | `tools/{category}/{slug}` |
-| Knowledge(知识) | Milvus(向量库) | `knowledge-{日期}-{随机}` |
-
----
-
-## 二、Resource 数据结构
-
-### 工具表字段
-
-```json
-{
-  "id": "tools/plugin/ip_adapter",
-  "title": "IP-Adapter",
-  "body": "",
-  "content_type": "text",
-  "metadata": {
-    "category": "plugin",
-    "tool_slug": "ip_adapter",
-    "status": "未接入",
-    "version": "v1.0",
-    "description": "22M参数的轻量适配器,通过CLIP ViT-H图像编码器实现图像提示",
-    "usage": "scale=1.0用于纯图像提示,scale=0.5用于多模态(图像+文本)",
-    "scenarios": ["人物一致性控制", "风格迁移", "图像引导生成"],
-    "input": "参考图像 + 文本提示(可选)",
-    "output": "生成图像",
-    "source": "https://github.com/tencent-ailab/IP-Adapter",
-    "knowledge_ids": ["knowledge-20260309-215835-a699"],
-    "migrated_from": "knowhub_old"
-  },
-  "submitted_by": "migrate_script"
-}
-```
-
-### metadata 字段说明
-
-| 字段 | 类型 | 必填 | 说明 |
-|------|------|------|------|
-| `category` | string | ✅ | 分类:`image_gen` / `image_process` / `model` / `plugin` / `workflow` / `other` |
-| `tool_slug` | string | ✅ | 小写英文短名,空格换下划线,如 `controlnet`、`ip_adapter` |
-| `status` | string | ✅ | 接入状态:`未接入` / `已接入` / `测试中` |
-| `version` | string\|null | — | 版本号 |
-| `description` | string\|null | — | 一句话功能介绍 |
-| `usage` | string\|null | — | 核心用法说明 |
-| `scenarios` | array | — | 应用场景列表 |
-| `input` | string\|null | — | 输入类型描述 |
-| `output` | string\|null | — | 输出类型描述 |
-| `source` | string\|null | — | 来源/文档链接 |
-| `knowledge_ids` | array | — | 关联的知识 ID 列表(双向索引) |
-
-### ID 命名规则
-
-```
-tools/{category}/{slug}
-
-示例:
-tools/plugin/ip_adapter
-tools/plugin/controlnet
-tools/image_gen/midjourney
-tools/model/sdxl
-```
-
----
-
-## 三、双向索引机制
-
-```
-Resource(工具)                     Knowledge(知识)
-┌─────────────────────────┐         ┌──────────────────────────────┐
-│ id: tools/plugin/ip_adapter │◄────►│ id: knowledge-20260309-xxx   │
-│ metadata.knowledge_ids:  │         │ resource_ids:                │
-│   ["knowledge-xxx"]      │         │   ["tools/plugin/ip_adapter"] │
-└─────────────────────────┘         │ tags: {"tool": true}         │
-                                     └──────────────────────────────┘
-```
-
-- **Resource → Knowledge**:`metadata.knowledge_ids` 存储关联知识的 ID 列表
-- **Knowledge → Resource**:`resource_ids` 存储关联工具的 ID 列表,同时打 `tags.tool = true` 标记
-
-### 重要:双向索引是手动维护的
-
-**目前没有任何自动同步机制**,两侧的索引相互独立存储,需要调用方自己负责保持一致。
-
-两侧的写入时机:
-
-| 方向 | 存在哪 | 写入时机 |
-|------|--------|----------|
-| Resource → Knowledge | SQLite `resources.metadata.knowledge_ids` | 创建/更新 Resource 时手动 PATCH |
-| Knowledge → Resource | Milvus `resource_ids` 字段 | Knowledge 创建时传入,**创建后无法通过 API 修改** |
-
-> Knowledge 的 `resource_ids` 字段目前**不在 PATCH 接口的支持范围内**,一旦 Knowledge 创建,只能通过删除重建来更改其关联的工具。
-
----
-
-## 四、API 接口
-
-服务地址由环境变量 `KNOWHUB_API` 指定(如 `http://localhost:9999`)。
-
-### 4.1 工具表(Resource)
-
-#### 创建工具
-```http
-POST /api/resource
-Content-Type: application/json
-
-{
-  "id": "tools/plugin/controlnet",
-  "title": "ControlNet",
-  "body": "",
-  "content_type": "text",
-  "metadata": {
-    "category": "plugin",
-    "tool_slug": "controlnet",
-    "status": "已接入",
-    "description": "...",
-    "usage": "...",
-    "scenarios": [...],
-    "knowledge_ids": []
-  },
-  "submitted_by": "your_name"
-}
-```
-
-#### 更新工具(局部更新,推荐)
-```http
-PATCH /api/resource/tools/plugin/controlnet
-Content-Type: application/json
-
-{
-  "metadata": {
-    "status": "已接入",
-    "knowledge_ids": ["knowledge-xxx", "knowledge-yyy"]
-  }
-}
-```
-> ⚠️ PATCH metadata 会**整体替换** metadata 字段,需带上所有已有字段。
-
-#### 获取工具详情
-```http
-GET /api/resource/tools/plugin/controlnet
-```
-
-返回额外的导航字段:`toc`(根节点)、`children`(子节点)、`prev`/`next`(同级导航)。
-
-#### 列出所有工具
-```http
-GET /api/resource?limit=1000
-```
-
-过滤出工具(客户端过滤):
-```javascript
-const tools = results.filter(r => r.id.startsWith("tools/"));
-```
-
-#### 删除工具
-```http
-DELETE /api/resource/tools/plugin/controlnet
-```
-
----
-
-### 4.2 知识(Knowledge)
-
-#### 搜索工具相关知识(语义搜索)
-```http
-GET /api/knowledge/search?q=IP-Adapter人物一致性&top_k=5&min_score=3
-```
-
-#### 列出所有工具相关知识
-```http
-GET /api/knowledge?tags=tool&status=approved,checked&page_size=200
-```
-
-#### 获取单条知识
-```http
-GET /api/knowledge/knowledge-20260309-215835-a699
-```
-
-#### 批量删除知识
-```http
-POST /api/knowledge/batch_delete
-Content-Type: application/json
-
-["knowledge-xxx", "knowledge-yyy"]
-```
-
----
-
-## 五、典型操作示例(Python)
-
-### 新增一个工具并关联知识
-
-```python
-import httpx
-
-KNOWHUB_API = "http://your-server:9999"
-
-# 1. 创建工具
-tool = {
-    "id": "tools/plugin/controlnet",
-    "title": "ControlNet",
-    "body": "",
-    "content_type": "text",
-    "metadata": {
-        "category": "plugin",
-        "tool_slug": "controlnet",
-        "status": "已接入",
-        "version": "v1.1",
-        "description": "基于条件图像控制SD生成的插件",
-        "usage": "提供边缘图/骨骼图/深度图等条件,精确控制生成结果",
-        "scenarios": ["姿势控制", "边缘控制", "深度控制"],
-        "input": "条件图像(canny/pose/depth等)+ 文本提示",
-        "output": "生成图像",
-        "source": "https://github.com/lllyasviel/ControlNet",
-        "knowledge_ids": []
-    },
-    "submitted_by": "your_name"
-}
-
-resp = httpx.post(f"{KNOWHUB_API}/api/resource", json=tool)
-print(resp.json())  # {"status": "ok", "id": "tools/plugin/controlnet"}
-
-# 2. 回填知识关联(PATCH 更新 knowledge_ids)
-patch = {
-    "metadata": {
-        **tool["metadata"],  # 保留所有已有字段
-        "knowledge_ids": ["knowledge-20260309-215835-a699"]
-    }
-}
-
-resp = httpx.patch(f"{KNOWHUB_API}/api/resource/tools/plugin/controlnet", json=patch)
-print(resp.json())  # {"status": "ok"}
-```
-
-### 更新工具接入状态
-
-```python
-# 先获取当前 metadata,再更新
-resp = httpx.get(f"{KNOWHUB_API}/api/resource/tools/plugin/controlnet")
-tool = resp.json()
-meta = tool["metadata"]
-
-meta["status"] = "已接入"
-
-httpx.patch(
-    f"{KNOWHUB_API}/api/resource/tools/plugin/controlnet",
-    json={"metadata": meta}
-)
-```
-
----
-
-## 六、前端查看
-
-访问 KnowHub 管理界面,点击右上角 **🔧 工具表** 按钮:
-
-- 按 `category` Tab 切换分类
-- 左侧列表点击工具查看详情
-- 详情页显示:基础概览 / 使用指南 / 技术规格 / 消息信源 / 关联知识(可跳转)
-- 知识卡片底部有工具 Tag,点击可跳回工具表对应条目
-
----
-
-## 七、注意事项
-
-1. **PATCH metadata 是整体替换**:更新前先 GET 拿到当前值,合并后再 PATCH,避免覆盖已有字段(尤其是 `knowledge_ids`)。
-2. **Resource ID 含斜杠**:URL 调用时需注意路径编码(框架已支持 `{resource_id:path}`,直接拼接即可,无需手动 encode)。
-3. **双向索引需手动维护**:创建/删除工具时,需同步更新关联 Knowledge 的 `resource_ids` 字段(PATCH `/api/knowledge/{id}`)。
-4. **工具筛选靠客户端**:`GET /api/resource` 返回所有 resource,需在客户端过滤 `id.startsWith("tools/")` 得到工具列表。