ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

部署 zeroclaw + qwen + dingtalk + skills:从零搭建 Rust 智能助理的完整配置指南

部署 zeroclaw + qwen + dingtalk + skills:从零搭建 Rust 智能助理的完整配置指南

1. 为什么我选 zeroclaw 而不是 openclaw:Rust 智能助理的落地场景

zeroclaw 是一个用 Rust 写的 AI Agent 框架,能做什么?简单说,它把大模型对话、工具调用、定时任务、消息渠道(钉钉、Telegram、Discord 等)和技能模块(skills)打包成一个可本地运行的二进制程序。适合谁?适合想在低配设备上跑一个常驻智能助理、又不想被 Python 运行时和 GC 拖累的开发者。我试过在 2 核 4G 的轻量服务器上跑,内存占用稳定在 200MB 上下,比同类 Python 方案省不少。

这次的目标很明确:在 Rust 环境下,用 zeroclaw 接入 qwen 模型(走阿里百炼的 OpenAI 兼容接口),再挂上钉钉机器人,最后加载 skills 技能模块,让一条钉钉消息能端到端走通「钉钉 → zeroclaw → qwen → 回传钉钉」的完整链路。整个过程我会给出可复制的 config.toml 片段、依赖清单和启动命令,你照着做就能复现。

先说清楚架构。zeroclaw 的核心是一个 agent 循环:收到消息后,它把消息和上下文一起发给模型,模型返回工具调用或文本,zeroclaw 执行工具(比如读文件、发邮件、查新闻),再把结果喂回模型,直到模型给出最终回复。钉钉在这里扮演的是「渠道」角色,通过 webhook 或长连接把消息送进 zeroclaw 的 gateway,再把回复推回钉钉群或单聊。skills 则是预置的工具包,每个 skill 有自己的 SKILL.md 描述和可执行脚本,zeroclaw 根据描述决定什么时候调用它。

为什么不用 openclaw?openclaw 生态更成熟,但资源消耗确实大,尤其在低配机器上跑久了容易吃满内存。zeroclaw 基于 Rust,没有 GC 停顿,启动快,二进制体积小,适合长期驻留。代价是文档和社区还在成长,有些配置得自己翻源码。不过对于「钉钉 + qwen + skills」这个组合,zeroclaw 的配置项已经够用了。

还有一个现实问题:token 消耗。网上有人说 zeroclaw 跑起来 token 烧得很快,我实测下来,如果 skills 开得多、上下文压缩没做好,确实不到 10 次对话就能吃掉 100 万 token。所以后面我会重点讲怎么控制上下文和 skills 的加载范围,避免无谓的消耗。

这一节先把场景和选型讲清楚,下一节开始动手:装 Rust、拉代码、配模型。

2. 前置准备:Rust 环境、qwen 模型接入与 zeroclaw 编译

在写配置之前,得先把地基打好。这一节覆盖三件事:Rust 工具链安装、qwen 模型 API Key 获取、zeroclaw 源码编译。每一步都有可复制的命令,你按顺序执行即可。

2.1 安装 Rust 工具链(Ubuntu 22.04 为例)

zeroclaw 要求 Rust 1.75 以上。如果你机器上还没装 Rust,用官方脚本最省事:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source "$HOME/.cargo/env" rustc --version cargo --version

装完后确认rustc和cargo都能输出版本号。如果网络拉取 crates.io 慢,可以配一个国内镜像源,在~/.cargo/config.toml里加:

[source.crates-io] replace-with = 'ustc' [source.ustc] registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/"

2.2 获取 qwen 模型 API Key

qwen 系列模型通过阿里百炼平台提供 OpenAI 兼容接口。你需要一个 API Key,然后在 zeroclaw 里把default_provider指向百炼的兼容端点。百炼的兼容模式地址是:

https://dashscope.aliyuncs.com/compatible-mode/v1

模型名可以选qwen-max、qwen-plus、qwen-coder-plus等。我这次用qwen-plus,因为它在成本和能力之间比较平衡,适合日常助理场景。如果你要跑代码相关的任务,qwen-coder-plus更合适。

拿到 Key 后,先别急着写进 config.toml,后面我会讲怎么用环境变量覆盖,避免明文泄露。

2.3 编译 zeroclaw

拉源码并编译:

git clone https://github.com/zeroclaw-labs/zeroclaw.git cd zeroclaw cargo build --release --locked

--locked保证依赖版本和 lock 文件一致,避免因为依赖漂移导致编译失败。如果网络不好,可以手动下载 release 包,或者用cargo build --release不加--locked试试。

编译完成后,把二进制装到 PATH:

cargo install --path . --force --locked

然后验证:

zeroclaw status

如果输出了工作区路径和配置状态,说明安装成功。接下来可以跑一次单次提问,确认模型能通:

zeroclaw agent -m "用 Python 实现快速排序"

这一步会用到你后面配置的模型。如果还没配,它会提示你缺 API Key。

2.4 依赖清单

zeroclaw 本身是 Rust 二进制,运行时依赖不多。但 skills 里的脚本可能依赖 Python 3.11+、jq、curl 等。建议提前装好:

sudo apt update sudo apt install -y python3 python3-pip jq curl python3 --version

Python 版本要 3.11 以上,因为部分 skill 脚本用了tomllib(Python 3.11 才进标准库)。如果你系统自带的是 3.10,需要自己升级或用 pyenv。

这一节把环境铺好了,下一节进入核心:写 config.toml,把 qwen、钉钉、skills 串起来。

3. 可复制配置:config.toml 里接入 qwen、钉钉与 skills 的完整片段

zeroclaw 的配置文件默认在~/.zeroclaw/config.toml。你也可以用zeroclaw onboard --interactive交互式生成,但手写更可控。下面这份配置是我实测能跑通的版本,你直接复制后改几个字段即可。

3.1 模型与 provider 配置

api_key = "sk-你的百炼Key" default_provider = "custom:https://dashscope.aliyuncs.com/compatible-mode/v1" default_model = "qwen-plus" default_temperature = 0.7 model_routes = [] embedding_routes = []

这里的关键是default_provider用custom:前缀加完整 URL,指向百炼的 OpenAI 兼容端点。default_model填qwen-plus,你也可以换成qwen-max或qwen-coder-plus。api_key建议不要明文写,后面用环境变量ZEROCLAW_API_KEY覆盖。

3.2 钉钉渠道配置

[channels_config] cli = true message_timeout_secs = 300 [channels_config.dingtalk] client_id = "你的钉钉AppKey" client_secret = "你的钉钉AppSecret" allowed_users = ["*"]

钉钉这边需要在开放平台创建一个应用,拿到client_id(AppKey)和client_secret(AppSecret)。allowed_users = ["*"]表示允许所有用户,生产环境建议改成具体用户 ID。钉钉的消息通过 Stream 模式接入,不需要公网 IP,这点对本地部署很友好。

3.3 自主性与安全策略

[autonomy] level = "supervised" workspace_only = true allowed_commands = ["git", "npm", "cargo", "ls", "cat", "grep", "find", "echo", "pwd", "wc", "head", "tail", "curl", "mkdir", "jq", "python3"] forbidden_paths = ["/etc", "/root", "/home", "/usr", "/bin", "/sbin", "/lib", "/opt", "/boot", "/dev", "/proc", "/sys", "/var", "/tmp", "~/.ssh", "~/.gnupg", "~/.aws", "~/.config"] max_actions_per_hour = 20 max_cost_per_day_cents = 500 require_approval_for_medium_risk = true block_high_risk_commands = true auto_approve = ["file_read", "file_write", "memory_recall"] always_ask = []

level = "supervised"表示中等风险操作需要确认,高风险直接拦截。workspace_only = true限制 agent 只能在工作区内操作。allowed_commands是白名单,只允许这些命令执行。forbidden_paths是黑名单,防止 agent 读到敏感目录。这套组合下来,即使模型被诱导,也很难造成破坏。

3.4 记忆与存储

[memory] backend = "sqlite" auto_save = true hygiene_enabled = true archive_after_days = 7 purge_after_days = 30 conversation_retention_days = 30 embedding_provider = "none" embedding_model = "text-embedding-3-small" embedding_dimensions = 1536 vector_weight = 0.7 keyword_weight = 0.3 min_relevance_score = 0.4 embedding_cache_size = 10000 chunk_max_tokens = 512 response_cache_enabled = false response_cache_ttl_minutes = 60 response_cache_max_entries = 5000 snapshot_enabled = false snapshot_on_hygiene = false auto_hydrate = true

记忆后端用 sqlite,轻量且无需额外服务。embedding_provider = "none"表示不做向量检索,只用关键词匹配,这样省 token 也省算力。如果你需要语义检索,可以改成openai并配 embedding 模型,但会额外消耗 token。

3.5 网关与调度

[gateway] port = 3000 host = "127.0.0.1" require_pairing = false allow_public_bind = false paired_tokens = [] pair_rate_limit_per_minute = 10 webhook_rate_limit_per_minute = 60 trust_forwarded_headers = false rate_limit_max_keys = 10000 idempotency_ttl_secs = 300 idempotency_max_keys = 10000 [scheduler] enabled = true max_tasks = 64 max_concurrent = 4 [cron] enabled = true max_run_history = 50

网关默认绑127.0.0.1:3000,不对外暴露。钉钉走 Stream 模式,不需要网关公网可达。调度器和 cron 开着,方便后面加定时任务。

3.6 skills 加载

skills 放在~/.zeroclaw/workspace/skills/目录下。每个 skill 是一个子目录,里面有SKILL.md和可执行脚本。zeroclaw 启动时会扫描这个目录,把 skill 描述注入到系统提示里,模型根据描述决定是否调用。

添加 skill 的命令:

npx skills add https://github.com/vikiboss/60s-skills --skill daily-news-60s

或者手动下载后放到~/.zeroclaw/workspace/skills/下。注意 skills 不要开太多,每个 skill 的描述都会占用上下文 token,开十几个之后 token 消耗会明显上升。

3.7 环境变量覆盖敏感信息

不要把 API Key 和钉钉 Secret 明文写在 config.toml 里。用环境变量覆盖:

export ZEROCLAW_API_KEY="sk-你的百炼Key" export EMAIL_SMTP_PASSWORD="你的授权码"

zeroclaw 会优先读ZEROCLAW_API_KEY和API_KEY环境变量。钉钉的 Secret 目前只能写在配置里,建议把 config.toml 权限设为 600:

chmod 600 ~/.zeroclaw/config.toml

这一节把配置写完了,下一节启动并验证端到端链路。

4. 启动与验证:一条钉钉消息从 qwen 回传的端到端测试

配置写好后,启动 zeroclaw 并验证链路。这一节给出启动命令、验证步骤和预期结果。

4.1 启动 gateway 和 daemon

先启动 gateway,它会加载配置并连接钉钉:

zeroclaw gateway

如果一切正常,你会看到类似输出:

[INFO] gateway listening on 127.0.0.1:3000 [INFO] dingtalk channel connected [INFO] loaded 3 skills

如果钉钉连接失败,检查client_id和client_secret是否正确,以及钉钉应用是否开启了 Stream 模式。

长期运行用 daemon:

zeroclaw daemon

daemon 会在后台守护进程,断线自动重连。

4.2 验证模型连通性

在钉钉发消息之前,先用 CLI 验证模型:

zeroclaw agent -m "你好,请用一句话介绍你自己"

预期返回 qwen 的回复。如果报 401,说明 API Key 不对;如果报连接超时,检查default_provider的 URL 是否拼写正确。

4.3 钉钉端到端测试

在钉钉里给机器人发一条消息,比如「今天有什么新闻」。预期流程:

  1. 钉钉把消息推给 zeroclaw 的 dingtalk channel
  2. zeroclaw 把消息和 skill 描述一起发给 qwen
  3. qwen 判断需要调用daily-news-60sskill
  4. zeroclaw 执行 skill 脚本,拿到新闻数据
  5. 把结果喂回 qwen,qwen 整理成自然语言
  6. zeroclaw 把回复推回钉钉

如果一切正常,你会在钉钉里收到一条整理好的新闻摘要。如果 skill 没被调用,检查SKILL.md里的description是否清晰,模型靠这个描述决定是否调用。

4.4 查看日志确认链路

zeroclaw 的日志会记录每一步:

tail -f ~/.zeroclaw/logs/zeroclaw.log

你会看到类似:

[INFO] received message from dingtalk user=xxx [INFO] calling model qwen-plus [INFO] tool call: daily-news-60s [INFO] tool result: {...} [INFO] sending reply to dingtalk

这条日志链就是端到端走通的证据。如果中间断了,根据日志定位是哪一步失败。

4.5 验证 skills 加载

查看已加载的 skills:

ls ~/.zeroclaw/workspace/skills/

每个目录下应该有SKILL.md。如果某个 skill 没被加载,检查目录名和文件权限。zeroclaw 只加载有SKILL.md的目录。

这一节验证了链路,下一节讲常见报错和排查方法。

5. 常见报错排查:401、local proxy failed、reading choices 与 OAuth 问题

部署过程中最容易卡在几个报错上。这一节按报错信息分类,给出原因和解决方法。

5.1 401 Unauthorized

报错:

Error: 401 Unauthorized

原因:API Key 无效或未正确传递。排查步骤:

  1. 确认ZEROCLAW_API_KEY环境变量已设置,且值以sk-开头
  2. 确认default_provider的 URL 是https://dashscope.aliyuncs.com/compatible-mode/v1,不要漏掉/v1
  3. 确认default_model是百炼支持的模型名,比如qwen-plus,不要写成qwen3.5-plus这种不存在的名字
  4. 如果用的是自定义 provider,检查api_key字段是否被环境变量覆盖

5.2 local proxy failed

报错:

Error: local proxy failed: connection refused

原因:zeroclaw 尝试走本地代理,但代理没启动。排查:

  1. 检查[proxy]段,enabled = false时不应该走代理
  2. 如果确实需要代理,确认代理地址和端口正确
  3. 检查环境变量HTTP_PROXY/HTTPS_PROXY是否指向了一个不可用的地址

5.3 reading choices 报错

报错:

Error: reading choices: unexpected end of JSON input

原因:模型返回的响应不是预期的 OpenAI 格式。常见于 provider URL 配错,或者模型名不被支持。排查:

  1. 确认default_provider指向的是 OpenAI 兼容端点,不是原生 DashScope 端点
  2. 用 curl 直接测试端点:
curl -X POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions \ -H "Authorization: Bearer $ZEROCLAW_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"qwen-plus","messages":[{"role":"user","content":"hi"}]}'

如果 curl 返回正常 JSON,说明端点没问题,问题在 zeroclaw 配置。

5.4 OAuth 相关报错

报错:

Error: OAuth token expired

原因:某些 provider 用 OAuth 认证,token 过期。zeroclaw 目前对 OAuth 的支持有限,建议用 API Key 认证。如果你用的是需要 OAuth 的 provider,检查 token 刷新逻辑,或者换成 API Key 方式。

5.5 钉钉消息收不到回复

如果钉钉发了消息但没回复,排查:

  1. 检查allowed_users是否包含你的用户 ID
  2. 检查钉钉应用是否开启了机器人能力
  3. 查看日志里有没有received message from dingtalk,如果没有,说明消息没进来
  4. 检查message_timeout_secs是否太短,复杂任务需要更长时间

5.6 skills 不生效

如果模型不调用 skill,排查:

  1. 检查SKILL.md的description是否清晰描述了 skill 的用途
  2. 检查 skill 脚本是否有可执行权限:chmod +x script.py
  3. 检查allowed_commands是否包含脚本需要的命令,比如python3
  4. 减少同时加载的 skill 数量,太多 skill 会让模型难以选择

这一节覆盖了主要报错,下一节给出接入文档和 API Key 的获取入口。

6. 接入文档与 API Key 获取:把 qwen 和钉钉串起来的最后一步

如果你还没拿到 qwen 的 API Key,或者想确认 zeroclaw 的完整配置项,可以从下面这些入口进入。

TaoToken 的 API Key 管理页面在 console,你可以在这里创建和管理 Key。接入文档在 doc,里面有各模型的端点和参数说明。API 基础地址是https://taotoken.net/api,在 zeroclaw 里配置default_provider时可以用这个地址加/v1后缀。

如果你想先验证模型对话是否正常,可以用 模型对话 页面直接测试。长期跑编码或 Agent 任务的话,Coding Plan 更划算。API Key 的创建入口在 api-keys。

配置 zeroclaw 时,把default_provider写成:

default_provider = "custom:https://taotoken.net/api/v1" default_model = "qwen-plus"

然后把ZEROCLAW_API_KEY设成你在 console 里创建的 Key。这样 qwen 模型就能通过 TaoToken 的兼容端点接入 zeroclaw。

钉钉这边,开放平台的入口是https://open-dev.dingtalk.com/,创建应用后拿到 AppKey 和 AppSecret,填进[channels_config.dingtalk]段。钉钉的 Stream 模式不需要公网 IP,本地机器就能跑。

skills 的添加用npx skills add命令,或者手动下载放到~/.zeroclaw/workspace/skills/下。每个 skill 的SKILL.md里要写清楚description,模型靠这个决定是否调用。

最后提醒一句:token 消耗和 skills 数量、上下文长度直接相关。我实测下来,开 3 个 skill、对话 10 轮左右,qwen-plus 大概消耗 20 万 token。如果你发现消耗过快,先检查max_history_messages和compact_context配置,把历史消息数调小,或者开启上下文压缩。zeroclaw 的[agent]段里有compact_context = false,改成true可以自动压缩长对话,省 token 效果明显。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进