Chapter 9: Skill Middleware
Goal of this chapter: on top of Chapter 8 (RAG + Interrupt/Resume + Checkpoint), introduce the skill package, use skill middleware to inject and manage skills, so the Agent can discover and load a set of reusable skill documents (SKILL.md) and invoke them via tool calls when needed.
Code Location
- Entry: cmd/ch09/main.go
- Sync script: scripts/sync_eino_ext_skills.go
Prerequisites
- Same as Chapter 1: configure a working ChatModel (OpenAI or Ark)
- Prepare the skills documents provided by the
eino-extPR (eino-guide/eino-component/eino-compose/eino-agent)
skill middleware supports plugging in various skills. This chapter only uses the four eino-related skills as an example to demonstrate how to use skill middleware to integrate skills. Why these four?
ChatWithEino is positioned as “help users learn the Eino framework and assist with writing Eino code using AI.” These four skill documents cover exactly the key knowledge areas needed for this goal.
Skill sources can be:
- The local path to the
eino-extrepository (the script reads<src>/skills/...automatically) - Or a directory where skills are already installed (containing the above subdirectories)
From Graph Tool to Skill: Why “Skill Docs”
Chapter 8 solves “how to make a complex workflow callable as a Tool” (Graph Tool). But when building an agent for framework-learning/development assistance, you encounter another type of problem: how to inject stable, reusable knowledge and instructions into the Agent, and let it load them on demand at runtime.
That is the role of Skills:
- Tool is more like an “action/capability”: read files, run workflows, call external systems
- Skill is more like a “reusable knowledge/instruction pack”: a set of markdown files (
SKILL.md+reference/*.md) describing “how to do something”
And Skill middleware is responsible for integrating skills into the agent. After registering the skill middleware, the Agent can read a specific Skill on demand via the skill tool.
Simple analogy:
- Tool = “what you can do” (function/interface)
- Skill = “how to do it” (reusable handbook/manual)
Run
In the quickstart/chatwitheino directory:
1) Sync eino-ext skills to a local directory
To let the skill middleware “discover” these skills, place them under a unified directory following the scan convention:
EINO_EXT_SKILLS_DIR/<skillName>/SKILL.md
Sync command (recommended):
go run ./scripts/sync_eino_ext_skills.go -src /path/to/eino-ext -dest ./skills/eino-ext -clean
Notes:
-srcsupports two forms:- The root of the
eino-extrepository (the script reads<src>/skills/...automatically) - A directory where skills are already installed (should contain
eino-guide/,eino-component/, etc.)
- The root of the
-destdefaults to./skills/eino-ext(can be omitted)
2) Start Chapter 9
export EINO_EXT_SKILLS_DIR=/absolute/path/to/chatwitheino/skills/eino-ext
go run ./cmd/ch09
Output example (snippet):
Skills dir: /.../skills/eino-ext
Enter your message (empty line to exit):
Enable Skill in DeepAgent
Skill invocation does not happen automatically. You must register the Skill middleware when building the Agent. The core setup is three steps:
- Use a local filesystem backend (this chapter uses
eino-ext/adk/backend/local) to provide file reading/Glob capability - Use
skill.NewBackendFromFilesystemto turnEINO_EXT_SKILLS_DIRinto a Skill Backend - Use
skill.NewTyped[M]to create a genericSkill middlewareand attach it to DeepAgent’sHandlers
Key code snippet (note: this is simplified and not directly runnable; see cmd/ch09/main.go for full code):
backend, _ := localbk.NewBackend(ctx, &localbk.Config{})
skillBackend, _ := skill.NewBackendFromFilesystem(ctx, &skill.BackendFromFilesystemConfig{
Backend: backend,
BaseDir: skillsDir, // = $EINO_EXT_SKILLS_DIR
})
skillMiddleware, _ := skill.NewTyped[M](ctx, &skill.TypedConfig[M]{
Backend: skillBackend,
})
agent, _ := deep.NewTyped[M](ctx, &deep.TypedConfig[M]{
ChatModel: cm,
Backend: backend,
StreamingShell: backend,
Handlers: []adk.TypedChatModelAgentMiddleware[M]{
skillMiddleware,
// ... other middlewares like approval/safeTool/retry
},
})
Additional notes:
- This quickstart checks
EINO_EXT_SKILLS_DIRexistence at runtime to ensure “it runs even without skills configured”: if the directory exists, it registersskillMiddleware; otherwise it skips it (the agent still works and can use RAG tools). - The Skill tool’s input is JSON:
{"skill": "<skillName>"}, e.g.{"skill":"eino-guide"}.
Quick Verification (Recommended)
After startup, send a prompt that explicitly asks the model to call the skill tool (to verify skills are discovered and loadable):
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:
[tool result] Launching skill: eino-guide- Tool result includes
Base directory for this skill: .../eino-guide
What You Will See
- When the model calls the skill tool, the console prints:
[tool call] ...[tool result] ...(truncated for display)
- Sessions are saved to
./data/sessions_agenticby default and support resumption:go run ./cmd/ch09 --session <id>