dfd8421dc6
**Storage Layer:** - Database 类(aiosqlite + WAL + 并发保护) - WikiPage 数据模型 - fix_dirty_states 恢复机制 - FTS5 全文搜索支持 - 完整的 SQLite 表结构 **Service Layer:** - CacheService(LRU 缓存 + TTL + 大小限制) - QueryService(查询服务) - ParserService(Markdown 解析) - IndexerService(索引服务) - GraphService(链接图服务) **Tool Layer (8 个 MCP Tools):** - wiki_query - FTS5 全文搜索 + 标签过滤 - memory_bridge - 按工具来源浏览 - wiki_status - 索引状态 - wiki_lint - 健康审计 - cross_linker - 缺失链接发现 - tag_taxonomy - 标签一致性 - wiki_synthesize - 跨概念综合分析 - daily_update - 日常维护 + hot.md 生成 **MCP Protocol Layer:** - MCP 协议解析和封装 - 工具注册和路由 - 错误处理和日志 - stdio 模式支持 **配置和部署:** - requirements.txt - config.example.yaml - ecosystem.config.cjs (PM2) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
106 lines
3.6 KiB
Python
106 lines
3.6 KiB
Python
"""
|
|
Tool Layer - wiki_synthesize 工具
|
|
|
|
发现跨概念的综合分析机会,生成 synthesis 页面。
|
|
|
|
参考设计文档:第 2.2 节
|
|
"""
|
|
|
|
import logging
|
|
from typing import Dict, Any, List
|
|
from ..services import QueryService, GraphService
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class WikiSynthesizeTool:
|
|
"""wiki_synthesize 工具实现"""
|
|
|
|
def __init__(self, query_service: QueryService, graph_service: GraphService):
|
|
self.query_service = query_service
|
|
self.graph_service = graph_service
|
|
|
|
async def handle(self, concepts: List[str] = None, threshold: float = 0.3) -> Dict[str, Any]:
|
|
"""
|
|
发现跨概念的综合分析机会
|
|
|
|
Args:
|
|
concepts: 概念列表(空表示自动发现)
|
|
threshold: 相关性阈值
|
|
|
|
Returns:
|
|
{
|
|
"synthesis": [
|
|
{
|
|
"concept_a": "SQLite",
|
|
"concept_b": "Concurrency",
|
|
"common_references": ["page1", "page2"],
|
|
"strength": 0.8,
|
|
"suggestion": "Consider creating synthesis page: SQLite & Concurrency"
|
|
}
|
|
],
|
|
"total": 5
|
|
}
|
|
"""
|
|
synthesis = []
|
|
|
|
# 如果未提供概念,自动发现高相关性概念
|
|
if not concepts:
|
|
# 获取高度连接的页面作为候选
|
|
highly_connected = await self.graph_service.get_highly_connected_pages(threshold=10)
|
|
concepts = [item["title"] for item in highly_connected[:10]]
|
|
|
|
# 分析概念间的关联
|
|
for i, concept_a in enumerate(concepts):
|
|
for concept_b in concepts[i + 1:]:
|
|
# 查找同时引用两个概念的页面
|
|
pages_a = await self.query_service.search(concept_a, limit=50)
|
|
pages_b = await self.query_service.search(concept_b, limit=50)
|
|
|
|
paths_a = {p.path for p in pages_a}
|
|
paths_b = {p.path for p in pages_b}
|
|
|
|
common = paths_a & paths_b
|
|
|
|
if len(common) >= 2: # 至少 2 个共同引用
|
|
strength = len(common) / max(len(paths_a), len(paths_b))
|
|
|
|
if strength >= threshold:
|
|
synthesis.append({
|
|
"concept_a": concept_a,
|
|
"concept_b": concept_b,
|
|
"common_references": sorted(list(common)),
|
|
"strength": round(strength, 2),
|
|
"suggestion": f"Consider creating synthesis page: {concept_a} & {concept_b}"
|
|
})
|
|
|
|
# 按关联强度排序
|
|
synthesis.sort(key=lambda x: x["strength"], reverse=True)
|
|
|
|
return {
|
|
"synthesis": synthesis[:20],
|
|
"total": len(synthesis)
|
|
}
|
|
|
|
def get_schema(self) -> dict:
|
|
"""返回 MCP Tool schema"""
|
|
return {
|
|
"name": "wiki_synthesize",
|
|
"description": "发现跨概念的综合分析机会,生成 synthesis 页面",
|
|
"inputSchema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"concepts": {
|
|
"type": "array",
|
|
"items": {"type": "string"},
|
|
"description": "概念列表(空表示自动发现)"
|
|
},
|
|
"threshold": {
|
|
"type": "number",
|
|
"default": 0.3,
|
|
"description": "相关性阈值"
|
|
}
|
|
}
|
|
}
|
|
}
|