把 Claude Code 的完整 agent 能力装进你的聊天窗口
在飞书 / Slack / Discord / 微信中直接使用 Claude Code —— 工具调用、代码编辑、MCP servers,一个都不少。
大多数 "AI 聊天机器人" 只是 API wrapper。Naozhi 不同 —— 它直接 spawn 本机 AI CLI(Claude Code 或 Kiro)作为长生命周期子进程,通过 stdin/stdout 进行原生协议通信,保留 CLI 的全部能力:
- 读写文件、执行 Bash、Git 操作、子 agent 编排
- 所有已配置的 MCP servers
- 自定义 system prompt 和 per-agent 模型选择
- 可插拔 Protocol:Claude
stream-json(NDJSON)或 KiroACP(JSON-RPC 2.0)
graph TD
IM["飞书 / Slack / Discord / 微信"]
GW["Naozhi Gateway<br/>(Go, 单二进制)"]
CLI["AI CLI<br/>(Claude / Kiro, 长生命周期进程)"]
TOOLS["Bash · Read · Edit · Grep<br/>Glob · Agent · MCP servers"]
IM -- "WebSocket / Socket Mode<br/>Gateway / HTTP 长轮询" --> GW
GW -- "stdin/stdout<br/>(stream-json / ACP JSON-RPC)" --> CLI
CLI --- TOOLS
style IM fill:#e8f4fd,stroke:#4a90d9
style GW fill:#fff3cd,stroke:#d4a017
style CLI fill:#d4edda,stroke:#28a745
style TOOLS fill:#f8f9fa,stroke:#6c757d,stroke-dasharray: 5 5
| 特性 | 说明 | |
|---|---|---|
| 0 | 零基础设施 | 所有平台均支持 WebSocket / 长轮询。无需公网 IP、域名或端口转发 |
| 1 | 完整 Agent 能力 | 不是 API wrapper,是真正的 Claude Code CLI —— 工具调用、代码编辑、MCP 一个不少 |
| 2 | 会话自动恢复 | 进程崩溃/回收后自动 --resume,对话上下文完整保留 |
| 3 | 单二进制部署 | Go 编译,无容器、无依赖。6 平台预编译 release,内置自动更新 |
| 4 | 实时 Dashboard | 浏览器实时查看所有会话、事件流、费用统计 |
| 5 | 多节点 NAT 穿越 | 远程机器反向拨入主节点,统一管理多台工作站 |
| 6 | 消息队列与抢占 | 忙时消息自动排队/合并,支持 /stop 软中断与 /urgent 紧急抢占 |
| 7 | 多 Backend | 同一实例可并存 Claude(stream-json)与 Kiro(ACP),按会话切换 |
| 平台 | 接入方式 | 私聊 | 群聊 | 消息编辑 |
|---|---|---|---|---|
| 飞书 | WebSocket 长连接 / Webhook | ✓ | ✓ | ✓ 流式更新 |
| Slack | Socket Mode | ✓ | ✓ (mention) | — |
| Discord | Gateway WebSocket | ✓ | ✓ (mention) | — |
| 微信 | HTTP 长轮询 (iLink Bot) | ✓ | — | — |
所有平台开箱即用,无需公网 IP。
一个群聊可同时使用多个专业 agent,各自保持独立上下文:
/review 帮我看看这段代码有没有安全问题 → code-reviewer agent (sonnet)
/research Rust async runtime 对比分析 → researcher agent (opus)
普通消息会路由到默认 agent → general agent
Agent 命令、模型、system prompt 均可在 config.yaml 中自定义。
graph LR
MSG(["消息到达"]) --> FIND["查找/创建<br/>CLI 进程"]
FIND --> SEND["Send"]
SEND --> WAIT["等待结果"]
WAIT --> REPLY(["回复用户"])
WAIT -. "空闲 30min" .-> RECYCLE["进程回收<br/>(Close)"]
RECYCLE -. "下次消息" .-> RESUME["自动 --resume<br/>恢复上下文"]
RESUME --> SEND
style MSG fill:#e8f4fd,stroke:#4a90d9
style REPLY fill:#d4edda,stroke:#28a745
style RECYCLE fill:#f8d7da,stroke:#dc3545
style RESUME fill:#fff3cd,stroke:#d4a017
- Watchdog 双超时: 无输出超时 (默认 2min) + 总耗时超时 (默认 5min),防止进程挂起
- 容量管理: 可配置最大并发进程数 (默认 3),满载时自动驱逐最久空闲会话
- 中断恢复: 用户发送新消息时自动中断正在运行的 turn(软中断 control_request,ACP 回退 SIGINT)
- 会话自动串联 (auto-chain): 同一 workspace 的多个 session 自动接成一条链,Dashboard "load earlier" 可跨 session 边界回溯(默认 7d 窗口 / 32 链长)
会话忙碌时,新消息的处理策略可配置(session.queue.mode):
| 模式 | 行为 |
|---|---|
collect(默认) |
排队等待当前 turn 完成,settle 延迟后合并为一条后续 prompt |
interrupt |
每条新消息都自动打断当前 turn,最小化响应延迟(更费 token) |
passthrough |
每条消息直接转发给 CLI,各自得到独立结果。需 stream-json 后端,ACP 自动回退到 collect |
/stop: 软中断当前回复,保留后续排队消息/urgent <消息>: 紧急打断当前 turn 并优先处理该消息(passthrough 模式下的priority:"now"抢占)
同一个 naozhi 实例可同时挂载多个 CLI flavor:
cli:
backend: "claude" # 默认 backend
backends:
- id: "claude" # stream-json 协议
- id: "kiro" # ACP (JSON-RPC 2.0) 协议,自动选择
path: "~/.local/bin/kiro-cli"
model: "claude-sonnet-4.6"- Dashboard "new session" 下拉菜单按会话选择 backend
- API 通过
/api/sessions/send {"backend": "kiro"}覆盖 - ACP backend 自动处理
session/new、session/cancel通知与权限请求
在聊天中直接管理定时任务:
/cron add "@every 30m" 检查 staging 环境的健康状态
/cron add "0 9 * * 1-5" /review 扫描最近的 open PRs
/cron list
/cron pause <id>
- 标准 cron 表达式 +
@every语法 - 每 chat 10 个 / 全局 50 个配额
- 执行结果自动回推到聊天
发送语音消息即可与 Claude 对话。基于 Amazon Transcribe Streaming:
- 支持 OGG / FLAC / MP3 / WAV / M4A / AMR 等格式
- 不支持的格式自动通过 ffmpeg 转码为 PCM
- 多语言自动检测(可配置语言列表)
- 转码与上传并发执行,低延迟
将聊天绑定到代码项目,获得专属的 planner session:
/project my-app → 绑定到 my-app 项目
普通消息自动路由到 planner → 长期上下文,不受 TTL 回收
/project off → 解绑
- 自动发现
projects_root下含CLAUDE.md的目录 - planner session 免驱逐、免 TTL,保持长期对话上下文
- 每个项目可配置独立的模型和 system prompt
浏览器访问 http://localhost:8180 即可查看:
- 所有会话列表(运行中 / 就绪 / 挂起)+ 实时状态更新
- 事件流实时推送(thinking、tool_use、agent 调度、结果)
- 直接在 Dashboard 发送消息、上传文件(图片)、按会话选择 backend
- 发现并接管外部 Claude CLI 进程(一键 Take Over)
- 费用统计(per-session 累计 cost)
- 项目管理(绑定配置、planner 重启)
- 定时任务管理(顶级视图:创建、暂停、删除、run-now、调度预览)
NAT 后面的工作站也能统一管理:
graph RL
A["Node A<br/>(NAT 内)<br/>本地 Claude CLI"] -- "WebSocket 反向拨入" --> P
B["Node B<br/>(NAT 内)<br/>本地 Claude CLI"] -- "WebSocket 反向拨入" --> P
P["Primary<br/>(公网)<br/>Dashboard 统一入口"]
style P fill:#fff3cd,stroke:#d4a017
style A fill:#e8f4fd,stroke:#4a90d9
style B fill:#e8f4fd,stroke:#4a90d9
- 远程节点主动拨入 Primary 的
/ws-nodeWebSocket 端点 - Token 认证 + 自动重连(指数退避 1-30s)
- Dashboard 统一展示所有节点的会话
- 支持远程会话订阅、消息发送、进程接管
自动扫描本机运行的 Claude CLI 进程:
- 扫描
~/.claude/sessions/识别非 Naozhi 管理的 Claude 实例 - 显示会话概要(最后一条用户消息预览)
- 一键接管:SIGTERM → 等待 →
--resume接入 Naozhi 管理 - 自动首消息接管:检测到外部 session 时自动恢复
内置后台线程框架(sysession),用派生的 transient system session 执行周期性运维任务:
- auto-titler: 自动为活跃会话生成标题(达到最小轮次后触发,带重命名节流)
- attachment-gc: 回收超 TTL 且无引用的附件文件(默认 dry-run,先观察 would-remove 日志再开真删)
每个 daemon 独立 enabled 开关 + 调度周期,总开关为 sysession.enabled。
除 sessions.json 会话目录外,第二层持久化 ~/.naozhi/events/<keyhash>.log/.idx 记录每一条事件 —— 包括 Claude 自身 JSONL 无法恢复的字段:图片缩略图、附件路径、AskQuestion 卡片、agent-team 关联 ID。配合附件引用计数(.meta sidecar 记录引用会话哈希 + 最后引用时间),支持基于双 TTL 的精确回收。
用户可见文案支持中英双语(zh-CN / en-US),按平台 locale 提示 + 消息内容 CJK 比例启发式自动解析(默认 zh-CN)。用户锁定的语言不会被自动来源覆盖。
后台 goroutine 轮询 GitHub Releases,复用 naozhi upgrade 的校验流程(下载 → SHA-256 → 原子替换):
notify— 仅日志 + IM 通知download(默认)— 替换二进制,下次重启生效auto— 替换并立即重启
- Claude Code CLI 已安装并配置认证
推荐(macOS / Linux,零依赖):
curl -fsSL https://raw.githubusercontent.com/KevinZhao/naozhi/master/install.sh | bash脚本会按当前 OS/架构从 GitHub Releases 拉对应二进制、校验 SHA256、装到 ~/.local/bin/naozhi,全程不用 sudo。支持固定版本:
curl -fsSL https://raw.githubusercontent.com/KevinZhao/naozhi/master/install.sh \
| NAOZHI_VERSION=v0.0.3 bash卸载:curl -fsSL ... /install.sh | bash -s -- --uninstall
升级:naozhi upgrade(下载 → SHA-256 校验 → 原子替换;也可在 config.yaml 开启后台自动更新)
其它方式:从 Releases 手动下载,或源码编译:
go build -o bin/naozhi ./cmd/naozhi/仓库只提交 config.example.yaml 模板;部署时复制为 config.yaml 并填入你自己的值(config.yaml 在 .gitignore 中,避免提交环境特定数据):
cp config.example.yaml config.yaml
# 编辑 config.yaml:填入 workspace 路径、IM 平台凭据、cron notify chat_id 等凭据推荐通过环境变量注入(模板已用 ${VAR} 占位),避免写死在文件中。
# 1. 交互式扫码,自动获取 token 并生成配置
naozhi setup weixin
# 2. 启动
naozhi --config ~/.naozhi/config.yaml需要两个微信号 —— 一个登录为 bot,另一个发消息测试。
- 飞书开放平台 → 创建企业自建应用 → 开启"机器人"能力
- 权限:
im:message,im:message:send_as_bot,im:message:patch - 事件订阅: 选择 "使用长连接接收事件",订阅
im.message.receive_v1 - 发布应用版本
- 配置凭据并启动:
export FEISHU_APP_ID=your_app_id export FEISHU_APP_SECRET=your_app_secret naozhi --config config.yaml
- api.slack.com/apps → Create New App
- 开启 Socket Mode,获取 App-Level Token (
xapp-...) - Bot Token Scopes:
chat:write,app_mentions:read - Event Subscriptions:
message.im,app_mention
- discord.com/developers → New Application → Bot
- 开启 Message Content Intent
- 获取 Bot Token,邀请到服务器
naozhi --config config.yaml健康检查: curl http://localhost:8180/health
Dashboard: 浏览器打开 http://localhost:8180
| 命令 | 说明 |
|---|---|
| 普通消息 | 发送给默认 agent,保持多轮上下文 |
/review <text> |
路由到 code-reviewer agent |
/research <text> |
路由到 researcher agent |
/new |
重置默认 agent 对话 |
/new review |
重置指定 agent 对话 |
/clear |
重置会话(同 /new) |
/stop |
中断当前回复,保留后续排队消息 |
/urgent <text> |
紧急打断并优先处理该消息 |
/cd <path> |
切换工作目录 |
/pwd |
显示当前工作目录 |
/project <name> |
绑定到项目 |
/project off |
解绑项目 |
/cron add "<schedule>" <prompt> |
创建定时任务 |
/cron list |
查看定时任务 |
/cron del/pause/resume <id> |
管理定时任务 |
/help |
显示可用命令 |
Agent 命令通过 agent_commands 配置映射,可自定义。
server:
addr: ":8180"
dashboard_token: "${DASHBOARD_TOKEN}" # Dashboard 访问密码 (可选)
trusted_proxy: false # ALB/CloudFront 终止 TLS 时设为 true
cli:
backend: claude # "claude" | "kiro",单 backend 模式下的默认值
path: "~/.local/bin/claude"
model: "sonnet" # sonnet / opus / haiku
args:
- "--dangerously-skip-permissions"
# 可选:多 backend 并存(Claude + Kiro 同时启用)。dashboard "new session"
# 下拉菜单可以按会话选 backend,API 端通过 /api/sessions/send {"backend": ...}
# 覆盖。不设置 `backends` 时走单 backend 模式,使用上面的 cli.path/model/args;
# 每条 backend 的 path/model/args 省略时从顶层 cli.* 继承;`backend` 字段决定
# 默认 backend(同时也作为 dashboard 下拉第一项)。完整注释示例见
# config.example.yaml `cli.backends` 段。
# backends:
# - id: claude
# - id: kiro
# path: "~/.local/bin/kiro" # ACP 协议根据 id=kiro 自动选择,无需额外 flag
session:
cwd: "/home/user/projects" # CLI 默认工作目录,亦作 /cd 的允许根路径
max_procs: 3 # 最大并发 CLI 进程
ttl: "30m" # 空闲回收超时
watchdog:
no_output_timeout: "2m" # 无输出超时
total_timeout: "5m" # 单轮总超时
store_path: "~/.naozhi/sessions.json"
queue: # 忙时消息策略
mode: "collect" # collect | interrupt | passthrough
max_depth: 20
collect_delay: "500ms"
# auto_chain: # 同 workspace 会话自动串联(默认开启)
# enabled: true
# window_hours: 168 # 仅串联 7d 内修改过的 JSONL
# cap: 32
agents: # 自定义 agent
code-reviewer:
model: "sonnet"
args: ['--append-system-prompt', 'You are a code reviewer...']
researcher:
model: "opus"
agent_commands: # 命令 → agent 映射
review: code-reviewer
research: researcher
cron:
store_path: "~/.naozhi/cron_jobs.json"
max_jobs: 50
execution_timeout: "8h"
timezone: "Asia/Shanghai" # IANA 时区,解释 cron 表达式
jitter_max: "2m" # 调度抖动上限,拍平并发峰值
sysession: # 后台守护进程框架
enabled: true
daemons:
auto-titler: # 自动会话标题
enabled: true
attachment-gc: # 附件回收(默认关闭 + dry-run)
enabled: false
dry_run: true
# update: # 自动更新(轮询 GitHub Releases)
# enabled: true
# mode: "download" # notify | download | auto
# interval: "6h"
transcribe: # 语音转文字 (Amazon Transcribe)
enabled: true
region: "us-east-1"
language: "zh-CN,en-US" # BCP-47 列表,多语言自动检测
projects:
root: "/home/user/projects" # 项目扫描根目录
reverse_nodes: # 多节点:接受远程拨入
my-workstation:
token: "${NODE_TOKEN}"
display_name: "Kevin's Mac"
# upstream: # 多节点:作为远程节点拨入
# url: "wss://primary.example.com/ws-node"
# node_id: "my-workstation"
# token: "${NODE_TOKEN}"
platforms:
feishu:
app_id: "${FEISHU_APP_ID}"
app_secret: "${FEISHU_APP_SECRET}"
max_reply_length: 4000
# slack:
# bot_token: "${SLACK_BOT_TOKEN}"
# app_token: "${SLACK_APP_TOKEN}"
# discord:
# bot_token: "${DISCORD_BOT_TOKEN}"
# weixin:
# token: "${WEIXIN_BOT_TOKEN}"环境变量通过 ${VAR_NAME} 语法自动展开。
所有平台均支持 WebSocket / 长轮询,直接运行即可,无需公网 IP。
# 编译
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o bin/naozhi ./cmd/naozhi/
# 上传到服务器
scp bin/naozhi server:/usr/local/bin/
# 安装 systemd service(推荐 `sudo naozhi install`,自动生成单元文件;
# deploy/naozhi.service 是手动部署参考,与 cmd/naozhi/service.go 保持同步)
sudo cp deploy/naozhi.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable naozhi
# 配置凭据
cat > ~/.naozhi/env << 'EOF'
FEISHU_APP_ID=your_app_id
FEISHU_APP_SECRET=your_app_secret
DASHBOARD_TOKEN=your_dashboard_password
EOF
chmod 600 ~/.naozhi/env
# 启动
sudo systemctl start naozhi
journalctl -u naozhi -f可选 · 零停机重启 sudoers 精确化:若希望
systemctl restart naozhi时 shim 子进程不被 kill,参考docs/ops/sudoers-hardening.md安装deploy/naozhi-sudoers.example。不装也能跑 —— 只是每次 restart 会打断正在运行 的会话,journal 打WARN不致命。切勿为省事写NOPASSWD: ALL。
在线 profile:内存暴涨 / goroutine 泄漏 / CPU 热点排障,
ssh host后 用curl -H "Authorization: Bearer $TOK" http://127.0.0.1:8180/api/debug/pprof/...拉 heap / goroutine / CPU profile。端点受 token + loopback-only 双重防护,远端 请求(ALB / CloudFront)一律 403。详见docs/ops/pprof.md。
一键排障:
naozhi doctor聚合 binary / systemd / HTTP / auth / pprof / 状态目录 7 项检查,任一 fail 退出码 1。CI 友好,支持--json输出。详见docs/ops/doctor.md。
CloudFront → ALB (SG: CloudFront-only) → EC2 :8180 → systemd
- ALB 安全组仅允许 CloudFront 前缀列表
- EC2 通过 IAM 角色认证 Bedrock(无 AKSK)
- 推荐 t4g.small ARM64 实例
git tag v0.1.0
git push origin v0.1.0 # GitHub Actions 自动构建 6 平台二进制 + Releasecmd/naozhi/ 入口 + CLI 命令 (setup, install, doctor, upgrade, shim)
internal/
cli/ CLI 进程管理 + Protocol 接口 (stream-json / ACP)
session/ Session 路由 + 并发控制 + TTL 回收 + 持久化
dispatch/ 消息处理 + slash 命令 + per-session 队列
server/ HTTP server + REST API + WebSocket hub
dashboard/ Dashboard 视图与资源
platform/ IM 平台统一接口 (feishu / slack / discord / weixin)
cron/ 定时任务调度器 (robfig/cron)
project/ projectapi/ 项目发现 + Planner 路由 + 项目 API
sysession/ 后台守护框架 (auto-titler / attachment-gc)
discovery/ 外部 Claude 进程扫描 + 接管
transcribe/ 语音转文字 (Amazon Transcribe Streaming)
attachment/ 附件存储 + 引用计数 GC
eventlog/ history/ 事件日志持久化 + 历史回放
node/ upstream/ wshub/ 多节点协议 + 反向连接 + WebSocket hub
selfupdate/ 自动更新 (GitHub Releases 轮询 + 校验)
shim/ 零停机重启 sidecar 进程
i18n/ 多语言文案解析
metrics/ runtelemetry/ 指标 + 运行遥测
config/ YAML 配置 + 环境变量展开
deploy/ systemd service unit
完整架构设计见 DESIGN.md。
BSL 1.1 — 源码可读可改,个人和非生产用途免费。生产环境商用需获得授权。2030-03-21 后自动转为 Apache 2.0。