8 Commits

Author SHA1 Message Date
Blizzard d623b8590e feat: GraphRAG — LLM 抽三元组建 Neo4j 图谱 + 混合检索加图谱第三路
混合检索从 2 路(向量+全文)升级为 3 路(+图谱)。入库时 LLM 抽实体/关系建
Neo4j 图,检索时图谱路(实体关联三元组)融进 RRF;UI 可视化图谱。

- mcp-go rag: chat.go(OpenAI 兼容非流式 chat 客户端,抽取用) + graph.go(neo4j-go-driver
  连接 + LLM 抽三元组 + MERGE 实体/关系 + 图谱召回/全量三元组) + rag.go(Config 结构;
  graph+chat 路;Ingest 加 抽实体/写Neo4j 阶段;Search 三路 RRF 融合;SetChat 热更新)
- mcp-go: Neo4j env(默认 neo4j://localhost:7687, neo4j/sundynix);订阅 chat 控制面配置
  (复用 DeepSeek 做抽取);新工具 kb_graph(返回三元组)
- gateway: GET /api/v1/kb/graph;frontend KbView 知识图谱面板(实体—关系→实体)
- 验证: 全模块 build✓ + e2e PASS; live——入库'sundynix用Milvus...'→DeepSeek 抽 4 三元组
  →Neo4j(8 实体);检索三路融合 向量=4 全文=2 图谱=1;浏览器图谱面板渲染 4 三元组
- 边界: 实体链接用 CONTAINS 朴素匹配(可升级 LLM 查询实体抽取);全文/图谱重启随入库重建

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 11:10:22 +08:00
Blizzard 85a5c2c1e7 feat(rag): 混合检索融合 — Milvus 向量 + Bleve 全文 + RRF + DashScope rerank
检索从向量单路升级为混合:向量(Milvus) + 全文(Bleve BM25) → RRF 融合 →
可选 rerank(DashScope gte-rerank)。

- rag/bleve.go: Bleve 全文索引(内存,随 ingest 写入;kb 过滤);ingest 同步写 Milvus+Bleve
- rag/fuse.go: RRF(Reciprocal Rank Fusion, k=60, 按文本去重)融合多路排序
- rag/rerank.go: DashScope gte-rerank 客户端(可选,env 配置,失败降级 RRF)
- rag/rag.go: Search 改混合(向量+全文→RRF→可选rerank→topK);main 读 RERANK_* env
- 验证: 全模块 build✓ + e2e PASS; live——入库写双索引;查'NATS'→全文精确命中#1+向量
  →RRF NATS 排首(向量=4 全文=1);接 DashScope gte-rerank(百炼 key 有权限)→relevance
  score 0.19 真重排;retriever 节点端到端→DeepSeek 答 Milvus
- 边界: Neo4j 图路(GraphRAG,需实体抽取)推迟;Bleve 内存索引重启重建;rerank 走 env
  (TODO 同 embedding 搬控制面 kind=rerank)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 09:53:37 +08:00
Blizzard 3b54e59ecf feat: embedding 配置搬上控制面 — 数据源页可视化配置 + 热更新
embedding 从 env 改为控制面驱动(持久化+可视化),复用 chat 模型同套范式:
配置控制面泛化为按 kind(chat/embedding),加 embedding kind。

- shared: 配置 subjects 泛化 sundynix.config.<kind>.get/.updated;bus 方法改 kind 参数
  (RequestConfig/ServeConfig/PublishConfigUpdated/SubscribeConfigUpdated)
- gateway: sundynix_model 加 kind 列(每 kind 唯一激活)+旧行回填 chat;admin 按 kind
  增删改/激活/列表,测试连接 embedding 走 POST /embeddings;main 按 kind ServeConfig;
  变更广播各 kind
- dispatcher: 取 chat 配置(kind 化)
- mcp-go: rag.Engine.SetEmbedding 热更新(RWMutex);main 取/订阅 embedding 控制面配置
  (覆盖 env)
- admin 控制台: api 按 kind;抽出复用 ModelManager;ModelsPage(chat)+新 DatasourcesPage
  (embedding + 向量/图库占位);routes 数据源页就绪
- 验证: 全模块 build✓ + e2e PASS + 控制台 npm build✓;live 全跑通——chat(DeepSeek 回填
  kind 仍工作);mcp-go 不带 EMBED env 启动→控制台配 embedding(百炼)→测试连接✓→激活
  →NATS 热更新 mcp-go→入库+语义检索'存向量的数据库'→Milvus;浏览器数据源页拉到激活配置

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 17:25:54 +08:00
Blizzard 84d1a1dd3a feat: RAG 核心链 — embedding(provider) + Milvus 真连 + 入库/检索
mcp-go 接通向量 RAG:embedding(OpenAI 兼容 provider 抽象) + Milvus 真实连接,
kb_ingest 入库、wiki_search 真检索。retriever 节点一行不改即从桩变真。

- mcp-go internal/rag: embed.go(OpenAI 兼容 /embeddings 客户端) + milvus.go(milvus-sdk-go
  真连,集合按首次 embedding 维度懒建+AUTOINDEX/COSINE索引+加载,insert/向量search) +
  rag.go(Engine: 切块→embed→insert / embed query→search;embedding 或 Milvus 缺则降级)
- mcp-go gateway: 新工具 kb_ingest,wiki_search 换真(RAG 向量检索,kb 过滤 topK)
- mcp-go main: rag.Open 读 MILVUS_ADDR/EMBED_BASE_URL/EMBED_API_KEY/EMBED_MODEL 环境变量
- gateway: POST /api/v1/kb/ingest → kb_ingest(供知识库页/脚本)
- scripts/mock_embeddings.py: 确定性词法向量(字+bigram 哈希),无真 key 验证检索
- 开发期 embedding 接在线 API(无真 key 用 mock),见 llm-provider-strategy
- 验证: 全模块 build✓ + e2e PASS; live——入库5条→Milvus;retriever 节点查'向量数据库'
  →召回 Milvus 那条→DeepSeek 答'Milvus';查'知识图谱'→Neo4j(向量检索区分正确)

注: 当前向量单路;Bleve/Neo4j 融合 + rerank + 真实语义 embedding 为后续。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 17:07:36 +08:00
Blizzard 4928ffc0f7 feat: 短期多轮历史接入 Eino 图 MessagesPlaceholder (⑨)
会话历史(Redis,易失,与长期画像分开)经 MCP 工具进出 Eino 图:
recall 召回历史填 MessagesPlaceholder,写回把本轮 user/assistant 落历史。

- mcp-go: internal/history(go-redis, sundynix:history:<session>, LPUSH+LTRIM 保留近20条,
  24h TTL) + 工具 history_get(返回JSON turns)/history_append; main 开 Redis(降级)
- dispatcher Eino: 模板加 MessagesPlaceholder('history'); recall 调 history_get→转 schema.Message;
  Handle 累积 answer; memorize 异步 history_append(user+assistant)
- shared: contract.MetaSessionID; gateway: SubmitTask 注入 Meta[session_id](X-Session-ID 头,缺省 default)
- demo.sh: 同会话两轮提交,验证第2轮召回第1轮历史
- 验证: 4 模块 build✓ + 3 e2e PASS; live 跑通——轮1=0轮历史→落库, 轮2 history_get 命中→注入

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 14:18:45 +08:00
Blizzard cbd130ecae feat: 第一张真实 Eino 图 + 偏好记忆(让模型知道是我)
dispatcher 不再手搓 pool.Stream,改用编译好的 Eino 图驱动;接入用户常驻画像,
推理前召回并注入 system prompt,实现个性化(架构'心脏'首次真跳)。

Eino 图(dispatcher/internal/eino): START→recall→prompt→model→END + 全局 State
- recall(Lambda): 取 Meta[user_id] → 调 MCP memory_get → ProcessState 写画像
- prompt(ChatTemplate): {profile} 注入 system,{query} 作 user
- model: poolModel 适配 LLM Pool 为 model.BaseChatModel(Generate+Stream, schema.Pipe)
- 写回: 流排空后异步 memorize(流式节点走 OnEndWithStreamOutput 非 OnEndFn)

记忆存储(mcp-go owns): GORM Profile→sundynix_user_profile(复合主键, AutoMigrate,
遵守前缀约定), 新工具 memory_get/memory_upsert, 连不上降级
Gateway: SubmitTask 注入 Meta[user_id](X-User-ID 头), PUT /api/v1/memory→memory_upsert
shared: contract.MetaUserID; llm.Pool 拆出 StreamText

验证: 4 模块 build✓ + 3 e2e PASS; live 跑通——PUT 偏好落 sundynix_user_profile,
带 X-User-ID 提交→Eino recall 召回→注入→SSE 流出含画像的个性化回答, writeback 触发

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 14:06:18 +08:00
Blizzard adc521f94d feat: 打通 Dispatcher→MCP 工具调用链路 (core NATS request-reply)
第 4 层 Dispatcher 经 NATS request-reply + 队列组同步调用第 5 层 MCP 工具,
工具不可用/超时即降级,不阻断主流程。

- shared/contract: ToolCall/ToolResult + sundynix.tools.go.* subject 约定 + ToolSubjectGo/Py
- shared/bus: CallTool(发起) / ServeTool(队列组订阅+应答)
- mcp-go: 接共享 bus,gateway 通配订阅按工具名分发(wiki_search/echo),main 优雅退出
- dispatcher: ToolCaller 接口 + Orchestrator.retrieveContext(调 wiki_search,超时3s降级)
- e2e: TestToolCallRoundTrip(PASS);demo.sh 加 mcp-go(就绪门避免启动竞态),live 跑通

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 11:31:58 +08:00
Blizzard c7a02c3905 feat: 初始化 sundynix-agentix 分层式 AI Agent 平台脚手架
5 层 + 1 条 NATS 零拷贝消息总线的 monorepo(Monolith First → Microservices Morph B)。
纵向主干(任务流 + Token 流回流)已真实跑通,横向各层能力为带注释的桩。

已贯通(real code):
- sundynix-shared: 共享契约 + JetStream/core NATS 真实收发(bus) + 内嵌 NATS(devnats) + e2e 测试
- sundynix-gateway: Gin 接入 + DSL 解析组装 + NATS Publish + SSE 流式输出
- sundynix-dispatcher: NATS 消费 + Eino Orchestrator 流式回流 + 熔断器 + LLM Pool 占位流式
- 链路: HTTP POST → DSL → sundynix.tasks.* → Dispatcher → Token 经 sundynix.streams.<id> 回流 → SSE
- 基础设施: docker-compose(nats/postgres/redis/neo4j/milvus) + Makefile(make demo/e2e)

待填(桩):
- Eino 图编排 compose.NewGraph、LLM Pool 接 vLLM/Ollama
- Gateway store 换真实 pgx/redis
- sundynix-mcp-go: Bleve+Milvus+Neo4j 混合检索 / UniOffice / 外部 API
- sundynix-mcp-py: gVisor 沙箱 / MinerU(PaddleOCR) / Docker 解释器
- sundynix-desktop: React Flow 画布 → DSL 导出 → SSE 展示
2026-06-10 11:00:29 +08:00