DSH Ark Toolkit
给 DeepSeek Harness 接上字节的生成能力:豆包 Seedream 文生图,加上豆包语音合成(TTS)。
🚀 一句提示词出图 | 原生 TypeScript 实现 | 字节火山方舟 | 开箱即用
亮点 | 快速开始 | 工具一览 | 配置与限制 | 常见问题 | 开发与社区
看图不用装插件。 DSH 0.1.5 起 DeepSeek 模型已经原生支持图片输入(inputModalities 含 image),识图、OCR、多图对比直接交给模型即可。Ark Toolkit 从 0.1.0 起只负责生成图片和合成语音。
亮点
- 豆包 Seedream 文生图。 内置
ark_generate_image 工具,直接用字节 Seedream 模型生成图片并交付为 Artifact,支持 1K/1.5K/2K 分辨率档位(或自定义宽高像素)、宽高比、反向提示词与模型别名。
- 字节 TTS 语音合成。
ark_speak 工具把文本变成语音(MP3/OGG/PCM/WAV),使用字节豆包语音合成模型 2.0,交付为工作区音频 Artifact(可用"打开文件"或结果里的路径访问)。
- 原生 TypeScript,零自带运行时依赖。 两个工具都直接调用字节服务的 HTTP 接口,图片尺寸探测直接解析容器头并校验结束标记(PNG/JPEG/GIF/WebP),不安装任何原生图像库,也不会把 DSH 宿主已有的包再装一份到 Profile 里,安装后即可使用。
- 默认接入字节火山方舟。 在 插件 → 已安装 → 火山引擎方舟工具包 的详情页里填入你自己的 Ark API Key 即可。
安装即可使用。 把火山方舟 API Key 保存为 ARK_API_KEY 这个 DSH Credential,把火山引擎语音合成 Token 保存为 VOLCENGINE_TTS_KEY。
本副本以 @my-bundles/ark-toolkit 的名字从本地目录安装(源码抄自上游 @nextnowlabs/dsh-ark-toolkit@0.1.6;本地包 version 另走 DSH 版本线,当前 0.2.0-rc.1。安装详情见 安装与配置指南):
dsh plugin --profile web add ~/.dsh/my-bundles/ark-toolkit
目录
适合谁用
- 想直接在对话里生成图片:海报、插画、图标、示意图。
- 想把一段文字变成可播放、可下载的语音。
随附的 ark-skills Skill 会告诉 Agent 何时用哪个工具,以及如何处理远程服务返回的内容。
快速开始:三步完成
详细的安装、火山方舟/TTS 配置与完整字段参考见 安装与配置指南。
1. 安装
本副本以 link: 方式从 ~/.dsh/my-bundles/ark-toolkit 装进 Web Profile:
dsh plugin --profile web add ~/.dsh/my-bundles/ark-toolkit
Headless Profile 同样安装:
dsh plugin --profile headless add ~/.dsh/my-bundles/ark-toolkit
为什么用本地路径而不是包名。 本目录的源码抄自上游 @nextnowlabs/dsh-ark-toolkit@0.1.6,包名已改为 @my-bundles/ark-toolkit 且 private: true:profile 用 link: 指向本目录,改完源码 npm run build 再让服务重读即可生效,全程不经过 registry。于是「插件 → 已安装」的更新卡片会显示 unsupported-install-source(本地安装不提供在线更新),那里给出的手动更新命令就是上面这条 dsh plugin add <本目录>。
想跟上游版本:npm view @nextnowlabs/dsh-ark-toolkit version(那个号只表示「抄自哪一版」,不是本目录的 version)。
本目录的 version 跟随所依赖的 DSH 版本线:<DSH 基础版本>-rc.<N>,当前 0.2.0-rc.1。 基线取本包 package.json 里 @deepseek-ai/dsh-* devDependency 钉死的精确版本去掉预发布段(当前全是 0.2.0-rc.2 → 0.2.0),即版本为 0.2.0-rc.N;同一基线上每发一版 N 加一,依赖线换到新的 DSH 版本(例如 0.2.1)则重置为 0.2.1-rc.1。规则实现与守卫在 scripts/version.mjs + tests/version.spec.ts,发版脚本默认 --bump current(发布 manifest 已声明的版本),patch/minor/major 会被明确拒绝;本地包名(@my-bundles/ark-toolkit,private: true)与发布包名(@nextnowlabs/dsh-ark-toolkit)解耦,唯一来源是 scripts/publish-identity.mjs(详见发布)。
版本要求:DSH 0.2.0-rc.2。 DSH 0.2.0 把每个 @deepseek-ai/dsh-* 包的 peer 依赖改成了同版本的精确声明(cordis ~4.0.4、schemastery ~3.18.4),本插件的 peer 也随之整线对齐 ^0.2.0-rc.2,因此在 0.1.7 及更早的 DSH 上无法满足 peer,Profile 安装阶段即会失败。配置模型沿用 0.1.7 引入的「插件在 profile 补丁里的那一行 config 就是它的设置,按 profile entry id 读写」;插件工具卡片同时跟进 0.2.0 的 preparing/start/result 三阶段契约。
配置页的座位也随 0.2.0 变了(本插件 0.1.5 起)。 plugins.item 现在渲染在「插件」页的官方分组里,是 DSH 官方设置页的座位——第三方插件注册它会显示成官方插件。第三方 bundle 自己的配置应注册 plugins.bundle.config(key = 安装的包名,表单内嵌在该 bundle 的详情页)或 plugins.row.config。本插件改用前者:,配置表单出现在 详情页。页面标题与简介由包内 / 的 提供(DSH 只从 读插件展示元数据), 与 会守住座位名、包名 key 与这份导出。
2. 重启并确认
重启正在运行的 Web Profile,在 插件 → 已安装 里打开 火山引擎方舟工具包 的详情页,配置表单就在这一页里。默认已配置字节火山方舟(Volcengine Ark)端点;在 API key 里填入你的 Ark Key(保存为 ARK_API_KEY 凭据)后点 Save and apply,再运行 Test API connection 确认连接。
3. 直接说你要做什么
调用 /ark-skills,然后例如:
用豆包 Seedream 生成一张戴帽子的橘猫插画。
生成一张 16:9 的山景日落图,2K 分辨率。
把这句中文读出来。
工具一览
插件提供 2 个可以单独调用、也可以组合使用的工具:
| 工具 | 最适合解决的问题 | 主要结果 |
|---|
ark_generate_image | "用字节 Seedream 生成一张图" | PNG/JPEG Artifact、宽高与格式 |
ark_speak | "用字节 TTS 把文本变成语音" | MP3/OGG/PCM/WAV 音频 Artifact |
ark_generate_image 的参数按当前在售的 Seedream 5.0 pro / flash 对齐:size 取 1K/1.5K/2K(默认 2K)或 宽x高(总像素 921600–4624220、宽高比 1/16–16,两种写法不可混用);aspectRatio 取官方像素表里的 8 个比例(1:1/4:3/3:4/16:9/9:16/3:2/2:3/21:9),并按所选档位换算成像素值发送。图片接口没有 aspect_ratio 字段,n、组图(sequential_image_generation)与流式输出对 5.0 pro / flash 也不可用。
工作原理
插件把生成任务交给配置的字节服务,本地只做必要的文件落盘与尺寸探测。
ark_generate_image 走 OpenAI 兼容 /images/generations(Ark),把提示词、分辨率与宽高比发给 Seedream,再把返回的图片(URL 或 base64)写成工作区产物。
ark_speak 走火山引擎语音技术的 TTS V3 单向 SSE 接口,逐块拼接音频后写成工作区产物。
- 生成图片的宽高与格式由插件自己解析容器头并校验结束标记得到(纯 Node,不依赖 sharp 等原生图像库),用于回报结果与构造 Artifact 描述。
- 远程服务返回的文本与元数据都属于不可信内容,模型不会把它们当作指令执行。
flowchart LR
Agent["Agent 选择任务"] --> Generate["ark_generate_image(Seedream 文生图)"]
Agent --> Speak["ark_speak(豆包语音合成)"]
Generate --> Artifact["Artifact 交付"]
Speak --> Artifact
Artifact --> Session["继续推理和行动"]
配置与限制
完整配置字段速查、Profile patch 示例和常见配置问题见 安装与配置指南。
默认使用字节火山方舟
默认配置只使用字节的服务:
Base URL: https://ark.cn-beijing.volces.com/api/v3
模型(文生图): doubao-seedream-5-0-flash-260915(Seedream 5.0 flash)
API Key: 你自己的火山方舟 Key,保存为 DSH Credential `ARK_API_KEY`
ark_generate_image 工具走 /images/generations,使用字节 Seedream 模型。Seedream 别名只有两个:seedream-5.0-flash(默认)、seedream-5.0-pro;其它版本(Seedream 5.0 lite、4.5、4.0 等)不再提供别名,需要时直接传完整 Ark 模型 ID。默认选 flash 是因为它和 Seedream 5.0 pro 的能力一致(文生图、参考图生图、交互编辑、图层拆分),但出图更快、价格更低;需要更强的位置与元素控制时传 seedream-5.0-pro。
配置自己的火山方舟 API Key
在 插件 → 已安装 → 火山引擎方舟工具包 详情页里填写你的火山方舟 API Key,插件会保存为 DSH Credential(默认名 ARK_API_KEY),Key 无论在页面还是配置里都不会回显。页面读写的配置就是 profile 补丁里 id: ark-toolkit 那一行的 config(DSH 0.1.7 引入、0.2.0 沿用,没有第二处存储),一次保存是一次带版本栅栏的原子写入,保存后 runtime 会就地重建,无需重启 Profile。
火山方舟图文教程: 申请火山方舟 API Key,并用豆包 Seedream 生成图片。教程包含账号与 Key 获取截图、Ark Toolkit 的准确配置,以及可直接使用的 cURL 示例。
也可以在 Profile patch 中配置:
- id: ark-toolkit
config:
provider:
baseUrl: https://ark.cn-beijing.volces.com/api/v3
credential: ARK_API_KEY
配置 TTS 语音合成(ark_speak)
ark_speak 工具走火山引擎语音技术的 TTS V3 接口(openspeech.bytedance.com 单向 SSE 流式),默认使用豆包语音合成模型 2.0(资源 ID seed-tts-2.0)。它使用独立的 TTS Key(App Token),与上面的 Ark API Key 不同:
| 字段 | 默认值 |
|---|
| TTS 端点 | https://openspeech.bytedance.com/api/v3/tts/unidirectional/sse |
| DSH Credential | VOLCENGINE_TTS_KEY(火山引擎控制台 → 语音技术 → 应用 → Token) |
| 资源 ID(App ID) | seed-tts-2.0 |
| 默认音色 | zh_female_shuangkuaisisi_uranus_bigtts(爽快思思 2.0) |
按上面的表把 TTS Token 保存为 VOLCENGINE_TTS_KEY 这个 DSH Credential 即可使用。想换端点/资源/默认音色,或改凭据名,可在 Profile patch 中配置:
- id: ark-toolkit
config:
provider:
tts:
baseUrl: https://openspeech.bytedance.com/api/v3/tts/unidirectional/sse
credential: VOLCENGINE_TTS_KEY
resource: seed-tts-2.0
voice: zh_female_shuangkuaisisi_uranus_bigtts
调用时还可以通过参数临时指定音色、格式(mp3/ogg_opus/pcm/wav)、采样率、语速、音量、音调、情感(happy/sad/neutral)和语言(zh-cn/en/ja)。完整音色列表见火山引擎官方《在线音色列表》(如 Vivi 2.0、小何 2.0、Tim 等)。
插件 → 已安装 → 火山引擎方舟工具包 详情页还可以调整超时、并发、凭据名与端点(折叠在 Advanced settings 里)。
常见问题
| 问题 | 处理方式 |
|---|
| 方舟返回 401/403 | 确认 ARK_API_KEY 已保存且没有多余空格;在火山引擎控制台 API Key 管理 重新创建 |
| 模型不存在或未开通 | 到火山方舟 模型广场 开通对应 Seedream 模型;模型 ID 以控制台为准 |
| 火山方舟返回 429/限流 | 按错误信息等待后重试;或在火山引擎控制台查看配额并升级额度 |
| 自定义 Credential 缺失 | 在 插件 → 已安装 → 火山引擎方舟工具包 详情页里填写 API Key,并确认 Credential 名称与配置一致 |
| 产物无法预览 | 使用"打开文件"或结果中的工作区路径;预览 URL 只在 Web 路由可用时存在 |
| 想生成图片却提示工具不存在 | 重启 Web Profile 并刷新页面,确认已加载 /ark-skills;卡片里应显示运行时就绪 |
启动日志报 ctx.settings.register is not a function | 插件版本落后于 DSH:0.1.2 起适配 DSH 0.1.7 的 entry 作用域配置模型,0.1.4 起要求 DSH 0.2.0-rc.2。本副本跟随当前 DSH,遇到该报错说明 profile 里装的是旧包:重新 dsh plugin --profile web add ~/.dsh/my-bundles/ark-toolkit 并把 DSH CLI 升到 0.2.0-rc.2 以上 |
| Profile 安装报 peer 版本不满足 | 插件的 peer 是 ^0.2.0-rc.2:把 DSH 升到 0.2.0-rc.2(npm install -g @deepseek-ai/dsh@0.2.0-rc.2),或把插件降回与旧 DSH 同线的 0.1.3 |
| 页面显示"配置不可用",但工具能用 | 该 Profile 没挂载 settings 服务,或插件不是从 profile 补丁行加载的;Ark 工具本身不依赖它,改配置请直接编辑该行的 config |
接入生成服务会显著增加成本吗?
不会。每次调用只把当前提示词或文本发给字节服务,调用之间不会累积上下文,因此额外成本很小。默认的 Seedream 与豆包语音合成都按量计费;想进一步降低成本,可以在火山引擎控制台关注免费额度或选购更经济的模型版本。
开发与社区
发布
scripts/publish.mjs 负责发布到 npmjs 官方 registry(脚本自动使用官方 registry 与仓库本地 .npm-cache/ 缓存,规避镜像源与 ~/.npm 只读导致的 EROFS)。
发布身份与本地身份是分开的,且全仓只有一处定义(scripts/publish-identity.mjs):
| 名字 | 用途 |
|---|
| 本地 | @my-bundles/ark-toolkit(private: true) | profile 用 link: 安装、cordis.patch.yml 与 plugins.bundle.config 的 key 都用它 |
| 发布 | @nextnowlabs/dsh-ark-toolkit | 上传到 npm 的包名(npm 拒绝 private: true 的包) |
身份引用一共三处,发布时全部改成发布名(否则消费者装上后插件静默不加载):
| 身份点 | 本地构建(link: 安装) | 发布(staging) |
|---|
cordis.patch.yml 的插件行 name:(以及任何 <包名>#<行 id> key、按包名解析的 !!js) | 本地包名 | staging 里 rewritePatchForPublish() 全量替换为发布名 |
客户端半 lib/client.js 的加载器模块 id、plugins.bundle.config 座位 key、样式标签 data-plugin、手动更新命令 | 构建期从 package.json.name 注入(src/client/index.tsx 只写占位标识符 CLIENT_IDENTITY_TOKEN,由 scripts/build-client.mjs 替换) | staging 里用发布名重新构建,注入发布名 |
宿主半的插件 name 导出、ARK_TOOLKIT_PACKAGE(profile 里的安装目录、dependencies key、registry 查询) | 运行时读自身 package.json(src/version.ts 的 PLUGIN_PACKAGE) | 同上,staging 的 manifest 已是发布名 |
因此发布从不就地改真实 package.json:脚本 mkdtempSync 出一份 staging 副本(排除 node_modules/.git/.npm-cache),先写改写后的 manifest(发布名、删 private)、再改写 cordis.patch.yml,然后把仓库真实 node_modules 软链进 staging 跑一次真实构建(npm run build,于是 lib/** 自然带发布名),最后在 staging 里 npm pack --dry-run + npm publish --ignore-scripts。门槛(build / 测试 / verify:portable)仍在真实目录先跑完。流程结束会断言真实 package.json 的 md5 前后一致。
staging 会重建 lib/,所以发布产物与仓库里 committed 的 lib/ 可能字节不同,这是预期的:committed lib/ 是本地身份(客户端 bundle 里是本地包名),发布产物是发布身份。别为了让两者一致去改 committed lib/;CI 只要求 committed lib/ 等于本地 npm run build 的输出。
staging 自检:打包前扫描 npm pack 实际会带上的每个文件,package.json / cordis.patch.yml / lib/** / locale/** 等被消费者加载的文件里本地名的出现次数必须为 0,否则中止发布并列出残留文件;只有散文(README.md / CHANGELOG.md / docs/** / *.md)允许提到本地名。tests/publish-identity.spec.ts 与 verify:portable 都守着「发布名只能出现在 publish-identity.mjs 一处」「src/** 不得硬编码任何一方身份」。
版本号不走上游的 patch/minor/major,而是跟随所依赖的 DSH 版本线 <base>-rc.<N>(base = package.json 里 @deepseek-ai/dsh-* devDependency 钉死的精确版本去掉预发布段,当前 0.2.0):同一基线上每发一版 N 加一,依赖线换到新的 DSH 版本则重置为 <base>-rc.1。规则实现在 scripts/version.mjs,由发版脚本、npm run verify:portable 与 tests/version.spec.ts 共用。默认 --bump current:发布 manifest(与最新 CHANGELOG 标题)已经声明的版本——发布不再回写仓库,所以「先改好 package.json + CHANGELOG,再发版」是唯一自洽的流程。
npm run release # 发布当前声明的版本(0.2.0-rc.1),打完包再上传
npm run publish:dry # dry-run:staging + 预览 tarball,不发布、不碰 git
npm run release -- --no-git # 零 git 副作用(不 commit / 不 tag / 不 push)
npm run release -- --bump rc # 只把 staging 版本推进到下一个 N(0.2.0-rc.2),仓库不动
npm run release -- --bump 0.2.0-rc.2 # 指定精确版本(必须同 base 且严格大于当前版本)
npm run release -- --dsh-base 0.2.1 # 覆盖 DSH 基线
npm run release -- --tag beta # 发布为 beta dist-tag(预发布版本默认 beta,正式版本默认 latest)
npm run release -- --otp 123456 # 二步验证一次性密码(也支持 NPM_OTP 环境变量)
--bump patch / --bump minor / --bump major 会被明确拒绝(退出码 2):版本以依赖的 DSH 版本为准,用 current / rc 或显式 x.y.z-rc.N。
--no-git 覆盖 --no-git-tag 与 --no-push;本脚本不再创建发布 commit(它不改仓库),git 动作只有「给已准备好的提交打 tag」与「push」,用 --no-git 可全部关掉。
注意:不要直接运行裸 npm publish。publish 是 npm 的生命周期脚本名,
npm 在上传完成后会再次执行它,导致发布脚本递归重入并报"版本已存在"
(0.0.5 发布事故:包实际已上传成功,npm publish 却以失败退出且未创建
git tag)。统一使用 npm run release。
发布前会自动检查:当前 version 符合 <base>-rc.<N> 规则(不合规直接退出 2 并给出重置指引)、位于 main 分支、工作区干净(CI 用 --skip-checks 跳过)、已登录 npmjs、版本号未被占用(--force 可跳过);staging tarball 名必须是 nextnowlabs-dsh-ark-toolkit-<version>.tgz。首次发布先执行 npm login --registry https://registry.npmjs.org/。
许可证
插件采用 MIT License。