📍 词元二号站 开源解码 全平台 AI 助手自建完整拆解:AstrBot 的架构原理、五条部署路径、Agent 沙盒与插件扩展体系

全平台 AI 助手自建完整拆解:AstrBot 的架构原理、五条部署路径、Agent 沙盒与插件扩展体系

摘要:一篇讲透 AstrBot 的中文长文。从多平台机器人的架构难题讲起,拆解它的三层解耦设计、消息链与统一会话标识;完整对比 uv、Docker Compose、桌面客户端等五条部署路径;实操走通 QQ 接入链路并附排错清单;深入 Agent 沙盒、MCP 协议、Skills 优先级、知识库 RAG 全流程与向量维度陷阱;给出插件最小可运行代码、事件钩子表与运维清单。适合想自建全平台 AI 助手的个人用户与开发者。
字号 100%
行距 2.05
当前可见 60% 的内容
本文由 辛梓煜@词元2号站(www.ciyuanerhao.com)撰写,转载请注明出处。

快速摘要

如果你只想要一个结论:AstrBot 是目前把「一个 AI 助手,同时活在十几个聊天软件里」这件事做得最完整的开源方案。它的核心不是某个花哨功能,而是一套三层解耦的架构——消息平台适配层负责把 QQ、飞书、钉钉、Telegram、Slack 的协议差异抹平;模型接入层把 OpenAI、Anthropic、Gemini、DeepSeek、Ollama 本地模型统一成同一套调用接口;中间的核心调度层负责会话、上下文、人格、工具调用和插件分发。最快的上手方式是 uv tool install astrbot --python 3.12 三条命令起服务,浏览器打开 6185 端口配置;最稳的生产方式是 Docker Compose,把协议端和主程序放进同一个网络。真正拉开它和同类项目差距的,是 Agent Sandbox(隔离沙盒执行代码)、原生 MCP 协议接入、原生知识库 RAG,以及一千多个可一键安装的社区插件。

这篇文章不打算做功能罗列。我会从「为什么这类工具一直做不好」讲起,把架构原理、部署路径的取舍、协议对接的真实链路、沙盒的安全边界、知识库的向量维度陷阱、插件的最小可运行代码,一条条拆开讲清楚。中间穿插我自己折腾时踩过的坑和排错清单。

想看完整拆解,往下翻。


一、为什么「多平台 AI 助手」这件事一直做不好

1.1 每个平台都在说自己的方言

先说清楚问题本身。

你想给自己搞一个 AI 助手,希望它能在 QQ 群里回答问题,也能在飞书工作群里帮你查资料,还能在 Telegram 上陪你聊两句。听起来是一个需求,实际上是三套完全不同的工程。

QQ 这边,官方机器人有一套报备和权限体系,个人号则要走 OneBot 协议实现端;飞书是标准的开放平台事件订阅 + 回调验签;Telegram 是 Bot API 的长轮询或者 Webhook;Slack 又是一套 Events API 加 Socket Mode。它们的消息格式不一样,鉴权方式不一样,富媒体(图片、语音、文件)的传输方式更是各走各的路。

这意味着什么?意味着你写一遍逻辑,得改四遍适配。而且改完之后维护成本会指数上升——任何一个平台调整了接口,你都得回去补。

我自己最早的做法是:给每个平台各写一个小脚本,共用一个后端 API。写到第三个的时候就写不下去了。不是技术上做不到,是心态上崩了:同一个「查天气」的功能,我需要在四个地方分别处理消息解析、分别处理回复格式、分别处理错误重试。

1.2 把问题拆开看:三层解耦才是正解

后来我想明白了,这件事真正的解法是分层。

一个成熟的聊天机器人框架,至少要把三件事拆干净:

  • 协议层:负责和各个聊天软件收发消息,把千奇百怪的原始报文翻译成一种统一的内部表示;
  • 调度层:负责会话管理、上下文维护、人格注入、工具选择、权限校验、插件分发;
  • 能力层:负责真正干活——调用大模型、执行代码、检索知识库、访问外部工具。

三层之间用统一的数据结构通信。协议层换一个平台,调度层不用动;能力层换一个模型,协议层也不用动。

这个思路听起来朴素,但要真正落地,工作量非常可观。AstrBot 值得聊的地方,恰恰是它把这三层都做完了,而且做得比较干净。


二、AstrBot 到底是个什么东西

2.1 一句话定位

按官方仓库的描述,它是一个开源的一站式 Agentic 个人和群聊助手,可以在数十款主流即时通讯软件上部署,此外还内置了一个类似 OpenWebUI 的轻量化 ChatUI。项目由 AstrBotDevs 团队维护,用 Python 编写,采用 AGPL-v3 许可证,代码完全公开。

我更愿意用另一种说法来解释它:它是一台「消息中继 + 智能调度」的路由器。左边插着各种聊天软件,右边插着各种大模型和工具,中间那个盒子负责把两边的语言翻译通、把上下文管起来、把该调的工具调起来。

这个定位很重要。它不是一个「AI 聊天软件」,而是一个把 AI 能力接进你已有沟通渠道的基础设施。你不需要让身边的人下载新 App,他们照常在原来的群里说话,助手就在那儿。

2.2 整体架构长什么样

我把它的运行链路画成了这张图,看完基本就理解了它的骨架:

flowchart TB
    subgraph P["协议层 · Platform Adapters"]
        A1[QQ / OneBot v11]
        A2[飞书 / 钉钉 / 企微]
        A3[Telegram / Slack / Discord]
        A4[内置 ChatUI]
    end

    subgraph C["核心调度层 · Core"]
        B1[消息事件 AstrMessageEvent]
        B2[会话与上下文管理]
        B3[人格 / 唤醒规则 / 权限]
        B4[插件与事件钩子分发]
        B5[函数工具管理器]
    end

    subgraph E["能力层 · Providers & Tools"]
        D1[LLM 提供商]
        D2[Embedding / Rerank]
        D3[STT / TTS]
        D4[MCP 服务器]
        D5[Agent Sandbox]
        D6[知识库 RAG]
    end

    P --> B1 --> B2 --> B3 --> B4 --> B5
    B5 --> D1 & D2 & D3 & D4 & D5 & D6
    B5 --> R[结果消息链]
    R --> P

消息从任何一个协议适配器进来,被规整成统一的事件对象;核心层依次做上下文拼接、人格注入、唤醒判断、插件钩子分发;需要调用能力的时候,走函数工具管理器分发到具体的提供商;最后把结果重新打包成消息链,原路返回给对应的平台。

2.3 消息链和统一会话标识:两个关键抽象

框架好不好用,很大程度取决于抽象设计得干不干净。这里有两个概念,理解了它们,后面看插件开发会顺很多。

第一个是消息链(message chain)。

一条消息不是一个字符串,而是一串「消息段」的有序列表。一段纯文本、一张图片、一个 @ 提及、一段语音,各自是一个段。为什么要这么设计?因为不同平台对富媒体的表达完全不同,只有把消息拆成段的序列,才能在中间层做统一处理,最后由适配器负责翻译成目标平台的具体格式。

用白话讲:消息链就是一个「乐高积木清单」,中间层只管往清单里加积木、改积木,具体拼成什么样由每个平台自己决定。

第二个是统一会话标识(unified_msg_origin,文档里常缩写成 umo)。

QQ 群聊里的会话 ID 是群号,私聊里是对方 QQ 号,飞书那边又是另一套 chat_id。如果只用平台自己的 ID,跨平台就会撞车——某个 QQ 群号可能刚好和某个飞书群 ID 一样。

所以框架引入了一个组合标识,把「平台类型 + 会话类型 + 会话 ID」拼在一起,作为全局唯一的会话锚点。上下文存哪、人格用哪个、沙盒工作区放哪个目录,全都按这个标识来分。

这个设计的好处在实操中很明显:你在 QQ 群和飞书群里跟同一个助手说话,两边的对话历史是完全隔离的,不会串。


三、消息平台适配层:一次接入,处处可用

3.1 支持范围:官方维护与社区维护

这是我觉得这个项目最扎实的部分。按官方仓库当前的清单整理如下:

平台

维护方

备注

QQ

官方维护

官方机器人体系

OneBot v11

官方维护

对接第三方协议实现端

Telegram

官方维护

Bot API

企微应用 & 企微智能机器人

官方维护

企业场景常用

微信客服 & 微信公众号

官方维护

需公众号后台配置

飞书

官方维护

开放平台事件订阅

钉钉

官方维护

企业内部应用

Slack

官方维护

国际团队常用

Discord

官方维护

社区场景

LINE

官方维护

Satori

官方维护

通用协议

KOOK

官方维护

语音社区

Misskey

官方维护

联邦宇宙

Mattermost

官方维护

自建团队沟通

WhatsApp

官方维护

标注为将支持

Matrix

社区维护

通过社区插件适配器

Rocket.Chat

社区维护

通过社区插件适配器

VoceChat

社区维护

通过社区插件适配器

这里有个细节值得注意:社区维护的适配器是以插件形式存在的。这说明它的适配器体系本身就是可插拔的——你如果要接一个清单里没有的内部沟通系统,不需要改主程序,按适配器接口写一个插件就行。

3.2 「协议实现端」是什么,为什么 QQ 个人号要多一层

新手最容易卡住的地方在这儿。接飞书、钉钉、Telegram 都是填个 App ID 和密钥就完事,为什么接 QQ 个人号要多装一个东西?

原因是 QQ 个人号没有对外开放的机器人 API。所以社区的做法是:在服务器上跑一个无头的 QQ 客户端(也就是没有图形界面的 QQ),它以正常客户端的身份登录,然后把收到的消息按照一套公开规范(OneBot v11)转成标准的 WebSocket 或 HTTP 报文对外暴露。

这个中间件就叫协议实现端。NapCatQQ 是目前用得最多的一个,本质上就是在跑一个无界面 QQNT 实例。

用一个比喻说清楚这个分工:

  • 协议实现端 = 耳朵和嘴巴,负责在 QQ 这一侧真正地听和说;
  • AstrBot = 大脑,负责思考该说什么;
  • 两者之间用 WebSocket 连起来,构成完整闭环。

它本身不含任何业务逻辑,纯粹是消息通道层。理解了这一层,你就明白为什么 QQ 那条链路需要两个容器、两套端口。

3.3 连接方向和端口:反向 WebSocket 到底谁连谁

这是新手排错时最常搞混的点,我单独画个时序图:

sequenceDiagram
    participant N as 协议实现端<br/>(NapCat, 端口 6099 是它的面板)
    participant A as AstrBot<br/>(监听 6199)
    participant U as 用户 QQ

    Note over A: 启用 OneBot v11 适配器<br/>在 6199 端口开一个 WS 服务端
    N->>A: 主动发起连接 ws://host:6199/ws
    A-->>N: 握手成功,日志出现「适配器已连接」
    U->>N: 在群里发送一条消息
    N->>A: 按 OneBot v11 格式推送事件
    A->>A: 解析成消息链 → 调度 → 调用模型
    A->>N: 下发回复动作
    N->>U: 以 QQ 客户端身份发出消息

关键结论:反向 WebSocket 里,AstrBot 是服务端,协议实现端是客户端,由后者主动去连前者。

对应的端口分工是这样的:

端口

归属

用途

6185

AstrBot

WebUI 管理面板

6199

AstrBot

反向 WebSocket 服务端

6099

协议实现端

它自己的管理面板(扫码登录在这儿)

我第一次配的时候就栽在 URL 末尾少写了 /ws,日志一直刷连接被拒绝,找了半小时。这个路径后缀不能省。

还有一个高频坑:如果两个服务都跑在 Docker 里,连接地址不能写 127.0.0.1。容器里的 127.0.0.1 指的是容器自己,不是宿主机。同一个 Compose 网络下,直接用服务名当主机名(比如 ws://astrbot:6199/ws)才是对的。


四、模型接入层:把所有模型抹平成一套接口

4.1 OpenAI 兼容协议是这个行业的最大公约数

我自己折腾下来最深的一个体会:现在做 AI 应用集成,只要支持「OpenAI API 兼容」,就等于支持了市面上八成的模型服务。

因为绝大多数国内外的模型提供商,都会额外提供一个兼容 OpenAI 请求格式的接入点。你只需要改 base_url 和 api_key,代码一行不动就能切换后端。

AstrBot 就是这么设计的。它的提供商配置里有一个「自定义」选项,能对接任何 OpenAI API 兼容的服务。在这之上,它又为常见的几家做了预设,省掉你手填地址的麻烦。

按官方文档整理,模型侧的支持矩阵大致是:

类型

提供商

对话大模型

OpenAI、Anthropic、Google Gemini、Moonshot AI、智谱 AI、DeepSeek、ModelScope、OneAPI

本地部署

Ollama、LM Studio

API 网关(支持多模型)

AIHubMix、优云智算、硅基流动、PPIO 派欧云、302.AI、小马算力

智能体平台(LLMOps)

Dify、阿里云百炼应用、Coze

语音转文本(STT)

OpenAI Whisper、SenseVoice、Xiaomi MiMo Omni

文本转语音(TTS)

OpenAI TTS、Gemini TTS、GPT-Sovits 系列、FishAudio、Edge TTS、阿里云百炼 TTS、Azure TTS、Minimax TTS、Xiaomi MiMo TTS、火山引擎 TTS

嵌入与重排序

兼容 OpenAI API 与 Gemini API 的嵌入服务、重排序服务

4.2 本地部署路线:数据不出门的方案

如果你处理的是敏感内容,或者单纯不想让对话数据经过第三方,本地模型是可行的。

通过 Ollama 或 LM Studio,整套链路可以完全在本机跑完,不依赖任何外部接口。代价是硬件——中等规模的模型至少要十几 GB 显存才跑得舒服,纯 CPU 推理的响应速度在聊天场景里基本没法接受。

我的实际做法是混合路线:日常闲聊和通用问答走云端的高性价比模型,涉及内部文档的问答走本地小模型 + 本地知识库。 这个组合在成本和隐私之间的平衡点比较舒服。

一个提醒:并不是所有模型都能直接用。我遇到过某些视觉模型在这套框架下调用失败的情况,日志里报的错还比较隐晦。所以换模型之后,务必先在 WebUI 自带的聊天页面测一轮,别直接上生产群。

4.3 语音链路:让助手能听会说

多模态这块的设计比较有意思。它把语音拆成了两条独立的链路:

flowchart LR
    V1[用户发语音] --> S1[STT 转文本]
    S1 --> L[LLM 处理]
    L --> S2{是否开启 TTS}
    S2 -- 是 --> T1[文本转语音] --> V2[回复语音消息]
    S2 -- 否 --> V3[回复文本消息]

这两条链路可以单独开关。有些场景你希望助手能听懂语音但用文字回(方便别人截图存档),有些场景反过来。分开配置就很灵活。

这里有个部署方式相关的坑要提前说:如果用普通的 docker run 方式部署协议实现端,可能收不到语音和文件数据,只能收到文字和图片。这会直接导致语音转文字和沙盒的文件输入功能失效。官方文档里推荐用 Docker Compose 的方式,把两者放在同一套编排里,这个问题就不会出现。

4.4 还有一层:图像描述提供商

这是个容易被忽略但很实用的配置。

框架允许你单独指定一个「图像描述模型提供商」。当用户发来一张图片时,如果你的主对话模型不支持多模态输入,框架会先用这个提供商生成一段图片的文字描述,再把描述作为上下文的一部分喂给主模型。

这个设计等于给不支持看图的模型打了个补丁。配置里还能自定义描述用的提示词模板,默认是让模型用中文描述图片内容。


五、部署实操:五条路径怎么选

我把官方支持的部署方式全试了一遍,这一节讲清楚每条路的适用场景。

5.1 路径一:uv 一键部署(体验最快)

uv 是一个 Python 包与环境管理工具,速度比传统方式快很多。这条路是官方推荐给「熟悉命令行、想快速体验」的用户的。

# 安装工具本体(Windows / Linux / macOS 通用,也可以用 pip install uv)
pip install uv

# 安装 AstrBot,指定 Python 3.12
uv tool install astrbot --python 3.12

# 初始化环境,仅首次执行
astrbot init

# 启动
astrbot run

启动完成后浏览器打开 http://localhost:6185,默认账号是 astrbot,初始密码在启动日志里能看到。第一件事就是改密码,别拖。

后续更新用这条:

uv tool upgrade astrbot --python 3.12

两个必须知道的限制:

  • 这个项目需要 Python 3.12 或更高版本--python 3.12 这个参数就是确保工具环境用对版本;
  • 通过 uv 部署的实例,不支持在 WebUI 里点按钮升级,必须回到命令行执行上面的升级命令。

macOS 用户还有个小现象:因为系统的安全检查机制,首次运行命令可能要等十几二十秒才有反应,这是正常的,别以为卡死了。

5.2 路径二:Docker Compose(生产首选)

服务器上长期跑,我强烈建议走这条。理由不是「Docker 更高级」,而是三个非常具体的好处:

  1. 环境完全隔离,不会污染宿主机的 Python 环境;
  2. 协议实现端和主程序在同一个 Compose 网络里,可以用服务名互相访问,省掉一堆网络配置的麻烦;
  3. 数据目录挂载出来,备份和迁移就是复制一个文件夹的事。

官方仓库里带了 compose 配置,克隆下来直接起:

git clone https://github.com/AstrBotDevs/AstrBot
cd AstrBot
docker compose up -d

国内服务器拉镜像慢的话,改一下 compose.yml 里的镜像地址,换成国内的镜像加速地址即可:

services:
  astrbot:
    image: m.daocloud.io/docker.io/soulter/astrbot:latest
    ports:
      - "6185:6185"   # WebUI
      - "6199:6199"   # 反向 WebSocket
    volumes:
      - ./data:/AstrBot/data
    restart: always

./data 这个目录非常关键,配置、会话记录、插件全在里面。做定时备份的时候,备份这一个目录就够了。

5.3 路径三:桌面客户端 / 启动器(不想碰命令行)

如果你只想在自己电脑上用,完全不想碰服务器和终端,有两个选择:

  • 桌面客户端(AstrBot-desktop):面向桌面使用,以内置的 ChatUI 作为主要入口,官方明确说明不推荐用于服务器场景;
  • 启动器(AstrBot Launcher):图形化管理工具,支持版本下载、多实例管理、数据备份、Python 运行环境自动配置。适合想要环境隔离多开的用户——比如你要同时跑一个测试实例和一个正式实例。

我个人更推荐启动器这条路给非技术用户。多开和备份这两个能力,在你开始认真用之后会非常有价值。

5.4 路径四:面板类部署(宝塔 / 1Panel / CasaOS)

已经在用运维面板的,官方文档里对这三个都有专门的部署说明,都是在应用商店里点几下的事。CasaOS 这条特别适合家用 NAS 场景——你在家里的 NAS 上跑一个助手,全家都能用。

辛梓煜@词元二号站 这边实测下来,面板类部署的优点是可视化程度高、日志和端口管理方便,缺点是遇到需要进容器执行命令的场景(比如后面要讲的 MCP 依赖安装)会稍微绕一点。

5.5 路径五:包管理器与云端一键

还有两个偏小众但很省事的:

  • AUR:Arch Linux 用户可以用 yay -S astrbot-git 直接装,走系统包管理器;
  • 云平台一键部署:不想自己管服务器的,有第三方云服务提供了一键部署入口;
  • Kubernetes:仓库里带了 k8s 目录,有集群环境的可以直接用。

5.6 选型对照表

我把五条路径的取舍整理成表,直接对着选:

部署方式

上手难度

适合场景

主要限制

uv 一键

快速体验、本地调试

不支持 WebUI 内升级

Docker Compose

服务器长期运行、生产

需要理解容器网络

桌面客户端

极低

个人本机使用

不适合服务器

启动器

极低

多实例、需要备份

仅桌面端

面板 / AUR / K8s

中到高

已有运维体系

依赖既有环境

我的建议很简单:先用 uv 或桌面客户端跑通一遍,把配置流程摸熟;确认要长期用了,再迁到 Docker Compose 上去。 前期不要一上来就折腾容器编排,容易在网络问题上浪费大量时间,还没看到效果就放弃了。


六、把 QQ 链路完整走通:一次实操记录

这是最典型也最容易出问题的一条链路,我完整走一遍。

6.1 五个步骤

第一步,起两个容器。

主程序容器映射 6185 和 6199 两个端口,协议实现端容器映射它自己的面板端口 6099,两者放在同一个网络里。用 Compose 的话这些都在配置文件里写好了。

第二步,登录协议实现端。

浏览器打开 http://服务器IP:6099,进面板需要一个 Token,从容器日志里拿:

docker logs napcat

进去之后会看到一个二维码,用准备好的 QQ 号扫码登录。

这里有个非常重要的提醒:不要用你的主号。 无头客户端属于非官方登录方式,存在账号被风控的可能。用一个专门的小号,而且这个小号最好不是刚注册的(新号更容易触发风控)。

第三步,在主程序侧开启适配器。

进管理面板 → 机器人 → 创建机器人 → 消息平台类别选 OneBot v11 → 启用适配器。反向 WebSocket 端口保持 6199,可以设一个连接密钥(Token)增加安全性。保存。

第四步,在协议实现端配连接。

回到 6099 的面板 → 网络配置 → 新建 → 选择「WebSocket 客户端」:

  • URL 填 ws://主机地址:6199/ws(Compose 部署就填 ws://astrbot:6199/ws
  • Token 填上一步设的密钥
  • 心跳间隔和重连间隔建议都改成 1000 毫秒
  • 勾选启用,保存

第五步,验证。

盯着主程序的控制台日志,看到「aiocqhttp(OneBot v11) 适配器已连接」就说明握手成功了。然后用另一个 QQ 号私聊机器人,发一条 /help,有回复就全通了。

别忘了最后一步:进配置页 → 其他配置 → 管理员 ID,填你自己的 QQ 号(不是机器人的)。不填的话很多管理指令你没权限用。

6.2 排错清单

我把踩过和见过的问题整理成表,出问题按顺序对照排查:

现象

大概率原因

处理方式

连接被拒绝(ECONNREFUSED)

主程序没在监听 6199

确认适配器已启用并保存

容器间连不上

用了 127.0.0.1

改成 Compose 服务名

一直重连不成功

URL 末尾少了 /ws

补上路径后缀

握手后立刻断开

两侧 Token 不一致

重新复制粘贴一遍

收得到文字收不到语音

部署方式导致的数据通道限制

改用 Compose 部署

扫码登录一直失败

容器内存不足

给容器留出 1GB 以上

日志有 GPU 相关报错

无头环境的正常现象

可以忽略,不影响功能

面板打不开

端口映射或防火墙

检查映射与安全组规则

6.3 安全上的三条硬规矩

这块我必须多说两句,因为很多教程不讲:

  1. 协议实现端的管理面板(6099)绝对不要直接暴露在公网。 那个面板能操作已登录的 QQ 账号,泄露出去后果很严重。只走内网访问,或者通过 SSH 隧道转发。
  2. 首次登录管理面板后立刻改默认密码。 默认凭据是公开的,不改等于门开着。
  3. 定期备份数据目录。 配置、会话历史、插件数据全在里面,丢了就得从头再来。

七、Agent 能力:沙盒、MCP 与 Skills

这一节是我认为最值得单独拿出来讲的部分,也是这个项目和普通「聊天机器人 + API 转发」的分水岭。

7.1 从「代码执行器」到「Agent 沙盒」

早期版本里有一个代码执行器功能,从 v4.12.0 开始被沙盒环境取代了。这个演进的方向很清楚:从「能跑代码」变成「能安全地跑代码,并且跑完的环境还能接着用」。

目前它提供了两种执行环境,在配置页的「使用电脑能力」里选:

local 模式——把执行能力挂在主程序所在的宿主环境上。Agent 可以调用本机的 Shell、本机的 Python、本机的文件系统工具。

这个模式的能力边界,等同于主程序进程本身的权限。它能访问什么,取决于进程的系统权限、运行用户、工作目录和操作系统限制。说白了:主程序能干的事,Agent 都能干。 这个模式很方便,但风险显而易见,官方文档里也明确提示要谨慎使用。

在 local 模式下,框架会给每个会话准备一个独立的工作区目录,目录名由会话标识规范化而来(不适合做文件名的字符会被替换成下划线)。本地文件工具的相对路径会解析到这个工作区下。

sandbox 模式——把执行动作放到隔离环境里。

这才是推荐的用法。它的好处不只是安全,还有一个很实用的特性:会话级资源复用

7.2 会话级复用是什么意思

这个概念第一次听可能有点抽象,我举个例子说清楚。

假设你在群里让助手帮你分析一份数据。它跑了一段 Python,把数据读进内存,画了张图发给你。然后你说「把横轴改成对数刻度再画一遍」。

如果每次执行都是全新的一次性环境,那第二次得从头再读一遍数据、重新装一遍依赖。如果环境能复用,第二次就可以直接在已有的状态上改。

框架的做法是:按会话标识缓存沙盒实例。在默认的主 Agent 流程下,这个标识通常就等于消息会话的统一标识。所以同一个会话的后续请求,会继续复用同一个沙盒;沙盒失效了会自动重建。

配置里还有几个参数值得注意:

  • warm_pool_size:预热池大小,提前准备好几个沙盒实例,减少首次调用的等待时间。资源紧张时可以调小甚至关掉;
  • TTL:沙盒的存活时长,超时会被回收;
  • 工作区根目录:对于新版驱动器,固定是 /workspace调用文件系统工具时要传相对路径(比如 reports/result.txt),而不是绝对路径(/workspace/reports/result.txt)。这个细节写插件时很容易踩。

另外还有一个面向「电脑使用」(Computer Use)的沙盒运行时,能通过统一的 SDK 创建 Linux、macOS、Windows、Android 等不同类型的沙盒,暴露 Shell、截图、鼠标、键盘、文件系统等接口。浏览器能力不是所有配置档都有,需要选支持浏览器能力的配置档才会挂载相关工具。

7.3 MCP:让助手接上外部工具

MCP 是一套让大模型和外部工具对话的开放协议。用一句白话解释:它规定了「工具应该怎么自我介绍」和「模型应该怎么调用工具」,只要双方都守这个规矩,任何工具都能即插即用。

从 v3.5.0 开始,框架原生支持这个协议,可以添加多个服务器、使用它们提供的函数工具。

配置文件在数据目录下,首次启动如果找不到会自动创建:

data/mcp_server.json

大多数服务器用 uv 或者 npm 启动,所以你的环境里得有这两个工具。Docker 部署的话,如果镜像里没带 Node,需要进容器装一下:

docker exec -it astrbot /bin/bash
apt update && apt install curl -y
# 装 nvm 后安装 Node 22
nvm install 22
node -v && npx -v

Docker 部署还有一个约定:把服务器装在 data 目录下,这样容器重建之后不会丢。

实际配置起来其实很轻。一个典型的服务器配置大概长这样:

{
  "mcpServers": {
    "arxiv-search": {
      "command": "uvx",
      "args": ["arxiv-mcp-server"],
      "env": {}
    }
  }
}

加完之后,模型在对话里就能自动判断什么时候该调用这个工具、传什么参数。你不需要写任何胶水代码。

这件事的价值在于解耦。 主程序不用为每一个新工具改代码,工具方也不用关心是哪个客户端在调用它。写一个自己的服务器也不复杂,本质就是一个按规范返回结构化数据的服务,Python 或者 TypeScript 都行。

7.4 Skills:给 Agent 的操作说明书

Skills 是另一套机制,可以理解成给 Agent 准备的「操作手册包」——里面通常包含说明文档和可执行的代码片段、脚本。

它的一个特点是高度可复用:同一份技能包可以在不同的项目和客户端之间通用。

在这个框架里,Skills 的优先级规则设计得比较细,我整理成表:

优先级

来源

说明

最高

当前会话工作区

同名时覆盖所有其他来源,仅对当前请求生效

次高

本地 Skills

优先于插件内置和沙盒专属

插件内置 Skills

优先于沙盒专属

最低

沙盒专属 Skills

仅在没有同名的其他来源时注入

上传方式是在管理面板的插件页面找到 Skills 入口,按格式要求上传。

有一个前置条件必须注意:如果选了沙盒执行环境但没有真正启动沙盒模式,Skills 是不会传给 Agent 的。这个坑我见过好几个人踩,表现是「上传了技能包但助手完全不知道有这回事」。

7.5 关于安全边界,我的实际态度

讲完能力得讲讲风险,这块不能含糊。

让一个大模型能在你的服务器上执行任意代码和 Shell 命令,本质上是把一部分控制权交给了一个概率模型。它绝大多数时候会按你的意图行事,但不保证百分之百。

我自己的三条原则:

  1. 能用沙盒就绝不用 local 模式。 方便一点点,不值得拿宿主机换。
  2. 给沙盒的网络访问做限制。 需要访问外部资源就配代理并做白名单,不要让它裸奔。
  3. 群聊场景一定要做权限控制。 一个开放的群里,任何人都能给助手发指令。如果助手有执行能力,就意味着任何人都能间接在你的服务器上做事。权限体系一定要开,管理员指令和普通用户指令必须分开。

八、知识库与 RAG:让助手回答你自己的问题

8.1 先说清楚 RAG 是什么

RAG 的全称是检索增强生成,白话讲就是「开卷考试」。

模型本身不知道你公司的内部文档写了什么。RAG 的做法是:先把你的文档切成小块、转成向量存起来;用户提问时,先用问题去向量库里检索最相关的几段,把这几段和问题一起塞给模型,让它照着这些材料回答。

这样模型就不用「背下」你的资料,而是每次现查现答。好处是资料更新只要重新入库,不需要重新训练模型。

8.2 完整流程

从 4.5.0 版本开始,知识库被重新设计并成为原生功能。整个流程是这样的:

flowchart TD
    A[上传文档 md/txt/docx/xlsx/pptx] --> B[Markitdown 转成 Markdown]
    B --> C[切分成文本块 chunk]
    C --> D[嵌入模型转成向量]
    D --> E[(向量库)]

    Q[用户提问] --> QE[问题转成向量]
    QE --> S[相似度检索]
    E --> S
    S --> R[重排序模型精排]
    R --> P[拼进提示词]
    P --> L[LLM 生成回答]

具体操作分四步:

第一步,配嵌入模型。 打开服务提供商页面 → 新增服务提供商 → 选择 Embedding。目前支持兼容 OpenAI API 和 Gemini API 的嵌入服务。

第二步,配重排序模型(可选但推荐)。 同样在服务提供商页面新增,选择重排序。重排序的作用是对初检的结果做二次精排,能明显提升召回质量。

第三步,创建知识库并上传文档。 进知识库页面点创建。框架用 Markitdown 把非文本文件转成对模型友好的 Markdown 格式,支持 md、txt、docx、xlsx、pptx 等格式,其中 md 和 txt 兼容性最好。单次最多同时上传 10 个文件,单文件不超过 128 MB。

大文件处理会比较慢,可以另开一个标签页在控制台看进度。上传成功会有绿色提示。

第四步,测试和切换。 页面上有「搜索内容」功能可以直接测召回效果,这个测试不消耗模型调用。聊天时用 /kb use 知识库名称 切换,完整指令看 /kb help

它支持多知识库管理,配置文件里可以为不同的配置档指定不同的默认知识库。配置项里有一个「默认知识库名称」,留空就表示不启用。

8.3 一个必须记住的坑:向量维度不能改

这是官方文档里专门用警告标出来的:一旦某个知识库选定了嵌入模型,就不要再修改该提供商的模型或向量维度信息。

原因是向量库里存的是固定维度的向量。你换了模型,新问题生成的向量维度和库里存的对不上,轻则召回率断崖式下跌,重则直接报错。

如果确

🔒
🔒 以下内容仅对更高等级用户组开放,请升级您的账户等级以查看完整内容。
您当前:游客 · 可见 60% 内容 · 升级至 注册用户 可见 70%
👀
游客
可见 60%
✓ 当前
👤
注册用户
可见 70%
社区精英
可见 100%
🛡️
社区守护
可见 100%
仅解锁本文,永久有效。如需PDF珍藏版,请联系站长获取。 当前单篇价格 ¥5
✏️ 发表评论

请先登录后发表评论

前往登录
📊 站点统计
今日发布0 篇
文章总数106 篇
昨日发布4 篇
本月发布14 篇
建站时间38 天
🔍 搜索
📅 日历
« 2026 » « 08 »
     12
3456789
10111213141516
17181920212223
24252627282930
31      
站点公告

联系站长

微信:wyxs1638
AIGC技术社区
致力于解码 AIGC前沿技术 与经验分享
纯粹的技术交流社区

💡 欢迎您的建议与反馈,让社区变得更好

快速通道
联系站长
站长微信二维码
AI交流群
AI交流群二维码