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>
This commit is contained in:
Blizzard
2026-06-10 14:06:18 +08:00
parent a67604f4b7
commit cbd130ecae
19 changed files with 638 additions and 57 deletions
+5 -1
View File
@@ -11,11 +11,13 @@ import (
sharedbus "github.com/sundynix/sundynix-shared/bus"
"github.com/sundynix/sundynix-mcp-go/internal/mcp"
"github.com/sundynix/sundynix-mcp-go/internal/memory"
"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")
b, err := sharedbus.Connect(natsURL)
if err != nil {
@@ -25,7 +27,9 @@ func main() {
log.Printf("[mcp_go] connected %s", natsURL)
engine := search.NewHybrid() // LLM Wiki 混合检索:Bleve + Milvus + Neo4j
gw := mcp.NewGateway(b, engine)
mem := memory.Open(pgDSN) // 偏好记忆:sundynix_user_profile(连不上则降级)
defer mem.Close()
gw := mcp.NewGateway(b, engine, mem)
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()