vault backup: 2026-04-29 18:54:02
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
---
|
||||
Description: ""
|
||||
date: "2026-03-12"
|
||||
lastmod: ""
|
||||
tags: []
|
||||
title: 第四章:Tool 与文件系统访问
|
||||
weight: 4
|
||||
tags: ["Eino", "Agent", "Tool", "Backend", "DeepAgent", "文件系统"]
|
||||
create time: "2026-04-29 15:30"
|
||||
---
|
||||
|
||||
本章目标:为 Agent 添加 Tool 能力,让 Agent 能够访问文件系统。
|
||||
# 第四章:Tool 与文件系统访问
|
||||
|
||||
## 概述
|
||||
|
||||
本章为 Agent 引入 Tool(工具)能力,使其能够突破纯文本对话的边界,直接操作文件系统、搜索代码库、执行命令。通过 DeepAgent 预构建组件和 Backend 抽象接口,只需几行配置即可让 Agent「看见」并「触碰」真实世界。
|
||||
|
||||
## 为什么需要 Tool
|
||||
|
||||
@@ -27,26 +27,37 @@ weight: 4
|
||||
|
||||
**简单类比:**
|
||||
|
||||
- **Agent** = "智能助手"(能理解指令,但需要工具才能执行)
|
||||
- **Tool** = "工具箱"(文件操作、网络请求、数据库查询等)
|
||||
- **Agent** = "智能助手"(能理解指令,但需要工具才能执行)
|
||||
- **Tool** = "工具箱"(文件操作、网络请求、数据库查询等)
|
||||
|
||||
> [!question] 深入思考
|
||||
>
|
||||
> 如果 Agent 拥有无限个 Tool,会不会反而变得更差?
|
||||
> 提示:考虑模型上下文窗口限制、Token 成本、以及"选择困难症"效应。实际设计中,**工具的元信息描述质量**比数量更重要——一个好的 `Description` 能让模型精准选对工具。
|
||||
|
||||
## 为什么需要文件系统能力
|
||||
|
||||
本示例是 ChatWithDoc(与文档对话),目标是帮助用户学习 Eino 框架并编写 Eino 代码。那么,最好的文档是什么?
|
||||
本示例是 ChatWithDoc(与文档对话),目标是帮助用户学习 Eino 框架并编写 Eino 代码。那么,最好的文档是什么?
|
||||
|
||||
**答案就是:Eino 仓库的代码本身。**
|
||||
**答案就是:Eino 仓库的代码本身。**
|
||||
|
||||
- **Code**: 源代码展示了框架的真实实现
|
||||
- **Comment**: 代码注释提供了设计思路和使用说明
|
||||
- **Examples**: 示例代码演示了最佳实践
|
||||
| 资源类型 | 价值 |
|
||||
|---------|------|
|
||||
| **Code** | 源代码展示了框架的真实实现 |
|
||||
| **Comment** | 代码注释提供了设计思路和使用说明 |
|
||||
| **Examples** | 示例代码演示了最佳实践 |
|
||||
|
||||
通过文件系统访问能力,Agent 可以直接读取 Eino 源码、注释和示例,为用户提供最准确、最及时的技术支持。
|
||||
通过文件系统访问能力,Agent 可以直接读取 Eino 源码、注释和示例,为用户提供最准确、最及时的技术支持。
|
||||
|
||||
> [!tip] 现实启发
|
||||
>
|
||||
> 很多官方文档会过时或写得模糊,但代码不会。让 Agent "读源码"是一种绕过信息衰减的可靠策略——这也是为什么 RAG 系统的向量库经常直接索引代码仓库的原因。
|
||||
|
||||
## 关键概念
|
||||
|
||||
### Tool 接口
|
||||
|
||||
`Tool` 是 Eino 中定义可执行能力的接口:
|
||||
`Tool` 是 Eino 中定义可执行能力的接口:
|
||||
|
||||
```go
|
||||
// BaseTool 提供工具的元信息,ChatModel 使用这些信息决定是否以及如何调用工具
|
||||
@@ -69,41 +80,51 @@ type StreamableTool interface {
|
||||
}
|
||||
```
|
||||
|
||||
**接口层次:**
|
||||
**接口层次:**
|
||||
|
||||
- `BaseTool`:基础接口,只提供元信息
|
||||
- `InvokableTool`:可执行工具(继承 BaseTool)
|
||||
- `StreamableTool`:流式工具(继承 BaseTool)
|
||||
- `BaseTool`:**信息层**,只提供工具的名称、描述和参数 schema,ChatModel 据此决定是否调用
|
||||
- `InvokableTool`:**同步执行层**,返回完整结果字符串,适合大多数文件操作场景
|
||||
- `StreamableTool`:**流式执行层**,通过 `StreamReader` 逐步输出结果,适合大量输出的场景(如长文件读取或命令执行)
|
||||
|
||||
> [!note] 设计要点
|
||||
>
|
||||
> 为什么 Tool 的参数是 JSON 字符串而不是 Go struct?
|
||||
> 因为 Tool 需要在 ChatModel 的上下文里传递——模型只能理解文本。所以 Eino 将参数序列化为 JSON 传给模型,模型再返回 JSON,由 ToolsNode 反序列化后调用底层实现。这种设计让任何语言/协议的工具都能与基于 JSON 的大模型对齐。
|
||||
|
||||
### Backend 接口
|
||||
|
||||
`Backend` 是 Eino 中用于文件系统操作的抽象接口:
|
||||
`Backend` 是 Eino 中用于文件系统操作的抽象接口,定义了六种核心文件能力:
|
||||
|
||||
```go
|
||||
type Backend interface {
|
||||
// 列出目录下的文件信息
|
||||
LsInfo(ctx context.Context, req *LsInfoRequest) ([]FileInfo, error)
|
||||
|
||||
// 读取文件内容,支持按行偏移和限制
|
||||
Read(ctx context.Context, req *ReadRequest) (*FileContent, error)
|
||||
|
||||
// 在文件中搜索匹配的内容
|
||||
GrepRaw(ctx context.Context, req *GrepRequest) ([]GrepMatch, error)
|
||||
|
||||
// 根据 glob 模式匹配文件
|
||||
GlobInfo(ctx context.Context, req *GlobInfoRequest) ([]FileInfo, error)
|
||||
|
||||
// 写入文件内容
|
||||
Write(ctx context.Context, req *WriteRequest) error
|
||||
|
||||
// 编辑文件内容(字符串替换)
|
||||
Edit(ctx context.Context, req *EditRequest) error
|
||||
// 列出目录下的文件信息
|
||||
LsInfo(ctx context.Context, req *LsInfoRequest) ([]FileInfo, error)
|
||||
|
||||
// 读取文件内容,支持按行偏移和限制
|
||||
Read(ctx context.Context, req *ReadRequest) (*FileContent, error)
|
||||
|
||||
// 在文件中搜索匹配的内容
|
||||
GrepRaw(ctx context.Context, req *GrepRequest) ([]GrepMatch, error)
|
||||
|
||||
// 根据 glob 模式匹配文件
|
||||
GlobInfo(ctx context.Context, req *GlobInfoRequest) ([]FileInfo, error)
|
||||
|
||||
// 写入文件内容
|
||||
Write(ctx context.Context, req *WriteRequest) error
|
||||
|
||||
// 编辑文件内容(字符串替换)
|
||||
Edit(ctx context.Context, req *EditRequest) error
|
||||
}
|
||||
```
|
||||
|
||||
> [!tip] 方法分组
|
||||
>
|
||||
> Backend 的六类方法可以归为三类:
|
||||
> **发现**(LsInfo / GlobInfo)、**检索**(Read / GrepRaw)、**修改**(Write / Edit)。记住这个分类有助于快速理解不同 Backend 实现的侧重点。
|
||||
|
||||
### LocalBackend
|
||||
|
||||
`LocalBackend` 是 Backend 的本地文件系统实现,直接访问操作系统的文件系统:
|
||||
`LocalBackend` 是 Backend 的本地文件系统实现,直接访问操作系统的文件系统:
|
||||
|
||||
```go
|
||||
import localbk "github.com/cloudwego/eino-ext/adk/backend/local"
|
||||
@@ -111,13 +132,17 @@ import localbk "github.com/cloudwego/eino-ext/adk/backend/local"
|
||||
backend, err := localbk.NewBackend(ctx, &localbk.Config{})
|
||||
```
|
||||
|
||||
**特点:**
|
||||
**特点:**
|
||||
|
||||
- 直接访问本地文件系统,使用 Go 标准库实现
|
||||
- 直接访问本地文件系统,使用 Go 标准库实现
|
||||
- 支持所有 Backend 接口方法
|
||||
- 支持执行 shell 命令(ExecuteStreaming)
|
||||
- 路径安全:要求使用绝对路径,防止目录遍历攻击
|
||||
- 零配置:开箱即用,无需额外设置
|
||||
- 支持执行 shell 命令(ExecuteStreaming)
|
||||
- 路径安全:要求使用绝对路径,防止目录遍历攻击
|
||||
- 零配置:开箱即用,无需额外设置
|
||||
|
||||
> [!warning] 安全问题
|
||||
>
|
||||
> LocalBackend 要求使用绝对路径来防止 `../` 目录遍历攻击。这意味着 Agent 永远不能通过构造恶意文件名跳出设定的根目录范围——这是 LLM 集成中的关键安全措施。
|
||||
|
||||
## 实现:使用 DeepAgent
|
||||
|
||||
@@ -130,63 +155,75 @@ backend, err := localbk.NewBackend(ctx, &localbk.Config{})
|
||||
**ChatModelAgent vs DeepAgent 对比:**
|
||||
|
||||
<table>
|
||||
<tr><td>能力</td><td>ChatModelAgent</td><td>DeepAgent</td></tr>
|
||||
<tr><th>能力</th><th>ChatModelAgent</th><th>DeepAgent</th></tr>
|
||||
<tr><td>多轮对话</td><td>✅</td><td>✅</td></tr>
|
||||
<tr><td>添加自定义 Tool</td><td>✅ 手动注册每个 Tool</td><td>✅ 手动注册或自动注册</td></tr>
|
||||
<tr><td>文件系统访问(Backend)</td><td>❌ 需手动创建并注册所有文件工具</td><td>✅ 一级配置,自动注册</td></tr>
|
||||
<tr><td>命令执行(StreamingShell)</td><td>❌ 需手动创建</td><td>✅ 一级配置,自动注册</td></tr>
|
||||
<tr><td>内置任务管理</td><td>❌</td><td>✅ <pre>write_todos</pre> 工具</td></tr>
|
||||
<tr><td>内置任务管理</td><td>❌</td><td>✅ `write_todos` 工具</td></tr>
|
||||
<tr><td>支持子 Agent</td><td>❌</td><td>✅</td></tr>
|
||||
</table>
|
||||
|
||||
**选择建议:**
|
||||
|
||||
- 纯对话场景(无外部访问)→ 用 `ChatModelAgent`
|
||||
- 需要访问文件系统或执行命令 → 用 `DeepAgent`
|
||||
> [!tip] 选择建议
|
||||
>
|
||||
> - 纯对话场景(无外部访问)→ 用 `ChatModelAgent`
|
||||
> - 需要访问文件系统或执行命令 → 用 `DeepAgent`
|
||||
|
||||
### 为什么使用 DeepAgent?
|
||||
|
||||
相比直接使用 ChatModelAgent,DeepAgent 的优势:
|
||||
相比直接使用 ChatModelAgent,DeepAgent 的优势在于把「基础设施」封装成了第一类配置,你只需声明意图而非实现细节:
|
||||
|
||||
1. **一级配置**: Backend 和 StreamingShell 是一级配置,直接传入即可
|
||||
2. **自动注册工具**: 配置 Backend 后自动注册文件系统工具,无需手动创建
|
||||
3. **内置任务管理**: 提供 `write_todos` 工具,支持任务规划和跟踪
|
||||
4. **支持子 Agent**: 可以配置专门的子 Agent 处理特定任务
|
||||
5. **更强大**: 集成了文件系统、命令执行等多种能力
|
||||
1. **一级配置**:Backend 和 StreamingShell 直接在 Config 中传入,无需自己组装 ToolsNode
|
||||
2. **自动注册工具**:配置 Backend 后自动注册文件系统工具,免去逐个定义的样板代码
|
||||
3. **内置任务管理**:提供 `write_todos` 工具,支持复杂任务的规划与跟踪
|
||||
4. **支持子 Agent**:可以配置专门的子 Agent 处理特定任务
|
||||
5. **更强大**:集成了文件系统、命令执行等多种能力
|
||||
|
||||
### 代码实现
|
||||
|
||||
这段代码完成了两件事:创建 Backend 实例,再将其注入 DeepAgent。让我们逐行看:
|
||||
|
||||
```go
|
||||
import (
|
||||
localbk "github.com/cloudwego/eino-ext/adk/backend/local"
|
||||
"github.com/cloudwego/eino/adk/prebuilt/deep"
|
||||
localbk "github.com/cloudwego/eino-ext/adk/backend/local"
|
||||
"github.com/cloudwego/eino/adk/prebuilt/deep"
|
||||
)
|
||||
|
||||
// 创建 LocalBackend
|
||||
// 第一步:创建 LocalBackend —— 文件系统能力的实际执行者
|
||||
backend, err := localbk.NewBackend(ctx, &localbk.Config{})
|
||||
|
||||
// 创建 DeepAgent,自动注册文件系统工具
|
||||
// 第二步:将 backend 注入 DeepAgent,它会自动注册文件相关 Tool
|
||||
agent, err := deep.New(ctx, &deep.Config{
|
||||
Name: "Ch04ToolAgent",
|
||||
Description: "ChatWithDoc agent with filesystem access via LocalBackend.",
|
||||
ChatModel: cm,
|
||||
Instruction: instruction,
|
||||
Backend: backend, // 提供文件系统操作能力
|
||||
StreamingShell: backend, // 提供命令执行能力
|
||||
MaxIteration: 50,
|
||||
Name: "Ch04ToolAgent", // Agent 的名称
|
||||
Description: "ChatWithDoc agent with filesystem access.",
|
||||
ChatModel: cm, // 底层大模型
|
||||
Instruction: instruction, // 系统提示词
|
||||
Backend: backend, // 文件系统操作能力
|
||||
StreamingShell: backend, // 命令执行能力
|
||||
MaxIteration: 50, // 最大思考-行动循环次数
|
||||
})
|
||||
```
|
||||
|
||||
> [!note] MaxIteration 的含义
|
||||
>
|
||||
> 每次 Agent 「思考 → Tool Call → 观察结果」算一次迭代。设为 50 意味着最多允许 50 轮。如果达到上限仍未得到满意结果,会返回部分完成的内容。**设置过高会浪费 Token,过低则可能让 Agent 中途放弃**。后续章节会讨论如何优化这个值。
|
||||
|
||||
### DeepAgent 自动注册的工具
|
||||
|
||||
当配置了 `Backend` 和 `StreamingShell` 后,DeepAgent 会自动注册以下工具:
|
||||
当配置了 `Backend` 和 `StreamingShell` 后,DeepAgent 会自动注册以下工具:
|
||||
|
||||
- `read_file`: 读取文件内容
|
||||
- `write_file`: 写入文件内容
|
||||
- `edit_file`: 编辑文件内容
|
||||
- `glob`: 根据 glob 模式查找文件
|
||||
- `grep`: 在文件中搜索内容
|
||||
- `execute`: 执行 shell 命令
|
||||
| 工具名 | 对应 Backend 方法 | 用途 |
|
||||
|-------|------------------|------|
|
||||
| `read_file` | `Read` | 读取文件内容 |
|
||||
| `write_file` | `Write` | 写入文件内容 |
|
||||
| `edit_file` | `Edit` | 编辑文件内容 |
|
||||
| `glob` | `GlobInfo` | 根据 glob 模式查找文件 |
|
||||
| `grep` | `GrepRaw` | 在文件中搜索内容 |
|
||||
| `execute` | shell 命令 | 执行 shell 命令 |
|
||||
|
||||
> [!note] 从接口到 Tool 的映射
|
||||
>
|
||||
> Backend 定义了 6 个方法(LsInfo / Read / GrepRaw / GlobInfo / Write / Edit),但 DeepAgent 只注册了 5 个 Tool(少了 LsInfo)。这是因为 `glob` 已经能完成目录探索的需求。如果未来需要更详细的列表信息,可以手动补充 LsInfo 对应的 Tool。
|
||||
|
||||
## 代码位置
|
||||
|
||||
@@ -221,17 +258,27 @@ go run ./cmd/ch04
|
||||
|
||||
**推荐的三仓库目录结构(如要完整体验):**
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
ER[eino 核心库\nPROJECT_ROOT] --> ADK[adk/]
|
||||
ER --> COMP[components/]
|
||||
ER --> COMPOSE[compose/]
|
||||
ER --> EXT[eino-ext 扩展库]
|
||||
ER --> EX[eino-examples 示例库]
|
||||
EX --> QS[quickstart/]
|
||||
QS --> CW[chatwitheino / 本示例]
|
||||
|
||||
style ER fill:#e3f2fd
|
||||
style CW fill:#fff3e0
|
||||
```
|
||||
eino/ # PROJECT_ROOT(Eino 核心库)
|
||||
├── adk/
|
||||
├── components/
|
||||
├── compose/
|
||||
├── ext/ # eino-ext(扩展组件,如 OpenAI、Ark 等实现)
|
||||
├── examples/ # eino-examples(本仓库,本示例所在位置)
|
||||
│ └── quickstart/
|
||||
│ └── chatwitheino/
|
||||
└── ...
|
||||
```
|
||||
|
||||
> [!example] PROJECT_ROOT 的两种用法
|
||||
>
|
||||
> **场景一:快速验证**(不设置)
|
||||
> Agent 只能访问 `chatwitheino` 目录下的文件,适合学习当前示例的代码结构。
|
||||
>
|
||||
> **场景二:完整对话**(设置 `export PROJECT_ROOT=/path/to/eino`)
|
||||
> Agent 可以搜索 Eino 框架全部源码——比如查找某个 API 的实现细节、阅读组件设计思路等。这是 ChatWithEino 真正「与文档对话」的价值所在。
|
||||
|
||||
可以使用 `dev_setup.sh` 脚本自动设置上述目录结构:
|
||||
|
||||
@@ -264,66 +311,85 @@ you> 读取 main.go 文件的内容
|
||||
|
||||
## Tool 调用流程
|
||||
|
||||
当 Agent 需要调用 Tool 时:
|
||||
当 Agent 需要调用 Tool 时,内部会经历以下循环。你可以把整个过程理解为「思考 → 行动 → 观察」的闭环:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
U[用户提问] --> A{Agent\n分析意图}
|
||||
A -->|纯对话| R[直接回复]
|
||||
A -->|需要工具| T1[生成 Tool Call\n参数 JSON]
|
||||
T1 --> T2[执行 Tool\n读取/写入/搜索等]
|
||||
T2 --> T3[返回 Tool Result]
|
||||
T3 --> A2{Agent\n整合信息}
|
||||
A2 --> R2[生成最终回复]
|
||||
R2 --> U2[回复用户]
|
||||
|
||||
style A fill:#e1f5fe
|
||||
style T2 fill:#fff3e0
|
||||
style T3 fill:#e8f5e9
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 用户:列出当前目录的文件 │
|
||||
└─────────────────────────────────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ Agent 分析意图 │
|
||||
│ 决定调用 glob 工具 │
|
||||
└──────────────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ 生成 Tool Call │
|
||||
│ {"pattern": "*"} │
|
||||
└──────────────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ 执行 Tool │
|
||||
│ glob("*") │
|
||||
└──────────────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ 返回 Tool Result │
|
||||
│ {"files": [...]} │
|
||||
└──────────────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ Agent 生成回复 │
|
||||
│ "找到 5 个文件..." │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
**以"列出当前目录的文件"为例:**
|
||||
|
||||
> [!example] 逐步拆解
|
||||
>
|
||||
> **Step 1 — 意图识别**
|
||||
> 用户说"列出文件",Agent 判断这不是纯对话请求,而是文件系统操作意图。
|
||||
>
|
||||
> **Step 2 — 工具选择与参数生成**
|
||||
> Agent 从可用工具中选择 `glob`(查找文件列表),生成参数 `{"pattern": "*"}`。
|
||||
>
|
||||
> **Step 3 — Tool 执行**
|
||||
> `ToolsNode` 接收 JSON 参数,反序列化后调用 `GlobInfo`,将结果序列化为 JSON 返回。
|
||||
>
|
||||
> **Step 4 — 结果整合**
|
||||
> Agent 收到 `["main.go", "go.mod", ...]`,整理成自然语言回复:"找到 5 个文件..."。
|
||||
|
||||
你是否有想过——Agent 是如何知道该选哪个工具的?关键在于 `BaseTool.Info()` 返回的 **元信息**(名称、描述、参数 schema)。ChatModel 基于这些信息来决定调用哪个 Tool 以及传入什么参数。这就是后面会详细展开的 Function Calling 机制。
|
||||
|
||||
## 本章小结
|
||||
|
||||
- **Tool**:Agent 的能力扩展,让 Agent 能够执行具体操作
|
||||
- **Backend**:文件系统操作的抽象接口,提供统一的文件操作能力
|
||||
- **LocalBackend**:Backend 的本地文件系统实现,直接访问操作系统文件系统
|
||||
- **DeepAgent**:预构建的高级 Agent,提供 Backend 和 StreamingShell 的一级配置
|
||||
- **自动注册工具**:配置 Backend 后自动注册文件系统工具
|
||||
- **Tool 调用流程**:Agent 分析意图 → 生成 Tool Call → 执行 Tool → 返回结果 → 生成回复
|
||||
| 概念 | 一句话理解 |
|
||||
|------|-----------|
|
||||
| **Tool** | Agent 的能力扩展,让它能执行具体操作而非仅对话 |
|
||||
| **Backend** | 文件系统操作的抽象接口,定义发现、检索、修改三类方法 |
|
||||
| **LocalBackend** | Backend 的本地实现,开箱即用且路径安全 |
|
||||
| **DeepAgent** | 预构建的高级 Agent,配置 Backend 即可自动获得文件能力 |
|
||||
| **自动注册** | 声明式配置优于命令式组装——传一个 Backend 就得到五个工具 |
|
||||
| **调用流程** | 意图分析 → Tool Call → 执行 → 结果 → 回复(闭环迭代) |
|
||||
|
||||
## 扩展思考
|
||||
|
||||
**其他 Tool 类型:**
|
||||
### 其他 Tool 类型
|
||||
|
||||
- HTTP Tool:调用外部 API
|
||||
- Database Tool:查询数据库
|
||||
- Calculator Tool:执行计算
|
||||
- Code Executor Tool:运行代码
|
||||
当前我们只用了文件系统相关 Tool。Eino 生态中还支持更多类型:
|
||||
|
||||
**其他 Backend 实现:**
|
||||
- **HTTP Tool**:调用外部 API,让 Agent 具备联网能力
|
||||
- **Database Tool**:查询数据库,适用于数据分析场景
|
||||
- **Calculator Tool**:精确计算,弥补大模型不擅长数学的问题
|
||||
- **Code Executor Tool**:运行代码,适合生成并验证算法实现
|
||||
|
||||
- 可以基于 Backend 接口实现其他存储后端
|
||||
- 例如:云存储、数据库存储等
|
||||
- LocalBackend 已经提供了完整的文件系统操作能力
|
||||
### 自定义 Tool 创建
|
||||
|
||||
**自定义 Tool 创建:**
|
||||
除了使用 DeepAgent 自动注册的 Tool,你还可以手动创建。最简单的方式是使用 `utils.InferTool` 从函数签名自动推断参数 schema:
|
||||
|
||||
如果需要创建自定义 Tool,可以使用 `utils.InferTool` 从函数自动推断。详见:
|
||||
```go
|
||||
// 写一个普通 Go 函数...
|
||||
func Greet(name string) string {
|
||||
return fmt.Sprintf("Hello, %s!", name)
|
||||
}
|
||||
|
||||
// ...一行代码转成 Tool
|
||||
greetTool := utils.InferTool(Greet)
|
||||
```
|
||||
|
||||
如果你想了解更多,详见:
|
||||
|
||||
- [Tool 接口文档](https://github.com/cloudwego/eino/tree/main/components/tool)
|
||||
- [Tool 创建示例](https://github.com/cloudwego/eino-examples/tree/main/components/tool)
|
||||
|
||||
## 关联笔记
|
||||
|
||||
- [[Eino/quick_start/_index]]
|
||||
- [[Eino/quick_start/chapter_03_memory_and_session]] — Agent 的记忆与会话管理(上一章)
|
||||
- [[Eino/quick_start/chapter_05_middleware]] — Tool 调用中间件与拦截器(下一章)
|
||||
|
||||
Reference in New Issue
Block a user