feat(skill): multi-provider image generation with auto-fallback

- Add Gemini, Seedream (Volcengine Ark), Qwen (DashScope), MiniMax
  providers to image-generation skill with universal sequential
  fallback: OpenAI → Gemini → Seedream → Qwen → MiniMax → LinkAI
- Each provider filters unsupported size tiers to valid values
  (e.g. Seedream 1K→2K, Qwen 3K→2K, Gemini 3K→2K)
- Pinned model only tries its native provider; auto-routing uses
  each provider's default model
- Support skill-namespaced config (config.skill.image-generation.model
  → SKILL_IMAGE_GENERATION_MODEL env var)
- Add image lightbox (click-to-enlarge) in web console
- Add  docs for built-in skills (skill-creator, knowledge-wiki,
  image-generation) under docs/skills/
This commit is contained in:
zhayujie
2026-04-23 12:39:39 +08:00
parent 81e8bb62ae
commit 68ce2e5232
16 changed files with 2189 additions and 84 deletions

View File

@@ -0,0 +1,160 @@
---
title: image-generation - 图像生成
description: 文生图 / 图生图 / 多图融合,支持多家厂商自动路由与回退
---
通用的图像生成与编辑技能,支持 OpenAI、Gemini、Seedream火山方舟、Qwen百炼、MiniMax、LinkAI 共六家厂商。不需要手动选模型,脚本会按固定优先级自动挑选已配置的厂商来出图。
## 模型选择
`image-generation` 采用「固定优先级 + 自动回退」的策略,配好 Key 就能用:
1. **优先级顺序**`OpenAI → Gemini → Seedream → Qwen → MiniMax → LinkAI`
2. **没配 Key 的跳过**:只有设了 API Key 的厂商才会参与
3. **失败自动切下一家**:遇到 401、模型未开通、网络异常等错误时会自动试下一个
4. **指定模型时前置**:如果明确传了某个模型名,对应厂商会被提到最前面先试
### 支持的模型
| 厂商 | 模型 / 别名 | 特点 |
| --- | --- | --- |
| OpenAI | `gpt-image-2`、`gpt-image-1` | 通用文生图,高质量、高智能,支持 `quality` 参数控制画质 |
| Gemini Nano Banana | `nano-banana-2`、`nano-banana-pro`、`nano-banana` | 对应 `gemini-3.1-flash`、`gemini-3-pro`、`gemini-2.5-flash` 的图像版本 |
| Seedream火山方舟 | `seedream-5.0-lite`、`seedream-4.5` | 原生 2K4K最多 14 张图融合 |
| Qwen百炼 | `qwen-image-2.0`、`qwen-image-2.0-pro` | 擅长中文排版和图文融合 |
| MiniMax | `image-01` | 简单快速的图片生成 |
| LinkAI | 任意模型 | 通用代理,兜底用 |
<Note>
默认情况下 Agent 不会主动选模型,而是走自动路由。如果你想用某个特定模型,直接在对话里说就行,比如「用 seedream 画一只猫」或「用 gpt-image-2 生成海报」。也可以通过下面的「自定义配置」固定默认模型。
</Note>
## 自定义配置
### API Key 配置
至少需要配**一个**厂商的 Key配多个就能享受自动回退能力。有三种配置方式
#### 方式一:已有模型 Key 自动复用
如果你在 web控制台 或 `config.json` 中配置了对话模型的 Key比如 `openai_api_key`、`gemini_api_key` 等),启动时这些 Key 会被**自动同步**到对应的环境变量。也就是说,只要你的对话模型能用,图像生成就能直接用同一个 Key不需要额外配置。
#### 方式二:在 config.json 中配置
在 `config.json` 中直接写对应的 Key 字段即可,支持的字段如下:
```json
{
"openai_api_key": "sk-xxx",
"openai_api_base": "https://api.openai.com/v1",
"gemini_api_key": "AIza-xxx",
"ark_api_key": "xxx",
"dashscope_api_key": "sk-xxx",
"minimax_api_key": "xxx",
"linkai_api_key": "xxx"
}
```
修改后需要重启生效。每个 Key 还有对应的 `*_api_base` 字段可以自定义接口地址。
#### 方式三:对话中直接配置
在对话里发送 API KeyAgent 会通过 `env_config` 工具自动保存到 `~/cow/.env`**不需要重启**就能生效。例如:
```
帮我配置 OPENAI_API_KEY 为 sk-xxx
```
或者:
```
设置 ARK_API_KEY 为 xxx
```
### API Key 一览
| 环境变量 | config.json 字段 | 对应厂商 | 默认 Base URL |
| --- | --- | --- | --- |
| `OPENAI_API_KEY` | `openai_api_key` | OpenAI | `https://api.openai.com/v1` |
| `GEMINI_API_KEY` | `gemini_api_key` | Gemini | `https://generativelanguage.googleapis.com` |
| `ARK_API_KEY` | `ark_api_key` | 火山方舟Seedream | `https://ark.cn-beijing.volces.com/api/v3` |
| `DASHSCOPE_API_KEY` | `dashscope_api_key` | 阿里百炼Qwen | `https://dashscope.aliyuncs.com` |
| `MINIMAX_API_KEY` | `minimax_api_key` | MiniMax | `https://api.minimaxi.com` |
| `LINKAI_API_KEY` | `linkai_api_key` | LinkAI | `https://api.link-ai.tech` |
### 指定默认模型
如果想让所有图像生成固定走某个厂商的模型,可以在 `config.json` 里加:
```json
"skill": {
"image-generation": {
"model": "seedream-5.0-lite"
}
}
```
启动时这段配置会被自动转成环境变量 `SKILL_IMAGE_GENERATION_MODEL`,脚本读到后会固定使用这个模型所在的厂商进行生成。
## 开启和关闭
`image-generation` 是内置技能,**会根据 API Key 自动调整状态**
- **Key 已配置**技能正常可用Agent 收到画图请求时会直接调用
- **Key 未配置**技能仍然会出现在上下文中标记为「需要配置」Agent 会引导用户去配 Key而不是直接调用失败
如果想手动控制,也可以用命令:
```text
/skill disable image-generation # 手动关闭(即使有 Key 也不会被调用)
/skill enable image-generation # 重新开启
```
终端里对应的命令是 `cow skill disable image-generation` / `cow skill enable image-generation`。
## 参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
| --- | --- | --- | --- | --- |
| `prompt` | string | 是 | — | 图像描述 |
| `image_url` | string / list | 否 | null | 编辑用的输入图,支持本地路径或 URL。传多个就是多图融合 |
| `quality` | string | 否 | auto | `low` / `medium` / `high`,只有部分厂商支持 |
| `size` | string | 否 | auto | `512` / `1K` / `2K` / `3K` / `4K`,也可以写像素值如 `1024x1024` |
| `aspect_ratio` | string | 否 | null | `1:1` / `3:2` / `2:3` / `16:9` / `9:16` / `21:9`Gemini 还支持 `1:4` / `4:1` / `1:8` / `8:1` |
<Warning>
**质量越高、分辨率越大,花的钱越多、等的时间越长。**
- 日常对话和快速预览直接用默认(`auto`),或者 `quality=low` + `size=1K`,大概 20 秒出图
- 做海报、用户明确要高清的时候再上 `quality=high` + `size=2K/4K`,可能要等 15 分钟,取决于不同模型的速度
</Warning>
## 输出
成功时返回:
```json
{
"model": "doubao-seedream-5-0-260128",
"images": [
{"url": "/path/to/output.png"}
]
}
```
失败时返回 `{ "error": "..." }`。出错后**不要直接重试**——大概率是配置问题Key 填错、API 地址不对、模型没开通),让用户修好配置再试。
## 常见用法
- **文生图**:根据描述生成插画、海报、图标、头像、分镜图等
- **图生图**:在已有图片上改风格、换元素、加装饰、加文字等
- **多图融合**:把多张参考图合成一张(换装、角色合影等)
<Note>
- bash 超时建议设 600 秒。单个厂商的 HTTP 超时是 300 秒,但脚本可能依次尝试多个厂商
- 输入的图片会自动压缩到 4MB 以内、最长边不超过 4096px
- Gemini / Seedream / Qwen / MiniMax 不支持 `quality` 参数,传了也没用
- Seedream 默认出 2K 图,`seedream-5.0-lite` 支持到 3K`seedream-4.5` 支持到 4K
</Note>

View File

@@ -0,0 +1,112 @@
---
title: knowledge-wiki - 知识库
description: 维护本地结构化知识库,自动归档、分类和交叉引用
---
帮你把对话中产生的资料、灵感和零散笔记整理成结构化的本地知识库,自动维护索引和页面之间的交叉引用。
`knowledge-wiki` 在工作空间下维护一个 `knowledge/` 目录,相当于 Agent 的「外脑」。技能设置了 `always: true`,会**常驻上下文**,不需要任何外部依赖。
## 什么时候会触发
- 你分享了一篇文章、一份文档或一个 URL想要沉淀下来
- 聊天过程中聊出了值得长期保留的结论
- 你想查一下之前积累过的知识
## 目录结构
```
knowledge/
├── index.md # 全局索引(必须维护)
├── log.md # 操作日志(只追加)
└── <category>/ # 分类子目录(按内容自由分组)
└── <slug>.md # 知识页(文件名用小写加中划线)
```
## 三个核心操作
### 1. 收录Ingest
你分享了一段资料时Agent 会:
1. 读懂原文,提取关键信息
2. 按内容决定放到哪个分类下——先看 `index.md` 里有没有合适的分类,没有就新建一个
3. 生成知识页 `knowledge/<category>/<slug>.md`
4. 更新索引 `index.md` 和日志 `log.md`
### 2. 综合Synthesize
聊天中产生了新的结论或洞见时:
1. 在合适的分类下创建新知识页
2. 给相关的已有页面加上互相指向的链接
3. 更新索引和日志
### 3. 查询Query
你问到以前积累的知识时:
1. 先从 `index.md` 里找可能相关的页面
2. 用 `read` 工具打开具体页面
3. 需要时再用 `memory_search` 补充检索
4. 回答里会带上知识页的链接,方便你点过去看原文
## 知识页怎么写
```markdown
# 页面标题
> Source: <来源 URL 或简要说明>
正文内容。页面之间用相对路径链接:
[相关页](../category/related-page.md)
## 要点
- ...
## 相关页面
- [页面 A](../category/page-a.md) — 为什么相关
```
<Note>
- `> Source:` 用来记录这条知识的来源。有明确来源时一定要写
- 交叉引用很重要:创建或更新某页时,记得也去关联页面里补上反向链接
- **只链接已经存在的页面**。如果某个概念值得单独成页,先建好再加链接
</Note>
## 索引格式
`knowledge/index.md` 采用扁平列表,按分类分组,每个知识页占一行:
```markdown
# Knowledge Index
## 分类 A
- [页面标题](category-a/page-slug.md) — 一句话摘要
## 分类 B
- [页面标题](category-b/page-slug.md) — 一句话摘要
```
不用表格,不加 emoji。分类怎么起名、怎么组织都可以灵活调整。
## 日志格式
`knowledge/log.md` 只追加、不修改,最新的写在最下面:
```markdown
## [YYYY-MM-DD] ingest | 页面标题
## [YYYY-MM-DD] synthesize | 页面标题
```
## 写作约定
- **文件名**用小写加中划线,比如 `machine-learning.md`
- **一页只讲一件事**,需要关联的内容通过链接串起来
- **有了就更新,不要重复建页**
- **每次改完都要更新索引** `knowledge/index.md`
- **写精华别抄全文**,抓住要点就行
- **对话里引用知识页时用完整路径**,比如 `[标题](knowledge/<category>/<slug>.md)`。页面之间互相链接才用相对路径
- **基于知识页回答问题时附上链接**,方便深入查阅

View File

@@ -0,0 +1,180 @@
---
title: skill-creator - 技能创建
description: 创建、安装、更新技能,规范 SKILL.md 写法与目录结构
---
`skill-creator` 是一个「元技能」,专门用来帮助 Agent 创建、安装和更新其他技能,确保所有技能的 `SKILL.md` 写法和目录结构保持一致。
## 什么时候会触发
- 用户想从 URL 或远程仓库安装一个技能
- 用户想从头创建一个全新的技能
- 需要升级或重构已有技能
## 技能是什么
简单来说,技能就是一份「可复用的说明书」加上可选的脚本和资源。它给 Agent 注入了某个领域的专业知识,让 Agent 在遇到对应任务时能像专家一样处理。
一个技能通常包含以下内容:
1. **专项工作流** — 某类任务的完整步骤
2. **工具用法** — 怎么调某种 API 或处理某种文件
3. **领域知识** — 团队约定、业务规则、数据结构之类
4. **附带资源** — 脚本、参考文档、模板等
<Note>
**核心原则:能省则省**。只写 Agent 自己想不到的内容,每加一行都要问自己:值不值得占这些 token
</Note>
## 目录结构
```
skill-name/
├── SKILL.md # 必需:技能定义
│ ├── YAML frontmatter必填 name / description
│ └── Markdown 正文(说明 + 示例)
└── 可选资源
├── scripts/ # 可执行脚本Python / Bash 等)
├── references/ # 内容较多的参考文档Agent 按需读取
└── assets/ # 模板、图标等,会直接用在输出里
```
## SKILL.md 规范定义
SKILL.md 文件头部的 `frontmatter` 字段:
| 字段 | 说明 |
| --- | --- |
| `name` | 技能名,小写加中划线,必须和目录名一致 |
| `description` | **最关键的字段**。写清楚「这个技能干什么」和「什么情况下该用它」Agent 看到这段来决定要不要调它。注意:所有触发相关的描述都放在这里,不要写到正文里 |
| `metadata.cowagent.requires.bins` | 系统里必须装了哪些命令行工具 |
| `metadata.cowagent.requires.env` | 需要哪些环境变量(全部满足才行) |
| `metadata.cowagent.requires.anyEnv` | 多个 API Key 满足一个就行 |
| `metadata.cowagent.requires.anyBins` | 多个工具满足一个就行 |
| `metadata.cowagent.always` | 设为 `true` 会始终加载,不检查依赖 |
| `metadata.cowagent.emoji` | 展示用的 emoji可选 |
| `metadata.cowagent.os` | 限定系统,如 `["darwin", "linux"]` |
<Note>
`category` 字段不需要手写,系统会自动设成 `skill`。
</Note>
声明 API Key 依赖有两种写法:
```yaml
metadata:
cowagent:
requires:
env: ["MYAPI_KEY"] # 必须有
```
```yaml
metadata:
cowagent:
requires:
anyEnv: ["OPENAI_API_KEY", "LINKAI_API_KEY"] # 有一个就行
```
**技能会自动按依赖启禁用**:环境变量齐了就自动启用,缺了就自动禁用,不需要手动 `/skill enable`。
## 资源目录怎么用
| 目录 | 放什么 | 不要放 |
| --- | --- | --- |
| `scripts/` | 需要反复执行的代码,或需要确定性结果的脚本 | 纯演示用的代码片段 |
| `references/` | **超过 500 行**、SKILL.md 实在塞不下的大文档(比如完整的数据库 Schema | 普通 API 文档、示例、教程 |
| `assets/` | 会出现在最终产物里的文件(模板、图标、样板代码等) | 说明性文档 |
<Warning>
**原则上所有内容都写在 `SKILL.md` 里**,只有确实放不下才拆到资源目录。
不要给技能加 `README.md`、`CHANGELOG.md`、`INSTALLATION_GUIDE.md` 之类的文件——全部放进 `SKILL.md`。资源目录里只放真正要跑的脚本或真正要用的素材。
</Warning>
## 安装外部技能
安装后最终落在 `<workspace>/skills/<name>/` 目录。
| 来源 | 怎么装 |
| --- | --- |
| URL单文件 | curl / web_fetch 直接拉 |
| URLzip 包) | 下载解压 |
| 本地 SKILL.md | 直接读 |
| 本地 zip 包 | 解压 |
安装步骤:
1. 找到 `SKILL.md`(可能在包的根目录或某个子目录里)
2. 从 frontmatter 里读出 `name`
3. 把**整个技能目录**(包括 `SKILL.md`、`scripts/`、`assets/` 等)复制到 `<workspace>/skills/<name>/`
4. 如果包里有 `INSTALL.md` 之类的安装脚本,照着跑一遍,但最终结果仍然要落在 `<workspace>/skills/<name>/` 下
## 从头创建技能
推荐按这个顺序来:
1. **搞清楚需求** — 让用户举几个具体的使用场景,一次别问太多
2. **想好结构** — 这个技能需要脚本吗?需要参考文档吗?需要模板素材吗?
3. **生成骨架** — 用初始化脚本:
```bash
scripts/init_skill.py <skill-name> --path <workspace>/skills [--resources scripts,references,assets] [--examples]
```
4. **填充内容** — 写好 SKILL.md、补上脚本和资源。脚本写完一定要实际跑一遍
5. **格式校验**(可选):
```bash
scripts/quick_validate.py <workspace>/skills/<skill-name>
```
6. **迭代完善** — 实际用起来之后根据反馈持续改进
## 命名规则
- 只用小写字母、数字和中划线。用户给的名字需要做标准化处理,比如 `Plan Mode` → `plan-mode`
- 长度别超过 64 个字符
- 尽量短、用动词开头、一看就知道干什么
- 必要时用工具名做前缀,比如 `gh-address-comments`、`linear-address-issue`
- 目录名和 `name` 字段必须完全一致
## 三级加载机制
技能不会一次性全部塞进上下文,而是分三级按需加载:
1. **元信息**`name` + `description`)— 常驻上下文,约 100 词。Agent 靠它判断「要不要用这个技能」
2. **SKILL.md 正文** — 确定要用了才加载,建议控制在 500 行以内
3. **资源文件** — Agent 需要的时候再读
如果一个技能涉及多个变体(比如多云厂商部署),建议这样组织:
```
cloud-deploy/
├── SKILL.md # 主流程和厂商选择逻辑
└── references/
├── aws.md
├── gcp.md
└── azure.md
```
用户选了 AWSAgent 只需要读 `aws.md`,不用把三家的文档全加载进来。
## 常见设计模式
**步骤式**:按编号列出操作步骤和对应脚本。
```markdown
1. 分析表单结构(运行 analyze_form.py
2. 生成字段映射(编辑 fields.json
3. 自动填充表单(运行 fill_form.py
```
**分支式**:根据用户意图走不同流程。
```markdown
1. 判断操作类型:
**新建内容?** → 走「创建流程」
**编辑已有内容?** → 走「编辑流程」
```
**模板式**:输出格式有严格要求时,在 SKILL.md 里直接给一个样板,让 Agent 照着写。