You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
6.0 KiB
Markdown

---
title: "Chapter 9: Skill (Console)"
---
The goal of this chapter is to build on Chapter 8 (RAG + Interrupt/Resume + Checkpoint) by introducing the `skill` middleware, enabling the Agent to discover and load a set of reusable skill documents (`SKILL.md`) and use them via tool calls when needed.
## Code Location
- Entry code: [cmd/ch09/main.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/cmd/ch09/main.go)
- Sync script: [scripts/sync_eino_ext_skills.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/scripts/sync_eino_ext_skills.go)
## Prerequisites
- Same as Chapter 1: you need to configure an available ChatModel (OpenAI or Ark)
- Have the skills from the `eino-ext` PR ready (`eino-guide` / `eino-component` / `eino-compose` / `eino-agent`)
Why these four?
ChatWithEino is positioned as "helping users learn the Eino framework and try writing Eino code with AI assistance". These four skills cover exactly the key knowledge areas needed for this goal:
- `eino-guide`: Learning entry point and navigation (where to start, how to get up and running quickly)
- `eino-component`: Component interfaces and various implementation references (Model/Embedding/Retriever/Tool/Callback, etc.)
- `eino-compose`: Orchestration and deterministic workflow references (Graph/Chain/Workflow, etc.)
- `eino-agent`: ADK/Agent-related references (Agent, Runner, Middleware, Filesystem, Human-in-the-loop, etc.)
Skills can come from:
- A local path to the `eino-ext` repository (the script will automatically read from `<src>/skills/...`)
- Or a directory where you've already installed the skills (the directory should contain subdirectories like the four mentioned above)
## From Graph Tool to Skill: Why We Need "Skill Documents"
Chapter 8 addressed "how to turn a complex workflow into a callable Tool" (Graph Tool). But when building an Agent for framework learning/development assistance, you'll encounter another type of problem: **How do you inject a set of stable, reusable knowledge and instructions into an Agent and let it load them on demand at runtime?**
This is the role of Skills:
- **Tools** are more like "actions/capabilities": read files, run workflows, call external systems
- **Skills** are more like "reusable knowledge/instruction packages": described by a set of markdown files (`SKILL.md` + `reference/*.md`) that explain "how to do a certain type of thing"
Simple analogy:
- **Tool** = "what it can do" (function/interface)
- **Skill** = "how to do it" (reusable manual/operations guide)
## Running
In the `quickstart/chatwitheino` directory, run:
### 1) Sync eino-ext Skills to a Local Directory
For the `skill` middleware to "discover" these skills, they need to be placed in a unified directory that follows the scanning convention:
- `EINO_EXT_SKILLS_DIR/<skillName>/SKILL.md`
Sync command (recommended):
```bash
go run ./scripts/sync_eino_ext_skills.go -src /path/to/eino-ext -dest ./skills/eino-ext -clean
```
Notes:
- `-src` supports two forms:
- The `eino-ext` repository root directory (the script will automatically read from `<src>/skills/...`)
- A directory where you've already installed skills (should contain subdirectories like `eino-guide/`, `eino-component/`, etc.)
- `-dest` defaults to `./skills/eino-ext` (can be omitted)
### 2) Start Chapter 9
```bash
EINO_EXT_SKILLS_DIR=/absolute/path/to/chatwitheino/skills/eino-ext go run ./cmd/ch09
```
Output example (excerpt):
```text
Skills dir: /.../skills/eino-ext
Enter your message (empty line to exit):
```
## Enabling Skills in DeepAgent
The "Skills can be called" behavior in this chapter doesn't happen automatically — you need to register the `skill` middleware when building the Agent. The core process is three steps:
1. Use a local filesystem backend (this chapter uses `eino-ext/adk/backend/local`) to provide file reading/Glob capabilities
2. Use `skill.NewBackendFromFilesystem` to turn `EINO_EXT_SKILLS_DIR` into a Skill Backend
3. Use `skill.NewMiddleware` to generate the middleware and add it to DeepAgent's `Handlers`
**Key code snippet (Note: this is a simplified code snippet that cannot be run directly. For the complete code, please refer to** [cmd/ch09/main.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/cmd/ch09/main.go)**)**:
```go
backend, _ := localbk.NewBackend(ctx, &localbk.Config{})
skillBackend, _ := skill.NewBackendFromFilesystem(ctx, &skill.BackendFromFilesystemConfig{
Backend: backend,
BaseDir: skillsDir, // = $EINO_EXT_SKILLS_DIR
})
skillMiddleware, _ := skill.NewMiddleware(ctx, &skill.Config{
Backend: skillBackend,
})
agent, _ := deep.New(ctx, &deep.Config{
ChatModel: cm,
Backend: backend,
StreamingShell: backend,
Handlers: []adk.ChatModelAgentMiddleware{
skillMiddleware,
// ... other middleware, such as approval/safeTool/retry, etc.
},
})
```
Additional notes:
- To ensure this quickstart "works even without configured skills", the code checks for the existence of `EINO_EXT_SKILLS_DIR`: `skillMiddleware` is only registered if the directory exists; otherwise it's skipped (you can still chat and use RAG tools in that case).
- The Skill tool's input is a JSON object: `{"skill": "<skillName>"}`, for example `{"skill":"eino-guide"}`.
## Quick Verification (Recommended)
After starting, enter a command that explicitly asks the model to call the skill tool (to verify that skills have been discovered and can be loaded):
```text
Use the skill tool with skill="eino-guide" and tell me what the entry point is for getting started.
```
You should see output similar to the following in the console:
- `[tool result] Launching skill: eino-guide`
- The tool result contains `Base directory for this skill: .../eino-guide`
## What You'll See
- When the model calls the skill tool, the console will print:
- `[tool call] ...`
- `[tool result] ...` (results are truncated for display)
- Sessions are saved in `SESSION_DIR` (default `./data/sessions`), with recovery support:
- `go run ./cmd/ch09 --session <id>`