84d1a1dd3a
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>
61 lines
2.0 KiB
Go
61 lines
2.0 KiB
Go
// Command server 启动 sundynix-mcp-go —— 第 5 层 Go I/O 型 MCP 工具微服务。
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
sharedbus "github.com/sundynix/sundynix-shared/bus"
|
|
|
|
"github.com/sundynix/sundynix-mcp-go/internal/history"
|
|
"github.com/sundynix/sundynix-mcp-go/internal/mcp"
|
|
"github.com/sundynix/sundynix-mcp-go/internal/memory"
|
|
"github.com/sundynix/sundynix-mcp-go/internal/rag"
|
|
"github.com/sundynix/sundynix-mcp-go/internal/search"
|
|
)
|
|
|
|
func main() {
|
|
natsURL := envOr("NATS_URL", "nats://localhost:4222")
|
|
pgDSN := envOr("POSTGRES_DSN", "postgres://sundynix:sundynix@localhost:5432/sundynix?sslmode=disable")
|
|
redisAddr := envOr("REDIS_ADDR", "localhost:6379")
|
|
milvusAddr := envOr("MILVUS_ADDR", "localhost:19530")
|
|
embBase := envOr("EMBED_BASE_URL", "") // OpenAI 兼容 embeddings 端点(空=向量检索降级)
|
|
embKey := envOr("EMBED_API_KEY", "")
|
|
embModel := envOr("EMBED_MODEL", "")
|
|
|
|
b, err := sharedbus.Connect(natsURL)
|
|
if err != nil {
|
|
log.Fatalf("[mcp_go] nats connect: %v", err)
|
|
}
|
|
defer b.Close()
|
|
log.Printf("[mcp_go] connected %s", natsURL)
|
|
|
|
engine := search.NewHybrid() // LLM Wiki 混合检索:Bleve + Milvus + Neo4j
|
|
mem := memory.Open(pgDSN) // 偏好记忆:sundynix_user_profile(连不上则降级)
|
|
defer mem.Close()
|
|
hist := history.Open(redisAddr) // 会话短期历史:Redis(连不上则降级)
|
|
defer hist.Close()
|
|
|
|
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
|
defer stop()
|
|
|
|
ragEngine := rag.Open(ctx, milvusAddr, embBase, embKey, embModel) // RAG 核心链:embedding + Milvus
|
|
defer ragEngine.Close()
|
|
gw := mcp.NewGateway(b, engine, mem, hist, ragEngine)
|
|
|
|
log.Println("[mcp_go] serving MCP over sundynix.tools.go.* (Ctrl-C to quit)")
|
|
if err := gw.Serve(ctx); err != nil && err != context.Canceled {
|
|
log.Fatalf("[mcp_go] exit: %v", err)
|
|
}
|
|
}
|
|
|
|
func envOr(key, def string) string {
|
|
if v := os.Getenv(key); v != "" {
|
|
return v
|
|
}
|
|
return def
|
|
}
|