From 3a4732df350275b4d8dd7ce51cbe48dd11bbacbc Mon Sep 17 00:00:00 2001 From: huanghaosheng <386998068@qq.com> Date: Tue, 5 May 2026 10:24:23 +0800 Subject: [PATCH] vault backup: 2026-05-05 10:24:23 --- Eino/EiNO 项目实战.md | 292 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 Eino/EiNO 项目实战.md diff --git a/Eino/EiNO 项目实战.md b/Eino/EiNO 项目实战.md new file mode 100644 index 0000000..9f8b1a8 --- /dev/null +++ b/Eino/EiNO 项目实战.md @@ -0,0 +1,292 @@ +--- +tags: [eino, go, ai-agent, rag, tool-calling, project-theme] +create time: 2026-05-05 14:30 +--- + +# EiNO 项目实战:个人知识助手 + +## 概述 + +基于字节跳动 EINO 框架(Go 语言),从零构建一个**个人知识助手 Agent**。该项目深度融合 **RAG(检索增强生成)** 与 **Tool Calling(工具调用)** 两大核心能力,采用 Supervisor 多 Agent 编排模式,帮助用户高效检索笔记、整理知识、发现关联。场景聚焦日常知识管理,不依赖外部基础设施,是入门 EINO 框架的理想项目。 + +## 正文 + +### 1. 项目背景 + +> [!question] 思考:当你积累了上千篇笔记,某天想找一篇"半年前记过的 Go 并发模式",只记得大概内容却忘了标题——你会怎么办? + +传统做法:逐个翻文件夹 → 搜关键词 → 翻了几分钟还是没找到。而一个智能知识助手可以: + +1. **听懂模糊描述**:"那个讲 goroutine 泄漏排查的文章"→ 语义检索精准定位 +2. **整理碎片知识**:"把最近关于 EINO 的笔记汇总成一篇综述" +3. **发现隐藏关联**:"这篇 RAG 笔记和那篇向量数据库笔记其实在讲同一件事" + +这个场景**天然适合 AI Agent**:检索知识库(RAG)+ 操作笔记(Tool Calling)+ 多步骤任务(ReAct)。 + +**用 EINO 的原因**: +- Go 原生协程,本地跑也轻量 +- 编译时类型检查,工具定义清晰、不易出错 +- ADK 内置 Supervisor / Plan-Execute / Interrupt 等模式,开箱即用 + +--- + +### 2. 系统架构总览 + +```mermaid +graph TD + U["用户提问"] --> S["Supervisor Agent
知识总管家"] + + S --> R["Retrieval Agent
知识检索专家"] + S --> W["Writer Agent
内容处理专家"] + S --> O["Organizer Agent
知识整理专家"] + + R --> VDB["向量数据库
笔记内容索引"] + R --> T1["Tool: 语义搜索
相似笔记召回"] + R --> T2["Tool: 关键词搜索
精确匹配"] + + W --> T3["Tool: 创建笔记
写入 Markdown"] + W --> T4["Tool: 摘要提取
生成笔记摘要"] + W --> T5["Tool: 标签推荐
自动打标签"] + + O --> T6["Tool: 关联发现
Wiki-link 推荐"] + O --> T7["Tool: 知识图谱
关联关系查询"] + + style S fill:#4A90D9,color:#fff + style VDB fill:#27AE60,color:#fff +``` + +> **Supervisor 模式**:Supervisor Agent 接收用户指令,根据意图路由——搜索类交给 Retrieval Agent、写作类交给 Writer Agent、整理类交给 Organizer Agent,最终汇总结果返回。 + +--- + +### 3. RAG 模块设计 + +RAG 负责从用户的笔记库中检索相关内容,让 Agent "读懂你的知识库"。 + +#### 3.1 笔记索引管道 + +```mermaid +flowchart LR + A["Markdown 笔记库"] --> B["Document Loader
按段落分块"] + B --> C["Embedding
文本向量化"] + C --> D["Indexer
写入向量库"] + D --> E["Hybrid Retriever
混合检索"] + E --> F["Agent
上下文注入"] +``` + +#### 3.2 核心代码:混合检索器 + +```go +// RetrieverService 混合检索:语义匹配 + 标签过滤 +type RetrieverService struct { + client milvus.Client + embedder embedding.Embedder +} + +func (s *RetrieverService) Retrieve(ctx context.Context, query string, tags []string) ([]*schema.Document, error) { + // 1. 将用户查询转为向量 + vector, err := s.embedder.Embed(ctx, query) + if err != nil { + return nil, fmt.Errorf("embed query: %w", err) + } + + // 2. 构建标量过滤:限定标签范围 + // 例如: "tag in ['go', 'concurrency', 'eino']" + expr := buildTagFilterExpr(tags) + + // 3. 混合检索:Top-K=5 + results, err := s.client.Search(ctx, "notes_collection", + nil, expr, + []string{"content", "title", "tags"}, + vector, + milvus.NewTopKMetricType(milvus.L2, 5), + milvus.NewSearchParam(16), + ) + // ... 转换为 EINO Document 格式 + return s.convertToDocs(results), nil +} +``` + +> [!tip] 设计要点 +> 混合检索 = **语义相似度**("我记得大概意思") + **标签过滤**("应该是 Go 相关的")。相比纯关键词搜索,它能找到表述不同但意思相近的笔记——这正是知识管理中最常见的场景。 + +--- + +### 4. Tool Calling 模块设计 + +Agent 通过工具与笔记系统交互:搜索、创建、整理、发现关联。 + +#### 4.1 工具清单 + +| 工具 | 类型 | 描述 | +|------|------|------| +| `semantic_search` | 查询 | 语义搜索笔记,支持模糊自然语言描述 | +| `keyword_search` | 查询 | 精确关键词 + 标签搜索 | +| `create_note` | 写入 | 创建新笔记(Markdown + YAML frontmatter) | +| `generate_summary` | 处理 | 为指定笔记生成摘要 | +| `suggest_tags` | 处理 | 根据内容自动推荐标签 | +| `find_related` | 查询 | 发现关联笔记,推荐 Wiki-link | + +#### 4.2 核心代码:定义工具 + +```go +// === 写笔记工具 === +type CreateNoteParams struct { + Title string `json:"title" desc:"笔记标题"` + Content string `json:"content" desc:"Markdown 格式正文"` + Tags []string `json:"tags" desc:"标签列表,如 ['go', 'eino']"` +} + +func CreateNoteTool(vaultPath string) componenttool.BaseTool { + return &componenttool.Tool{ + Name: "create_note", + Desc: "在知识库中创建一篇新的 Markdown 笔记", + Func: func(ctx context.Context, params *CreateNoteParams) (string, error) { + fullPath := filepath.Join(vaultPath, params.Title+".md") + content := buildMarkdownWithFrontmatter(params) + if err := os.WriteFile(fullPath, []byte(content), 0o644); err != nil { + return "", fmt.Errorf("write note: %w", err) + } + return fmt.Sprintf("笔记已创建: %s", fullPath), nil + }, + } +} + +// === 关联发现工具 === +type FindRelatedParams struct { + NoteTitle string `json:"note_title" desc:"目标笔记标题"` +} + +func FindRelatedTool(retriever *RetrieverService) componenttool.BaseTool { + return &componenttool.Tool{ + Name: "find_related", + Desc: "根据笔记内容,从知识库中发现与之关联的其他笔记,推荐 Wiki-link", + Func: func(ctx context.Context, params *FindRelatedParams) (string, error) { + noteContent := readNote(params.NoteTitle) + related, _ := retriever.Retrieve(ctx, noteContent, nil) + return formatWikiLinkSuggestions(related), nil + }, + } +} +``` + +> [!question] 思考:如果用户说"帮我把最近一周关于 EINO 的笔记整理成一篇综述",Agent 需要依次调用哪些工具?顺序能否调换? + +--- + +### 5. Multi-Agent 编排:Supervisor 模式 + +```go +// === 构建 Supervisor,编排三个 Specialist Agent === +func BuildKnowledgeSupervisor(ctx context.Context) (*adk.Supervisor, error) { + // Retrieval Agent: 负责搜索和检索 + retrievalAgent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ + Name: "RetrievalAgent", + Instruction: "你是知识检索专家,擅长从笔记库中找到最相关的内容...", + Model: model, + ToolsConfig: adk.ToolsConfig{ + ToolsNodeConfig: compose.ToolsNodeConfig{ + Tools: []componenttool.BaseTool{ + SemanticSearchTool(retriever), + KeywordSearchTool(), + FindRelatedTool(retriever), + }, + }, + }, + MaxIterations: 10, + }) + + // Writer Agent: 负责创建和整理内容 + writerAgent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ + Name: "WriterAgent", + Model: model, + ToolsConfig: adk.ToolsConfig{ + ToolsNodeConfig: compose.ToolsNodeConfig{ + Tools: []componenttool.BaseTool{ + CreateNoteTool(vaultPath), + SummaryTool(model), + SuggestTagsTool(model), + }, + }, + }, + MaxIterations: 8, + }) + + // Organizer Agent: 负责关联发现和知识图谱 + organizerAgent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ + // ... 配置 FindRelated 等整理工具 + MaxIterations: 8, + }) + + return adk.NewSupervisor(ctx, &adk.SupervisorConfig{ + Name: "KnowledgeSupervisor", + Model: model, + Instruction: "你是知识总管。根据用户意图路由任务...", + SubAgents: []adk.Agent{retrievalAgent, writerAgent, organizerAgent}, + }) +} +``` + +```mermaid +sequenceDiagram + participant U as 用户 + participant S as Supervisor + participant R as Retrieval Agent + participant W as Writer Agent + + U->>S: "帮我整理最近关于 EINO 的笔记,
写一篇学习综述" + + S->>S: 意图分类 → 检索 + 写作(复合任务) + + S->>R: 委派检索任务 + R->>R: Tool: semantic_search("EINO") → 找到 5 篇 + R->>R: Tool: find_related → 发现 3 篇关联笔记 + R->>S: 返回 8 篇笔记及其内容 + + S->>W: 委派写作任务(附检索结果) + W->>W: 基于 8 篇笔记撰写综述草稿 + W->>W: Tool: suggest_tags → ["eino", "agent", "go"] + W->>S: 返回综述 + 推荐标签 + + S->>U: 📝 综述全文 + 🏷️ 推荐标签 + 🔗 关联笔记 +``` + +--- + +### 6. 进阶拓展方向 + +> [!info] 掌握了基础架构后,可以探索这些方向 + +1. **会话式检索**:支持多轮追问——"上次那篇关于 goroutine 的"→"不是那篇,是讲泄漏排查的"→ Agent 结合上下文逐步缩小范围,像和人对话一样自然。 + +2. **定时知识回顾**:用 Cron 触发 Agent,每周自动检索本周新增笔记 → 生成"本周知识地图"→ 推送回顾通知。类似间隔重复,但由 AI 驱动。 + +3. **跨源增强**:当本地笔记不足时,Agent 可调用 `web_search` 工具获取外部信息作为补充,生成"本地知识 + 外部参考"的混合回答,并标注来源。 + +4. **知识冲突检测**:当新笔记与已有笔记表述矛盾(如某篇写"Go defer 是栈顺序",另一篇写"是队列顺序"),Agent 自动标记冲突,提醒用户核实。 + +5. **MCP 集成**:将工具标准化为 MCP Server,让其他 AI 客户端(如 Claude Desktop、VS Code 插件)也能直接调用你的知识助手。 + +--- + +### 7. 关键 EINO 概念速查 + +| EINO 概念 | 本项目对应 | +|-----------|-----------| +| `ChatModelAgent` | RetrievalAgent / WriterAgent / OrganizerAgent | +| `Supervisor` | KnowledgeSupervisor(多 Agent 总调度) | +| `Tool / ToolsNode` | 语义搜索、创建笔记、摘要、标签、关联发现 | +| `Retriever` | 混合检索器(语义 + 标签过滤) | +| `Embedding` | 文本向量化 | +| `Indexer` | 笔记内容写入向量库 | +| `Document Loader` | Markdown 笔记按段落分块加载 | +| `ChatTemplate` | System Prompt + 检索结果注入 | +| `Interrupt / Resume` | 删改操作前的确认拦截(进阶) | +| `Graph / Compile` | 编排所有节点、编译成可执行图 | + +--- + +## 关联笔记 + +- [[EINO ADK 深入]] +