Files
CamTalk/docs/Eino/EiNO 项目实战.md

293 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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<br/>知识总管家"]
S --> R["Retrieval Agent<br/>知识检索专家"]
S --> W["Writer Agent<br/>内容处理专家"]
S --> O["Organizer Agent<br/>知识整理专家"]
R --> VDB["向量数据库<br/>笔记内容索引"]
R --> T1["Tool: 语义搜索<br/>相似笔记召回"]
R --> T2["Tool: 关键词搜索<br/>精确匹配"]
W --> T3["Tool: 创建笔记<br/>写入 Markdown"]
W --> T4["Tool: 摘要提取<br/>生成笔记摘要"]
W --> T5["Tool: 标签推荐<br/>自动打标签"]
O --> T6["Tool: 关联发现<br/>Wiki-link 推荐"]
O --> T7["Tool: 知识图谱<br/>关联关系查询"]
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<br/>按段落分块"]
B --> C["Embedding<br/>文本向量化"]
C --> D["Indexer<br/>写入向量库"]
D --> E["Hybrid Retriever<br/>混合检索"]
E --> F["Agent<br/>上下文注入"]
```
#### 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 的笔记,<br/>写一篇学习综述"
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 深入]]