# javaClaw **Repository Path**: magicxie/javaClaw ## Basic Information - **Project Name**: javaClaw - **Description**: No description available - **Primary Language**: Java - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2026-02-22 - **Last Updated**: 2026-03-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # javaClaw 参照 [openClaw](https://github.com/openClaw) 原理使用 **Java 8** 重写的超轻量个人 AI 助手,目前仅QQ渠道 可拓展,核心逻辑保持精简,仅4000行代码,不依赖任何框架,适合学习与二次开发。 依赖仅如下 ``` com.fasterxml.jackson.core jackson-databind ${jackson.version} com.fasterxml.jackson.datatype jackson-datatype-jsr310 ${jackson.version} info.picocli picocli ${picocli.version} com.squareup.okhttp3 okhttp ${okhttp.version} ``` --- ## 特性 - **多渠道**:**当前已实现对接的为 QQ 机器人**(WebSocket 网关 + 单聊发消息);钉钉(DingTalk)为预留,未与钉钉平台真正对接。通过消息总线与 Agent 解耦,便于扩展新渠道 - **LLM**:HTTP 调用任意 OpenAI 兼容 API(如 OpenAI、DeepSeek、Azure 等),由 `LLMProvider` 抽象 - **Agent + 工具**:多轮对话、记忆与技能、内置工具(消息发送、文件读写、Shell、MCP 等),LLM 通过 tool_calls 与 MessageTool 等与渠道间接通信 - **轻量**:Java 8,Picocli CLI + JSON 配置,数据与工作区统一在 `~/.javaclawbot` --- ## 技术栈 | 类别 | 选型 | |----------|------| | 语言 | Java 8 | | CLI | Picocli | | 配置 | JSON + POJO(Jackson),路径统一为 **javaclawbot** | | LLM | HTTP 调用 OpenAI 兼容 API(`LLMProvider` 抽象) | | 渠道 | QQ(已对接,WebSocket 网关);钉钉(预留) | --- ## 示例 ### 网关模式,通过app来交互 通过 QQ 可以让其远程查看主机信息、执行文件操作等。 | ![截图1](img/img.png) | ![截图2](img/img_1.png) | ![截图3](img/img_2.png) | | :---: | :---: | :---: | ### agent模式 通过命令行交互 ![img_4.png](img/img_4.png) ![img_5.png](img/img_5.png) ![img_6.png](img/img_6.png) ### debug模式 手动调试 这样就可以本地调试 ![img_7.png](img/img_7.png) ![img_8.png](img/img_8.png) ### QQ机器人申请以及配置 qq渠道是最容易最简单的,三步即可,无任何卡点 第一步 登陆qq开放平台 https://q.qq.com/#/apps 第二步 创建机器人 ![img_9.png](img/img_9.png) 第三步 机器人配置 选择开发、沙箱配置,在消息列表配置 添加自己的QQ号,然后点击箭头指向的地方会弹出二维码 扫码关注即进入聊天,不需要发布到线上 ![img_10.png](img/img_10.png) 点击开发管理 就可以拿到机器人的app token等,然后配置到config.json ![img_11.png](img/img_11.png) ### 配置说明 参考这里 [06-config.json 填写说明](docs/06-config.json%20填写说明.md) --- ## 模块设计介绍 | Java 包/模块 | 职责简述 | 对应 Python | |--------------|----------|-------------| | **`agent`** | 核心 Agent:循环、上下文、记忆、技能、子 Agent、工具 | `nanobot/agent/` | | **`agent.AgentLoop`** | Agent 主循环:取消息 → 建会话/上下文 → 调 LLM → 执行 tool_call → 写回复/会话 | `agent/loop.py` | | **`agent.ContextBuilder`** | 组装 system prompt、多轮 messages(含 tool 结果、assistant 消息) | `agent/context.py` | | **`agent.MemoryStore`** | 持久记忆:`MEMORY.md`(长期事实)+ `HISTORY.md`(可 grep 的日志) | `agent/memory.py` | | **`agent.SkillsLoader`** | 技能加载:workspace 与内置 skills 目录下的 `SKILL.md`,按需/常驻加载 | `agent/skills.py` | | **`agent.tools`** | 工具抽象与实现:文件读写/列表、shell、**message**(通过 bus 回发到当前会话)、MCP 等;执行时 params 由框架注入 channel、chatId、metadata | `agent/tools/` | | **`bus`** | 消息总线:`InboundMessage` / `OutboundMessage`,`MessageBus`(队列 + 出站分发) | `nanobot/bus/` | | **`channels`** | **QQ 已对接**,钉钉预留:`BaseChannel` 抽象 + `QQChannel`(完整实现)、`DingTalkChannel`(预留);收消息时 `handleMessage` → `bus.publishInbound` | `nanobot/channels/` | | **`channels.ChannelManager`** | 按配置初始化钉钉(预留)/QQ channel、启动 outbound 分发循环(`dispatchOutbound`) | `channels/manager.py` | | **`providers`** | LLM:`LLMProvider` 接口、实现类(如 `OpenAICompatibleProvider`)、Registry 按 model 选 provider | `nanobot/providers/` | | **`config`** | 配置 Schema(POJO):agents、channels.dingtalk、channels.qq、providers、gateway、tools 等;Loader 读 `~/.javaclawbot/config.json` | `nanobot/config/` | | **`session`** | 会话:按 `channel:chatId` 的 sessionKey 管理多轮对话历史与持久化 | `nanobot/session/` | | **`cron`** | 定时任务:Cron 配置与存储,到期通过 Agent 执行 | `nanobot/cron/` | | **`heartbeat`** | 心跳/主动唤醒(如定时拉活) | `nanobot/heartbeat/` | | **`cli`** | CLI:`javaClaw gateway`、`agent`、`onboard`、`status`、`cron` 等子命令 | `nanobot/cli/commands.py` | | **`skills`(资源)** | 内置技能 `SKILL.md` 文件,与 Python 版共用或复制一份 | `nanobot/skills/` | --- ## 架构与调用链 渠道与 Agent 通过 **MessageBus(消息总线)** 解耦:**QQChannel 不调用 MessageTool,MessageTool 也不调用 QQChannel**,二者都只与 MessageBus 打交道。 ### 1. QQChannel 与 MessageTool 的职责 | 组件 | 职责 | |-------------|------| | **QQChannel** | ① **收**:把 QQ 平台事件转成 `InboundMessage` 并投到总线
② **发**:从总线拿到 `OutboundMessage`,调 QQ 接口真正发出去 | | **MessageTool** | Agent 的一个工具:当 LLM 要「给用户发一条消息」时被调用,只负责构造 `OutboundMessage` 并投到总线,**不直接调任何渠道 API** | 因此:MessageTool 不调用 QQChannel,两者都只和 MessageBus 交互。 ### 2. 一条完整调用链(执行顺序) 整体是「**QQ 进 → 总线 → Agent(可能用 MessageTool)→ 总线 → QQ 出**」: ``` 用户发消息到 QQ ↓ ① QQChannel(收) WebSocket 收到事件 → dispatchEvent() → handleMessage() → bus.publishInbound(InboundMessage) // 入队 ↓ ② AgentLoop bus.consumeInbound() 取到消息 → processMessage() → runAgentLoop() → 可能调用 LLM → LLM 返回 tool_calls,其中可能有 "message" → 执行 MessageTool.execute(params) ↓ ③ MessageTool 用 params 里的 channel、chatId、content、metadata 构造 OutboundMessage → bus.publishOutbound(OutboundMessage) // 入队 ↓ ④ ChannelManager.dispatchOutbound() bus.consumeOutbound() 取到 OutboundMessage → 根据 msg.getChannel() 找到 "qq" 对应的渠道 → QQChannel.send(msg) ↓ ⑤ QQChannel(发) send() 里调 QQ 开放接口 POST /v2/users/{openid}/messages → 用户端收到回复 ``` **先后顺序简述**: 1. **先执行**:QQChannel 的「收」逻辑(①),把 QQ 消息变成入站消息。 2. **中间**:AgentLoop + 可能用到的 MessageTool(②③),只和总线交互。 3. **后执行**:ChannelManager 从总线取到出站消息,再调用 QQChannel 的「发」逻辑(④⑤)。 ### 3. 设计原因 - **渠道与 Agent 解耦**:Agent(含 MessageTool)只认识「channel + chatId + content」,不关心具体渠道。发消息统一用 `bus.publishOutbound(msg)`,由 ChannelManager 根据 `msg.getChannel()` 决定交给哪个渠道的 `send()`。**当前已实现与平台对接的仅有 QQ 渠道**(钉钉为预留),加新渠道不用改 Agent / MessageTool。 - **MessageTool 只负责“要发什么”**:只把「发给谁、发什么」写成一条 `OutboundMessage` 丢进总线,不负责 HTTP/WebSocket 等具体发送。真正发 QQ 的是 `QQChannel.send()`,「业务决策(发什么)」与「渠道实现(怎么发)」分离。 - **一条总线串起收发**:入站 `QQChannel → publishInbound → AgentLoop consumeInbound`;出站 `MessageTool(或别的逻辑)→ publishOutbound → ChannelManager consumeOutbound → QQChannel.send()`。所有渠道和 Agent 都通过 MessageBus 通信,便于扩展和测试。 **一句话**:QQChannel 先收用户消息并写入总线,Agent 和 MessageTool 在中间消费、可能再往总线里写回复,最后由 ChannelManager 从总线取出回复并交给 `QQChannel.send()` 真正发到 QQ;两者通过 MessageBus 间接配合,而不是直接调用。 --- ## 构建与运行 ### 环境要求 - JDK 8+ - Maven 3.x ### 命令示例 ```bash # 编译 mvn compile # 打包可执行 JAR(含依赖) mvn package # 初始化配置与工作区(生成 ~/.javaclawbot/config.json 等) java -jar target/javaclaw.jar onboard # 编辑 ~/.javaclawbot/config.json,设置 providers.openai.apiKey、channels.qq 等 # 单条消息(CLI 模式) java -jar target/javaclaw.jar agent -m "你好" # 交互模式 java -jar target/javaclaw.jar agent # 启动 Gateway(钉钉/QQ 渠道 + Agent + 出站分发) java -jar target/javaclaw.jar gateway ``` --- ## 子命令 | 命令 | 说明 | |-----------|------| | `gateway` | 启动 Gateway(已配置的渠道 + Agent 循环 + outbound 分发) | | `agent` | CLI 运行 Agent(`-m` 单条或交互) | | `onboard` | 初始化 ~/.javaclawbot 与默认 config.json | | `status` | 查看配置与工作区状态 | | `cron` | 定时任务管理(占位) | --- ## 配置 - **配置文件**:`~/.javaclawbot/config.json`(Windows:`%USERPROFILE%\.javaclawbot\config.json`) - **数据目录**:`~/.javaclawbot` - **工作区**:`~/.javaclawbot/workspace` - **会话**:`~/.javaclawbot/sessions/` 配置项说明(agents、providers、channels.dingtalk / channels.qq、gateway、tools 等)见 [config.json 填写说明](docs/06-config.json%20填写说明.md)。 --- ## 文档 | 文档 | 说明 | |------|------| | [01-项目梳理-Java版](docs/01-项目梳理-Java版.md) | 架构、目录、流程与设计特点 | | [02-调用链-Java版](docs/02-调用链-Java版.md) | 程序入口、Gateway 启动、单条消息处理、直接调用、记忆合并 | | [03-接口文档-Java版](docs/03-接口文档-Java版.md) | 消息总线、渠道、LLM、工具、Agent、会话、技能、配置等接口 | | [05-最终技术方案-Java版](docs/05-最终技术方案-Java版.md) | 技术栈、路径约定、模块职责与扩展约定 | | [06-config.json 填写说明](docs/06-config.json%20填写说明.md) | config.json 各节点与常见场景 | --- ## 关注作者 ![qrCode.jpg](img/qrCode.jpg) ## License 请以项目根目录或仓库标注为准。