Skip to content

Repository files navigation

Better-Claw

Turn your Claude Code into a ClawdBot.

把你本地的 Claude Code 变成一个随时在线的私人 AI 助手 —— 通过 Telegram 对话、语音消息与它交互,它拥有和你桌面 Claude Code 完全相同的能力:MCP 工具、Skills、文件操作、Shell 命令,外加长期记忆和定时任务。

基于 Claude Agent SDK 构建,支持 Telegram / CLI 多平台接入和多用户管理。

前置依赖

  • Node.js ≥ 20
  • Claude Code CLI 已安装并完成认证(claude --version 可正常输出)— Agent SDK 复用 CLI 认证,无需单独配置 API Key

快速开始

# 1. 克隆仓库并安装依赖。
git clone https://github.com/your-org/better-claw.git
cd better-claw
npm install

# 2. 初始化数据目录(首次运行会自动创建并复制 config.example.yaml)。
npx tsx src/index.ts
# 输出:Initialized new data directory: .../data
# 输出:Please edit .../data/config.yaml and restart.

# 3. 编辑配置文件,填入实际值(至少检查 anthropic 和 telegram 部分)。
$EDITOR data/config.yaml

# 4. 启动服务。
npx tsx src/index.ts

数据目录 (--data-dir)

每个数据目录对应一个独立的 agent 实例,包含配置、用户数据、日志和会话历史。通过 --data-dir 参数可以在同一台机器上运行多个 agent 实例:

# 使用默认 ./data/ 目录。
npx tsx src/index.ts

# 指定自定义数据目录。
npx tsx src/index.ts --data-dir /path/to/my-agent

# start.sh 自动重启模式也支持 --data-dir。
./start.sh --data-dir /path/to/my-agent

首次使用新目录时,程序会自动创建目录、复制 config.example.yaml 作为初始配置,然后退出并提示编辑配置文件。

配置文件

配置文件位于 <data-dir>/config.yaml,所有字段都有默认值。最小可运行配置为空文件(Agent SDK 使用 CLI 认证)。

完整配置项参考 config.example.yaml

关键配置说明:

字段 说明
anthropic.authToken / baseUrl 通过代理服务器认证时使用
telegram.botToken 不配置则不启动 Telegram 适配器
logging.directory 相对路径基于 dataDir 解析,默认 logs
session.rotationTimeoutHours 超过此小时数自动开新会话
session.carryoverTurns 轮转时携带旧 session 最后 N 轮对话到新 session(默认 5)

权限与安全

多用户环境下,Better-Claw 通过多层机制隔离用户对文件系统和环境变量的访问。

权限组

每个用户属于一个权限组(默认 user),通过有序规则链控制文件系统访问。规则支持 ${userWorkspace}${userDir}${dataDir}${home}${configFile} 等变量。详见 config.example.yamlpermissions.groups 部分。

受保护路径 (protectedPaths)

非 admin 用户自动追加 deny readwrite 规则到规则链末尾(不可被权限组或工作组覆盖):

permissions:
  protectedPaths:
    - "${configFile}"    # 配置文件本身(含 API Key 等敏感信息)
    - "${home}/.claude"  # Claude CLI 认证目录

默认保护 config.yaml~/.claude。设为空数组可禁用(不推荐)。

环境变量过滤 (envFilter / envExtra)

非 admin 用户的 SDK subprocess 默认继承所有环境变量。通过 envFilter 可按通配符模式过滤敏感变量,通过 envExtra 可额外注入变量:

permissions:
  envFilter:
    - "ANTHROPIC_*"  # 过滤所有 ANTHROPIC_ 开头的变量
    - "AWS_*"
    - "SECRET_*"
  envExtra:
    MY_VAR: "value"  # 额外注入

SDK 必需的 Anthropic 变量始终从 anthropic 配置注入,不受 envFilter 影响。

System Prompt 安全策略

非 admin 用户的 agent 会在 system prompt 中被指示不得泄露环境变量、API Key 和配置文件内容,作为纵深防御。

记忆系统

Better-Claw 提供两层记忆系统:

  • Core Memory — 用户偏好、身份等高频信息,自动注入每次对话的 system prompt
  • Extended Memory — 知识、笔记、参考资料等长内容,agent 按需读取

每条 Extended Memory 支持 summary 字段(一句话摘要)。列出所有条目时会显示 key + summary,帮助 agent 快速判断需要读取哪个条目,无需逐个打开。

会话轮转与上下文衔接

会话在以下情况自动轮转:

  • 超时(用户最后消息距今超过 rotationTimeoutHours
  • Context 过大(token 占比达到 rotationContextRatio / rotationForceRatio
  • 手动(用户发送 /new 命令)

两层阈值与 Mid-query 轮转

系统使用 soft / force 两层阈值来控制轮转时机:

  • Soft 阈值rotationContextRatio,默认 0.5):达到后在后台预生成摘要,为即将到来的轮转做准备,不影响当前 query 执行。
  • Force 阈值rotationForceRatio,默认 0.7):达到后立即触发轮转,即使 agent 正在执行任务。

检查时机:每条 assistant 消息(包括只含 tool_use 的消息)都会实时计算 context ratio。这意味着即使在一次复杂的 agent loop(多轮 tool call)中,context 从 40% 涨到 70%,系统也能在中途及时发现并触发轮转,不必等到下一条用户消息。

Mid-query 自动续接

当轮转发生在 query 执行中途(mid-query rotation),系统会自动续接未完成的任务:

  1. 调用 interrupt() 中断当前 SDK query
  2. 保存已产生的部分对话到旧 session
  3. 创建新 session(携带 carryover)
  4. 重建 system prompt(包含 carryover 上下文)
  5. 自动注入续接 prompt,触发新的 executeQuery()

续接 prompt 内容:"上一个会话因 context 容量到达上限被自动轮转。请根据 system prompt 中 Carried Over from Previous Session 部分的上下文,继续完成之前未完成的任务。"

整个过程对用户透明——用户不会收到任何通知,agent 在新 session 中自动继续工作。

与之对比,常规轮转(between-query)发生在两次 query 之间,此时不需要自动续接,因为用户的新消息本身就是新 query 的触发。

Carryover 机制

不论何种原因触发轮转,系统都会从旧 session 最后 N 轮对话中提取 carryover,以规则化 digest 方式注入新 session 的 system prompt,确保模型不会遗忘轮转前的对话内容。

一轮 = 1 条用户消息 + 该轮最后 1 条 agent 回复。agent 在循环中可能产生多条中间 assistant 消息,carryover 只保留每轮的最终回复。

可选配置 carryoverIncludeToolCalls(默认 false):启用后 carryover 会携带完整的 tool_use(含工具名 + 输入参数)和 tool_result 内容,而非仅保留文本。适用于需要精确续接上下文的场景,但会增加 system prompt 体积。

Digest 策略(节省 token):

  • 用户消息:超过 carryoverUserMaxChars 字符则截断,并注明总长度
  • Agent 回复:超过 carryoverAssistantHeadChars + carryoverAssistantTailChars 则只保留开头和结尾原文,中间省略并注明总长度;未超过则保留全文

Carryover 在新 session 中始终保留,直到该 session 本身被轮转。

System Prompt 上下文构成

每个新 session 开始时,初始 context 约占 ~21k tokens(200k 窗口的 ~11%)。下图展示了各部分的占比:

System Prompt 上下文构成

其中 86% 是 Claude Code SDK 的固定开销(内置系统提示 + 工具 Schema),Better-Claw 自身的系统提示仅占 14%,最大的一块是会话历史(Session History)。

相关配置项(均在 session 下):

  • carryoverTurns — 携带的轮次数,默认 5,设为 0 禁用
  • carryoverUserMaxChars — 用户消息截断阈值,默认 500
  • carryoverAssistantHeadChars — agent 回复保留开头字符数,默认 200
  • carryoverAssistantTailChars — agent 回复保留结尾字符数,默认 200

用户时区与消息信封

用户时区

每个用户可以通过 user_profile MCP 工具设置自己的 IANA 时区(如 Asia/ShanghaiAmerica/New_York)。时区信息存储在用户的 profile.json 中。

时区影响范围:

  • System prompt 中的当前时间显示(以用户时区展示,附带 UTC 偏移量)
  • 消息信封中的时间戳
  • Agent 感知到的用户当地时间

时区优先级:

  1. 用户 profile 时区(最高,通过 user_profile 工具设置)
  2. 主机系统时区(最低,兜底默认值)

消息信封

消息信封(Message Envelope)在用户消息前自动附加平台来源和发送时间,帮助 agent 感知消息上下文。

格式:

[telegram | 2026-03-10 09:43 Asia/Shanghai (UTC+8)]
用户的消息内容

配置:

messageEnvelope:
  enabled: true   # 默认开启,设为 false 关闭

消息信封仅对用户消息生效,定时任务(cron)和 Webhook 触发的消息有各自独立的格式。

Webhook 集成

Better-Claw 提供 HTTP Webhook 接口,允许外部系统(如交易系统、监控系统)向用户发送消息通知。

配置

在 config.yaml 中启用 Webhook:

webhook:
  port: 3001                           # 监听端口
  apiKey: "your-secret-key"            # API 密钥(留空则不验证)

API 端点

POST /api/webhook/notify

Headers:

  • Content-Type: application/json
  • X-API-Key: (如果配置了 apiKey)

请求参数:

  • userId (string, 必填): 目标用户 ID
  • platform (string, 可选): 目标平台(telegram/dingtalk),默认用户最后绑定的平台
  • message (string, 与 prompt 二选一): 直接发送的消息内容(不经过 Agent)
  • prompt (string, 与 message 二选一): Agent prompt(经过 AI 处理后回复)
  • data (object, 可选): 附加数据,注入到 prompt 上下文

使用示例

直接发送消息(不经过 Agent):

curl -X POST http://localhost:3001/api/webhook/notify \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-secret-key" \
  -d '{
    "userId": "user_xxx",
    "message": "🔔 策略触发交易\n标的: 688256.SH\n动作: 买入\n价格: 1142.50"
  }'

经过 Agent 处理后回复:

curl -X POST http://localhost:3001/api/webhook/notify \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-secret-key" \
  -d '{
    "userId": "user_xxx",
    "prompt": "分析这笔交易并给出建议",
    "data": {
      "strategy": "AI芯片龙头",
      "action": "buy",
      "symbol": "688256.SH",
      "price": 1142.50,
      "quantity": 300
    }
  }'

响应

成功:{"success": true}

失败:{"error": "错误信息"}

  • 200: 成功
  • 400: 参数错误(缺少 userId 或 message/prompt)
  • 401: API Key 验证失败
  • 500: 服务器内部错误

Skill 系统

Better-Claw 支持树形 skill / skillset 管理,通过配置路径列表发现和组织 agent 技能。

目录结构约定

  • SKILL.md — 叶子节点(具体 skill),包含完整指引内容
  • SKILLSET.md — 中间节点(分类索引),用于组织子 skill
skills/
├── coding/                  ← Skill Set
│   ├── SKILLSET.md
│   └── typescript/          ← Skill
│       └── SKILL.md
└── standalone-skill/        ← 顶层 Skill
    └── SKILL.md

Frontmatter 格式

---
name: my-skill
description: 这个 skill 做什么的简要说明
---

工作原理

  1. 启动时扫描 config.yamlskills.paths 配置的所有路径
  2. 顶层节点的名称和描述注入到 system prompt
  3. Agent 通过 load_skillset MCP 工具按需加载和导航 skill 树
  4. SDK 通过 settingSources: ['user'] 原生发现 ~/.claude/skills/ 下的 skill,自动出现在 Skill 工具和 system prompt 的 <system-reminder>

配置

skills:
  paths:
    - "~/.claude/skills"    # Claude Code 默认路径(兼容原生/第三方 skill)
    - "./skills"            # 项目内置 skill
    - "~/my-custom-skills"  # 自定义路径

内置 Skills

仓库 skills/ 目录自带以下技能:

  • playwright — 浏览器自动化(导航、截图、表单填写),需配置 Playwright MCP server
  • peekaboo — macOS 屏幕截图与 GUI 自动化,需配置 Peekaboo MCP server
  • speech-to-text — 语音/音频转录为文字,需安装 openai-whisperffmpeg

参考各 skill 目录下的 SKILL.md 查看详细说明和依赖要求。

Claude Code Settings 继承

Better-Claw 与 Claude Code SDK 的 settings 系统协作,通过两个层面加载配置:

SDK 原生加载(settingSources: ['user']):

SDK 自动加载 ~/.claude/settings.json(user 层),从中发现:

  • ~/.claude/skills/ 下的原生 skill(出现在 SDK 的 Skill 工具和 system prompt 中)
  • user 层的 mcpServers(自动启动)

不加载 settings.local.json(local 层),以避免其中的 permissions.allow 规则(如 WebFetch domain 限制)被 SDK 转化为沙箱网络限制。

Better-Claw 显式加载(project + local 层):

Better-Claw 额外读取 project 和 local 层的 settings 文件,提取以下字段合并到 agent 配置中:

  • mcpServers — 外部 MCP 服务器配置(stdio / sse / http)
  • disallowedTools — 工具禁用列表

读取路径(仅 project + local):

  • .claude/settings.json(project,项目级配置)
  • .claude/settings.local.json(local,本地覆盖,通常 gitignore)

不继承的字段:

  • permissions(allow/deny 规则)— 与 Better-Claw 自有的权限系统冲突
  • modeleffortLevel 等 — 由 Better-Claw 的 config.yaml 统一管理

同名 MCP server 按层级覆盖(local > project > user),disallowedTools 跨层级去重合并。

配置热重载时(/admin reload-config)会同步刷新 Claude Code settings 缓存。

对话命令

在 Telegram 或 CLI 对话中可使用以下命令:

命令 说明
/bind <token> 绑定账号,将当前平台用户关联到系统用户
/stop 中断当前正在执行的 AI 响应,队列中的后续消息不受影响
/new 归档当前会话并开始一个全新会话
/restart 重启整个服务进程(由外层进程管理器重新拉起)
/admin <subcommand> 管理员命令,支持用户管理和工作组管理(仅 admin 用户可用,详见 /admin help

/admin 命令

permissionGroup === 'admin' 的用户可使用。支持以下子命令:

  • 用户管理user create/list/info/rename/set-group/delete/bind
  • 工作组管理workgroup create/delete/list/info/add-member/remove-member/set-access/members
  • 配置热重载reload-config

发送 /admin help 查看完整用法。

配置热重载

/admin reload-config 会重新读取 config.yaml 并更新内存中的配置,无需重启服务。

可热重载的字段:

字段 说明
anthropic API 配置(model、apiKey、authToken、baseUrl、maxBudgetUsd)
permissions 权限组、默认组、工作组定义
session 会话轮转阈值、摘要开关等
restart 重启权限
messagePush 中间消息推送
speechToText 语音转文字配置
permissionMode Agent 权限模式
messageEnvelope 消息信封开关
Claude Code settings ~/.claude/settings.json 等三层文件同步刷新

不可热重载(需要 /restart):

字段 原因
telegram / dingtalk 适配器连接已建立
webhook HTTP 服务器已启动
logging Logger 已初始化
dataDir 路径已解析

CLI 工具

所有子命令都支持 --data-dir(简写 -d)指定数据目录。

用户管理

使用前需要先通过 CLI 创建用户,然后在对话中用 /bind 绑定平台账号:

# 创建用户,会输出用户 ID 和 token。
npx tsx src/cli.ts user create -n "Alice"

# 在 Telegram 对话中发送 /bind <token> 完成绑定。
# 也可通过 CLI 直接绑定(支持 telegram / cli / qq / wechat / dingtalk):
npx tsx src/cli.ts user bind -t <token> -p telegram -u <telegramUserId>

# 查看所有用户。
npx tsx src/cli.ts user list

# 查看用户详情。
npx tsx src/cli.ts user info <userId>

# 修改显示名称。
npx tsx src/cli.ts user rename <userId> "Bob"

# 设置权限组。
npx tsx src/cli.ts user set-group <userId> admin

# 删除用户及其所有数据(交互式确认)。
npx tsx src/cli.ts user delete <userId>

工作组管理

工作组用于跨用户协作,共享一个 workspace 目录。配置持久化在 config.yamlpermissions.workGroups 中。

# 创建工作组。
npx tsx src/cli.ts workgroup create team-alpha

# 添加成员(默认 rw 读写权限,可用 -a r 指定只读)。
npx tsx src/cli.ts workgroup add-member team-alpha <userId>
npx tsx src/cli.ts workgroup add-member team-alpha <userId> -a r

# 查看工作组成员。
npx tsx src/cli.ts workgroup members team-alpha

# 修改成员权限(r 或 rw)。
npx tsx src/cli.ts workgroup set-access team-alpha <userId> r

# 查看工作组详情。
npx tsx src/cli.ts workgroup info team-alpha

# 列出所有工作组。
npx tsx src/cli.ts workgroup list

# 移除成员。
npx tsx src/cli.ts workgroup remove-member team-alpha <userId>

# 删除工作组及其 workspace(交互式确认)。
npx tsx src/cli.ts workgroup delete team-alpha

交互式对话

# CLI 对话模式(开发调试用)。
npx tsx src/cli.ts chat

开发

# 开发模式运行。
npm run dev

# CLI 对话模式。
npm run dev:chat

# 编译 TypeScript。
npm run build

# 运行测试。
npx vitest run

# 监听模式测试。
npx vitest

目录结构

better-claw/
├── src/
│   ├── index.ts              # 服务入口
│   ├── cli.ts                # CLI 管理工具入口
│   ├── config/               # YAML 配置加载 + Zod 校验
│   ├── core/                 # Agent 会话、消息队列、上下文管理
│   ├── adapter/              # 消息平台适配器(CLI、Telegram)
│   ├── memory/               # 两层记忆系统(core + extended)
│   ├── cron/                 # 定时任务调度与管理
│   ├── webhook/              # HTTP Webhook 服务器
│   ├── mcp/                  # MCP 工具服务器
│   ├── skills/               # Skill/Skillset 扫描、索引、MCP 工具
│   ├── user/                 # 用户管理与数据存储
│   ├── utils/                # 通用工具函数(时区处理等)
│   └── logger/               # pino 日志(控制台 + 文件轮转)
├── skills/                   # 内置 skill 目录(SKILL.md 文件)
├── tests/                    # vitest 测试
├── data/                     # 默认数据目录(gitignore)
├── config.example.yaml       # 配置模板
├── start.sh                  # 自动重启启动脚本
└── AGENT.md                  # 架构设计文档

数据目录内部结构

<data-dir>/
├── config.yaml
├── logs/
│   └── app.*.log
└── users/
    └── <userId>/
        ├── profile.json
        ├── session.json
        ├── workspace/
        ├── sessions/
        ├── memory/
        │   ├── core.json
        │   └── extended/
        └── crons.json

License

MIT

About

Turn your claude code into clawdbot

Topics

Resources

Stars

22 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages