现代 TypeScript 聊天机器人框架 —— AI 驱动、插件化、热重载、多平台
能力按成熟度分档:Stable(推荐首跑与对外默认承诺)、Advanced(多 bot / toolSearch / MCP 等)。完整分档见下表。
| Tier | 特性 | 说明 |
|---|---|---|
| Stable | AI 驱动 | ZhinAgent + 单 Provider;Sandbox 本地调试;基础多轮与工具调用 |
| Stable | 插件化架构 | usePlugin() Hooks API,AsyncLocalStorage 上下文 |
| Stable | 热重载 | 代码与配置变更自动生效 |
| Stable | Remote Console | Host 仅 API(:8086);UI 在 console.zhin.dev(Sandbox 聊天) |
| Stable | TypeScript | 完整类型推导 |
| Stable | 安全(基础) | Bash allowlist、文件策略、交互式审批(见 Agent 安全文档) |
| Advanced | 多平台 IM | 适配器见 plugins/adapters 与 适配器文档(成熟度因平台而异) |
| Advanced | Feature 体系 | 命令、工具、技能、cron、数据库等组合 |
| Advanced | toolSearch / MCP | 编排工具、deferred worker、MCP Client/Server |
推荐首跑:克隆仓库后进入
examples/minimal-bot(Sandbox + 最少插件)。L4 参考:examples/full-bot(硬编排 + 语义记忆 + MCP Mesh)。examples/test-bot为维护者厨房水槽配置,勿当作默认模板。
- Node.js 20.19.0+ 或 22.12.0+
- pnpm 9.0+(
npm install -g pnpm)
git clone https://github.com/zhinjs/zhin.git
cd zhin
pnpm install
cd examples/minimal-bot
cp .env.example .env # 可选:配置 Ollama 或 OpenAI
pnpm dev- 保持
pnpm dev运行(Host 监听http://127.0.0.1:8086,无内置网页 UI)。 - 打开 Remote Console,API Base 填终端日志中的 Host 地址(如
http://127.0.0.1:8086),Token 与.env中HTTP_TOKEN一致。 - 在 Sandbox 窗口发
hello;AI 回合需 Ollama 或 API Key。详见 minimal-bot README 与 Remote Console 说明。
npm create zhin-app my-bot
cd my-bot
pnpm dev # 开发模式(热重载)脚手架会引导你选择运行时、数据库、聊天平台和 AI 提供商。
启动后在本机提供 Console API(默认 http://127.0.0.1:8086)。在 console.zhin.dev 登录并填写 API Base 与 Token(见 docs/console-remote.md)。
Windows 用户 📌:遇到问题请参考 Windows 初始化指南。
// src/plugins/hello.ts
import { usePlugin, MessageCommand } from 'zhin.js'
const { addCommand } = usePlugin()
addCommand(
new MessageCommand('hello <name:string>')
.desc('打个招呼')
.action((_, result) => `Hello, ${result.params.name}!`)
)在 zhin.config.yml 中启用插件:
plugins:
- helloZhin.js 提供完整的插件开发工具链:
# 创建插件
npx zhin new my-plugin # 交互式创建插件模板
# 开发调试
pnpm dev # 热重载开发,终端直接输入消息测试
# 测试
pnpm test # 运行 Vitest 单元测试
pnpm test:watch # 监听模式
pnpm test:coverage # 生成覆盖率报告
# 构建与发布
npx zhin build # 构建插件
npx zhin pub # 发布到 npm其他用户安装你发布的插件:
npx zhin search <keyword> # 搜索插件
npx zhin install <name> # 安装插件
npx zhin info <name> # 查看插件信息📖 完整指南:插件开发、测试与发布
Zhin.js 内置 AI 智能体系统,让机器人具备大模型对话和工具调用能力:
# zhin.config.yml
ai:
providers:
ollama:
api: ollama-chat
host: "http://localhost:11434"
# models 可省略 — 启动时 listModels(Ollama / OpenAI 兼容 GET /v1/models)
agents:
zhin:
provider: ollama
model: qwen3:14b # 须出现在发现列表;中转 API 无需手写 models 白名单
agent:
execSecurity: allowlist # bash:deny / allowlist / full
execPreset: network # 预设:readonly / network / development
execApprovalMode: ask # 白名单外:ask / allow / deny插件通过 addTool 注册 AI 可调用的工具:
const { addTool } = usePlugin()
addTool({
name: 'get_weather',
description: '查询指定城市的天气',
parameters: {
city: { type: 'string', description: '城市名称', required: true }
},
execute: async ({ city }) => `${city}:晴,25°C`
})除了上述程序化注册,还可以在约定目录放置 Markdown 文件,框架自动发现并注册,无需编写 TypeScript。
tools/
├── greeting.tool.md # 纯模板 Tool
└── weather/
├── weather.tool.md # 带 handler 的 Tool
└── handler.ts # execute 逻辑
纯模板示例(greeting.tool.md):
---
name: greeting
description: 向用户问好
parameters:
name:
type: string
description: 用户名称
required: true
---
你好,{{name}}!欢迎使用 Zhin.js 🎉body 中的
{{param}}会被参数值替换后直接作为返回。若需复杂逻辑,在 frontmatter 加handler: ./handler.ts,指向一个默认导出函数。
skills/
└── code-review/
└── SKILL.md
---
name: code-review
description: 代码审查助手
keywords: [review, lint, best-practice]
tags: [dev]
tools: [read_file, grep_search]
always: false # true = 常驻注入;false = 按需激活
---
你是一个代码审查专家,请对用户提供的代码进行审查……agents/
└── translator.agent.md
---
name: translator
description: 多语翻译助手
model: gpt-4o
maxIterations: 5
tools: [web_search]
---
你是一名专业翻译,精通中英日三语互译……框架按 ./tools(或 ./skills / ./agents)→ ~/.zhin/<kind>/ → .agents/skills/(向上至 git 根)→ 已加载插件包内对应目录 → ~/.zhin/packages/ / .zhin/packages/ 的顺序扫描(实现见 packages/im/agent/src/discovery/),同名先发现者优先;插件模块变更可通过 Plugin.watch 热重载。
IM 会话与 Harness(ADR 0010)
长对话自动 Compaction(L1 micro + L2 LLM)、消息级会话树(/tree)、epoch 归档(/reset)。zhin.config.yml 示例:
ai:
agent:
compaction:
enabled: true
auto: true
keepRecentTokens: 20000| 类别 | IM 命令 |
|---|---|
| 会话 | /compact · /tree · /tree N · /reset |
| 运维 | /models · /health |
| 内省 | /cmd · /bots · /bindings · /tools · /mcp |
zhin-package 安装:
zhin packages install npm:@scope/pkgConsole 可查询会话树:GET /api/agent/sessions/:sessionKey/tree、POST .../leaf。
AI 执行 bash 命令时受 6 层纵深防御 保护:
| 层 | 防御 |
|---|---|
| 1 | 危险命令黑名单(sudo/eval/dd 等即使 full 模式也拦截) |
| 2 | 环境变量前缀剥离(FOO=bar rm → 识别为 rm) |
| 3 | Safe wrapper 剥离(timeout 10 rm → 识别为 rm) |
| 4 | 复合命令拆分(ls && rm -rf / → 逐段检查) |
| 5 | 只读命令自动放行(cat/grep/ls 无需白名单) |
| 6 | Owner 审批信号(execApprovalMode: ask 时经 ask_user / ZHIN_NEEDS_OWNER 确认) |
Zhin.js 采用分层架构,将 AI 编排、IM 消息生命周期与可选队列运行时分离。入口:docs/architecture/README.md、docs/architecture-overview.md、docs/contributing/repo-structure.md。默认开发示例:examples/minimal-bot;全功能回归:examples/test-bot。
本系统是基于 pnpm workspace 的单体多包结构,严格遵循从无状态元通用层向智能体/应用层单向依赖流转:
%%{init: {'theme': 'base', 'themeVariables': { 'fontSize': '14px' }}}%%
graph TB
subgraph L5["🚀 zhin (主入口与聚合导出)"]
L5A("Zhin 实例化 & 引导启动")
end
subgraph L4["🤖 @zhin.js/agent (Agent 编排与 IM 深度集成)"]
L4A("ZhinAgent 中央编排")
L4B("McpClientManager 跨应用客户端")
L4C("能力动态扫描 (Discovery)")
L4D("安全策略 (ExecPolicy & FilePolicy)")
end
subgraph L3["核心能力双子星 (IM 层 + AI 引擎层)"]
subgraph L3A["💬 @zhin.js/core (IM 核心模块)"]
C1("Plugin & Adapter & Bot 契约")
C2("Command & Middleware 中间件")
C3("MessageDispatcher 分发器")
end
subgraph L3B["🧠 @zhin.js/ai (通用 AI 核心引擎)"]
A1("ModelRegistry 模型发现/降级")
A2("AIProvider 厂商适配层")
A3("Memory & Session 状态持久化")
A4("Compaction 压缩器 & CostTracker")
end
end
subgraph L2["⚙️ @zhin.js/kernel (运行时内核 - 无 IM 概念)"]
L2A("PluginBase 关系树 & 依赖注入 (DI)")
L2B("Feature 运行时服务抽象")
L2C("Cron & Scheduler 任务调度")
end
subgraph L1["📦 基础层 basic/ (通用底层原子基建)"]
L1A("@zhin.js/logger 结构化日志")
L1B("@zhin.js/database 统一数据库")
L1C("@zhin.js/schema 强类型配置")
L1D("@zhin.js/cli 编译与手写架")
end
%% 依赖流向
L5 --> L4
L4 --> L3A
L4 --> L3B
L3A --> L2
L3B --> L2
L2 --> L1
classDef main fill:#2e7d32,stroke:#1b5e20,color:#fff,rx:8
classDef agent fill:#1565c0,stroke:#0d47a1,color:#fff,rx:8
classDef core fill:#e65100,stroke:#bf360c,color:#fff,rx:8
classDef ai fill:#6a1b9a,stroke:#4a148c,color:#fff,rx:8
classDef kernel fill:#37474f,stroke:#263238,color:#fff,rx:8
classDef basic fill:#4e342e,stroke:#3e2723,color:#fff,rx:8
class L5,L5A main
class L4,L4A,L4B,L4C,L4D agent
class L3A,C1,C2,C3 core
class L3B,A1,A2,A3,A4 ai
class L2,L2A,L2B,L2C kernel
class L1,L1A,L1B,L1C,L1D basic
- packages/im/kernel 剥离了一切 IM 交互要素,只负责插件和 Feature 开发契约,能作为独立任务框架。
- packages/im/ai 不包含聊天机器人特有逻辑,仅专注多轮 AI 交互及上下文管理,可在任意 Web 服务内单用。
当外部事件到达时,packages/im/core/src/built/dispatcher.ts 分解为 Guardrail(护栏安全检查)、Route(规则路由)与 Handle(中间件洋葱路由与指令处理)三个阶段:
sequenceDiagram
autonumber
actor User as 用户 (QQ/Discord)
participant Adapter as 平台 Adapter
participant Disp as MessageDispatcher
participant Handle as Handle 阶段
participant Cmd as 命令解析器
participant Agent as ZhinAgent (AI)
User->>Adapter: 发送原始消息 (Raw Event)
Adapter->>Adapter: 解析格式 & 构建标准 Message 实例
Adapter->>Disp: dispatch(message)
Note over Disp: Stage 1 Guardrail(鉴权/过滤/日志)
Note over Disp: Stage 2 Route(exclusive 或 dualRoute)
Disp->>Handle: Stage 3 Handle
alt 命中 Command
Handle->>Cmd: commandService.handle()
Cmd->>Cmd: 解析参数 (SegmentMatcher)
else 未命中 Command 且应触发 AI
Handle->>Agent: aiHandler → ZhinAgent.process()
Agent->>Agent: 工具收集 / 提示词 / Agent.run 循环
end
Handle->>Disp: 经 replyWithPolish → $reply → sendMessage
Disp->>User: 统一出站(before.sendMessage → Bot)
packages/im/agent/src/orchestrator 是 AI 的交互中轴,它扫描目录,以零代/代码化的格式汇聚资产,并受运行、文件沙盒的多重审查机制保护:
graph TD
%% 发现与注册
subgraph Discovery["系统动态文件发现(支持热重载)"]
ToolMD["*.tool.md (Markdown工具)"] -->|Frontmatter & handler.ts| ToolReg["ToolRegistry (工具注册)"]
SkillMD["SKILL.md (技能/提示词模板)"] -->|依赖检查 & 摘要XML| SkillReg["SkillRegistry (技能注册)"]
AgentMD["*.agent.md (Agent预设)"] -->|元数据 & 系统提示| SubAgentReg["SubAgentRegistry (子代理)"]
end
%% MCP 接入
subgraph MCPClient["跨系统标准互联"]
McpServer["MCP Servers (Claude-compatible)"] -.->|stdio / http-sse| McpMgr["McpClientManager (多客户端管理)"]
McpMgr -->|桥接转化为 AgentTool| ToolReg
end
%% AI 中枢大脑
subgraph Orchestrator["ZhinAgent 决策中枢"]
ZhinAgent["ZhinAgent Core"]
RichPrompt["buildRichSystemPrompt(主路径常驻段)"] --->|system prompt| ZhinAgent
PromptBuilder["PromptBuilder(可选分层 API)"] -.->|buildRichSystemPromptWithBuilder| ZhinAgent
ModelRegistry["ModelRegistry (模型自动发现 & 自动降级)"] --->|智能分配最合适 LLM| ZhinAgent
AIProvider["AIProvider (接入 Ollama / OpenAI / DeepSeek 等)"] -.->|单/多轮 API 轮询| ZhinAgent
end
%% 安全策略层
subgraph Security["双重安全屏障"]
ExecPolicy["ExecPolicy (6层Bash安全纵深防御)"]
FilePolicy["FilePolicy (路径校验 & 敏感设备/文件拦截)"]
end
%% 关联关系
ToolReg -->|获取执行清单| ZhinAgent
SkillReg -->|匹配历史上下文激活| ZhinAgent
SubAgentReg -->|嵌套派生 Subagent| ZhinAgent
ZhinAgent -->|1. 检查 Sandbox 命令| ExecPolicy
ZhinAgent -->|2. 检查读写操作| FilePolicy
ExecPolicy -->|拦截/合规执行| ToolReg
FilePolicy -->|合规访问| ToolReg
classDef disc fill:#fff3e0,stroke:#ffb74d,color:#5d4037
classDef mcp fill:#f3e5f5,stroke:#ba68c8,color:#4a148c
classDef orch fill:#e3f2fd,stroke:#64b5f6,color:#0d47a1
classDef sec fill:#ffebee,stroke:#e57373,color:#b71c1c
class ToolMD,SkillMD,AgentMD,ToolReg,SkillReg,SubAgentReg disc
class McpServer,McpMgr mcp
class ZhinAgent,RichPrompt,PromptBuilder,ModelRegistry,AIProvider orch
class ExecPolicy,FilePolicy sec
packages/im/agent/src/init/register-typing-indicator.ts 自动转换 AI 复杂的思考流、子任务分发状态并渲染给指示器。最终的渲染通过统一保护链路:
graph TD
%% AI 生命周期事件广播
subgraph EventStream["1. AI 生命周期事件流"]
direction LR
Evt_Start["ai.processing.start"] ~~~ Evt_Think["ai.thinking.update"] ~~~ Evt_SubStart["ai.subagent.start"] ~~~ Evt_SubFinish["ai.subagent.finish"] ~~~ Evt_Finish["ai.processing.finish"]
end
%% 状态自动连携
subgraph StateBinding["2. AI 思考状态连携机制"]
RegIndicator["register-typing-indicator (启动绑定)"]
TIM["TypingIndicatorManager (适配器管理)"]
ActiveInd["Active Typing Indicator (思考指示器)"]
RegIndicator -->|监听全部 ai.* 事件| TIM
TIM -->|启动 / 流式 editMessage / 终止| ActiveInd
end
%% 统一安全出站链路 (IM Send Path)
subgraph OutboundPipeline["3. 统一安全出站保护链路"]
ActiveInd -->|流式思考内容 / 状态占位符| SendAPI["Adapter.sendMessage / Message.$reply"]
ZhinAgentAns["ZhinAgent 最终回复内容"] -->|输出内容| SendAPI
SendAPI -->|1. 经过模板渲染与组件自解析| Render["renderSendMessage (JSX 动态解析)"]
Render -->|2. before.sendMessage 终层防线拦截| BeforeHook["Root Plugin 挂载的拦截钩子"]
BeforeHook -->|3. 送达底层平台容器发送| BotSend["Bot.$sendMessage"]
BotSend -->|4. 分发到客户端| Client["QQ / Discord / Slack IM 界面"]
end
%% 事件流到绑定的连动
Evt_Start -->|1. 触发| RegIndicator
Evt_Think -->|2. 触发| RegIndicator
Evt_SubStart -->|3. 触发| RegIndicator
Evt_SubFinish -->|4. 触发| RegIndicator
Evt_Finish -->|5. 触发| RegIndicator
classDef stream fill:#eceff1,stroke:#90a4ae,color:#263238
classDef binding fill:#e8f5e9,stroke:#81c784,color:#1b5e20
classDef pipeline fill:#fff8e1,stroke:#ffb74d,color:#5d4037
class Evt_Start,Evt_Think,Evt_SubStart,Evt_SubFinish,Evt_Finish stream
class RegIndicator,TIM,ActiveInd binding
class SendAPI,ZhinAgentAns,Render,BeforeHook,BotSend,Client pipeline
- 不允许直发绕过:指示器和最终答案均触发统一的 packages/im/core/src/adapter.ts 中的发送生命周期,拒绝
Bot.$sendMessage被业务层直接旁路调用。
仓库内 plugins/adapters/ 共 17 个适配器包(成熟度因平台而异,对外默认承诺以 Sandbox 为主):
| 平台 | 包名 | 平台 | 包名 |
|---|---|---|---|
| Sandbox(Stable 首跑) | @zhin.js/adapter-sandbox |
QQ (ICQQ) | @zhin.js/adapter-icqq |
| QQ 官方 | @zhin.js/adapter-qq |
NapCat | @zhin.js/adapter-napcat |
| OneBot v11 | @zhin.js/adapter-onebot11 |
OneBot v12 | @zhin.js/adapter-onebot12 |
| Milky | @zhin.js/adapter-milky |
KOOK | @zhin.js/adapter-kook |
| Discord | @zhin.js/adapter-discord |
Telegram | @zhin.js/adapter-telegram |
| Slack | @zhin.js/adapter-slack |
钉钉 | @zhin.js/adapter-dingtalk |
| 飞书 | @zhin.js/adapter-lark |
微信公众号 | @zhin.js/adapter-wechat-mp |
@zhin.js/adapter-email |
GitHub | @zhin.js/adapter-github |
|
| Satori | @zhin.js/adapter-satori |
# 运行
pnpm dev # 开发模式(热重载)
pnpm start # 生产模式
pnpm start -- -d # 后台守护进程
npx zhin stop # 停止后台进程
# 插件管理
npx zhin new <name> # 创建插件模板
npx zhin build # 构建插件
npx zhin pub # 发布插件到 npm
npx zhin search <keyword> # 搜索 npm 上的 Zhin 插件
npx zhin install <name> # 安装插件
# zhin-package(ADR 0010)
npx zhin packages list # 已安装的 zhin-package
npx zhin packages install npm:@scope/pkg
# 诊断
npx zhin doctor # 检查环境和配置
npx zhin setup # 交互式配置向导| 分类 | 链接 |
|---|---|
| 入门 | 快速开始 · Docker 部署 · Windows 环境 |
| 基础 | 核心概念 · 配置文件 · 命令系统 · 插件系统 |
| 进阶 | AI 模块 · ADR 0010 Harness · Feature 系统 · 工具与技能 · 消息流转 |
| 开发 | 插件开发指南 · 贡献指南 · 架构概览 · API 参考 |
本仓库采用 pnpm workspace 单仓多包管理(无 git submodule):
zhin/ # 主仓库 (github.com/zhinjs/zhin)
├── basic/ # 基础层(独立 npm 包目录)
│ ├── cli/ # CLI 工具 (@zhin.js/cli)
│ ├── database/ # 数据库抽象
│ ├── logger/ # 日志系统
│ └── schema/ # Schema 校验
├── packages/ # 核心层
│ ├── kernel/ # 运行时内核
│ ├── ai/ # AI 引擎
│ ├── core/ # IM 框架
│ ├── agent/ # Agent 编排
│ ├── client/ # Web 控制台
│ ├── satori/ # 渲染引擎
│ ├── create-zhin/ # 项目脚手架(create zhin-app)
│ ├── scaffold-wizard/ # 共享配置向导(create + zhin setup)
│ └── zhin/ # 主入口包
├── plugins/ # 插件生态(适配器 / 服务 / 特性 / 工具)
├── docs/ # VitePress 文档站
└── examples/ # 示例项目
📖 详见:仓库结构与模块化约定 · 单仓库迁移说明
git clone https://github.com/zhinjs/zhin.git
cd zhin
pnpm install && pnpm build
cd examples/minimal-bot && pnpm dev # Stable 黄金路径(根目录 pnpm dev 启动的是 test-bot)📖 详见:贡献指南
MIT License