DisPatch:一款用于本地AI代理的自托管聊天应用
- 发布日期
- 2026年7月11日
- 更新日期
- 2026年10月9日
- 作者
- Jacob Lloyd —— 项目完成后,在 AI 协助下撰写
- 阅读时长
- 约 17 分钟阅读
简单来说: DisPatch是一款聊天应用,它运行在您自己的电脑上,并且可以在家中的任何手机或笔记本电脑上使用。您可以通过它与同样运行在该电脑上的AI助手进行对话,还能将文件发送到电脑上供这些助手处理。一个PIN码机制确保了那些功能强大的AI助手不会被随意调用;因此,在这台供全家共用的设备上,用户只能使用那些经过安全授权的功能子集。
DisPatch是我自己开发的应用程序,目的是不再需要运行包含30个容器的 Rocket.Chat 环境来与我自己的AI代理进行交流。它仅由一个Python进程和一个SQLite数据库文件构成。家中的任何设备都能访问它;这些AI代理会像人类一样在各自的对话线程中回复信息。只要我把文件从手机上传到DisPatch,它们就会立刻出现在那些AI代理运行的机器上。2.0.0版本于2026年10月9日发布:下载包为3 MB的ZIP文件,其内置的测试套件能顺利通过1,915项测试。本页面介绍了该应用的功能、回复信息如何精准地发送到您的手机上,以及PIN码锁定机制如何防止家庭中的平板电脑被那些能够执行实际操作的AI代理所利用。
简而言之:
- 这是什么:一个专为本地AI代理设计的自托管式网页聊天工具(可作为 OpenClaw 网关使用,也可对接其他模型API);同时具备文件拖放功能,任何能访问主机的设备均可使用。
- 费用:免费。无需购买SaaS服务或注册账号。
- 所需条件:安装了Python 3.12及以上版本与
uv工具的Linux系统,或者Docker环境即可。若需要能调用外部工具的AI代理,则需安装OpenClaw。 - 功能亮点:为每个AI代理设立独立对话线程;支持带有“停止”按钮的实时回复流、内容重新生成与编辑功能;具备文件拖放能力;可嵌入各类工具与应用;提供十种主题样式;设有受PIN码保护的服务器级安全模式;还配有适用于定时任务的推送API。
- 下载方式:可获取2.0.0版本安装包,该版本与公开代码库中的
v2.0.0标签对应。采用MIT许可协议。
功能介绍
这些截图均来自一个使用模拟数据运行的沙盒环境。前四张截图来自 2.0 版本;“安全模式”与“文件服务器”相关的截图则来自 7 月份的测试版,不过它们在 2.0 版本中的运作方式完全相同。





- 跨设备同步对话记录:即便在手机上中途加入对话,显示的也是带有完整历史记录的同一对话流。用户可对对话进行置顶、归档、重命名及搜索操作。
- 流式 Markdown 回复功能:支持语法高亮的代码块与复制按钮;图片与视频则可通过弹窗预览;此外还提供可安装的 PWA 应用。
- 实时运行状态面板与停止按钮:状态栏会显示当前任务进展(如模型加载、内容生成或工具调用)。点击输入提示符即可查看智能体的思考过程及工具调用情况;按下“停止”按钮则可中断当前任务。
- 常规聊天应用控制功能:“重新生成”可保留之前的回复内容;用户可编辑任意消息并重新发送;还可引用回复、进行点赞/点踩操作或将其从对话上下文中移除。每个对话均可单独指定所使用的模型及推理深度级别,同时有一个进度条显示当前上下文的使用情况。
- 草稿与离线发送功能:未发送的消息会保留在对应对话中;即便在网络中断时发送消息,系统也会待网络恢复后自动发送。
- 工具与应用集成功能:点击“工具”按钮即可调用应用内的各类项目:静态文件夹、网页内容或自带后端与智能体的可信应用包。“任务面板”即为首个预置应用。
- 两种 AI 交互方式:用户可在设置面板中将某个机器人直接绑定至模型 API(如 LM Studio、Ollama、OpenAI、Anthropic 或任何兼容 OpenAI 的接口);也可通过 OpenClaw 网关连接那些需要调用工具并在本地执行操作的智能体。
- 推送式 API 功能:
POST /api/inject接口允许定时任务或其他智能体向指定对话中插入消息。正因如此,每日晨间简报能在无需我手动操作的情况下自动推送到手机上。 - 双层安全锁机制:PIN 码将具备完整权限的智能体与仅具备受限功能的“安全型”智能体区分开来。更多细节将在下文说明。
- 主机控制面板:可查看系统健康状态、存储空间使用率、数据库完整性及备份情况;同时还会列出所有配置不当的项目。
- 多语言与主题支持:提供八种界面语言,包括从右向左书写的阿拉伯语;另有十个主题可供选择。
- 本地文件预览功能:点击消息中的文件路径即可在应用内直接打开相应文件,即便是在手机端也是如此。只有在用户指定文件夹后系统才会启用此功能,且绝不会泄露任何敏感信息或系统路径。
智能体还可向对话中插入图片。只需在回复中加入 [[pic:prompt|caption]] 标记,即刻会显示占位符;待图片渲染完成后便会自动呈现实际图像。这些图片均由网络中的 GPU 服务器生成。若该服务器出现故障,则占位符会提示相关情况而非静默失败。
文件服务器
这是我最常用的功能。在任何设备上打开 DisPatch,将文件拖放到其中,文件便会上传至服务器;它们会按日期分组显示,图片和视频还会显示缩略图。

其价值在于文件的存储位置:它们就保存在运行代理程序的同一台机器上。比如我从手机上传的照片,几秒钟后就能被代理程序读取到;这样我就可以对照片进行描述、归档或发布到网站上,完全无需云盘或数据线。
代码中还设置了多种保护措施以防止常见故障发生:
- 在 FastAPI 缓冲上传内容之前,会先检查文件大小是否符合限制,从而避免手机端上传过大文件导致主机内存耗尽。
- 默认情况下总存储空间上限为20 GB(由
DISPATCH_FILES_TOTAL_MAX参数控制;设为0即关闭此限制)。 - 每个上传的文件都会先写入临时文件,同步完成后才重命名为正式文件名,这样即便连接中断也不会留下不完整文件。
- 被锁定的设备只能进行单向上传操作:它们可以向服务器发送文件,但无法浏览或下载服务器上的任何内容。
为何我选择自己构建,而非使用现有的 UI?
Rocket.Chat 确实能用,但为了实现“发送文本、接收回复并同步到各处”这一简单功能,却需要维护数据库以及大量容器,这实在是一种资源浪费。
对于“自托管式 AI 聊天应用”的需求,通常的解决方案是 Open WebUI 或 LibreChat,它们在与模型交互方面表现不错。不过我的需求有所不同:我希望有智能代理能参与到全屋共享的对话中;希望服务器能对儿童使用的设备施加访问限制;需要一个 HTTP 端点供脚本发送数据;还需要让文件能直接被那些智能代理读取。DisPatch 正是为了满足这些需求而诞生的。如果你只是想要一个漂亮的模型前端界面,那选择上述两者中的任何一个即可。
此外,DisPatch 无需任何构建步骤。其前端仅由纯 JS 模块以及普通的 CSS/HTML 构成,既不需要打包工具,也无需执行 npm run build。最初设定这一要求时,我的目标是“便于日后由 AI 代理进行修改”:只需编辑文件后刷新页面即可完成更改。如今我依然会做出同样的选择。
下载包中包含的内容
该压缩包名为 dispatch-2026-10.zip,即 DisPatch 2.0.0 版本。其内容与 公开代码库中的 v2.0.0 标签完全一致。我针对此版本做了如下检测:
| 项目 | 详情 |
|---|---|
| 下载大小 | 2,992,647 字节(2.9 MB);共319个文件;解压后大小为7.9 MB |
| SHA-256 | e9824d3c13bb3acd2d2eebcf2b162b14ae26eb86f56ca0e4ac8aa20f686a2398 |
| 后端 | 需要 Python 3.12+;使用 FastAPI 与 uvicorn;包含一个 SQLite 数据库文件,由 uv 进行管理。backend/app/ 目录下共有36,501行代码(其中 main.py 有12,331行),此外捆绑的“任务板”应用还包含5,497行代码 |
| 测试 | 共有30,726行 Python 测试代码;pytest 显示 1,915项测试全部通过;另有473项前端测试可通过 node --test 运行 |
| 前端 | 未经过构建的原生 JavaScript代码:除第三方库与测试代码外,还有约21,000行代码;另外还有约9,300行 CSS与 HTML代码 |
| 第三方库 | marked、highlight.js、DOMPurify。未调用任何 CDN服务 |
| 数据文件 | 默认情况下位于 ~/.local/share/local-chat/(该项目的旧名称)目录下:包含数据库、config.yaml、security.yaml、多媒体文件以及定期备份的数据库文件 |
| 许可证 | MIT |
自8月份的1.0.0版本压缩包发布后,有哪些变化呢?
- 回复处理效率提升且不会丢失。 现在消息会通过已建立的 WebSocket连接发送至代理网关,而无需为每条消息单独启动一个新的
openclaw进程。经实测,每次回复所需时间减少了约1秒(固定开销从2.26秒降至1.12秒)。模型生成文本后会实时流式传输至客户端。系统会持续跟踪每一条成功接收的回复直至其完全送达,因此即便连接中断或服务器重启,回复也能顺利发送。 - 许可证变更。 1.0.0版本采用 AGPL-3.0 许可证;2026年8月30日起项目改以 MIT 许可证发布,2.0.0版本亦遵循此许可证。此前的7月和8月发布的压缩包仍保留原地址,且各自附带了对应的
LICENSE文件。 - 编程终端功能已移除。 1.0.0版本曾提供可选的浏览器内终端功能(服务器端通过 PTY将输出流传输至 xterm.js)。由于我后来不再使用相关的编程代理工具,故2.0版本移除了该功能及其依赖的第三方库。当安装了
dsh后,DeepSeek Harness 面板可承担原终端的功能:支持启动、监控及终止实时会话。 - 新增功能: 对话控制、草稿与待发送消息管理、工具与应用集成、清单表格、本地内容预览器、图片标记功能;此外还新增了10种主题以取代原有的明暗模式切换选项,同时优化了消息行的视觉表现。完整更新列表可查阅代码库中的
CHANGELOG.md文件。
设置方法
以下内容摘自压缩包中的 README.md 以及 docs/ 目录。这只是一个普通的 uv 项目:
unzip dispatch-2026-10.zip
cd DisPatch-2.0.0/backend
uv sync --frozen
uv run pytest -q # 1,915 passed on my machine
uv run uvicorn app.main:app --host 0.0.0.0 --port 8765
或者跳过 Python 步骤:在解压后的目录顶层执行 cp .env.example .env && docker compose up -d。deploy/systemd/ 目录下包含了用于实现常驻运行模式的服务单元文件;而 docs/deploy-bare-metal.md 则说明了一个常被忽略的步骤:loginctl enable-linger。否则,当你关闭 SSH 会话后用户服务就会停止运行。
- 首先设置 PIN 码(点击齿轮图标,然后选择“安全”选项)。上述两个命令均监听
0.0.0.0,因此在设置 PIN 码之前,网络上的任何人都能完全访问该服务。在初步测试时,可使用--host 127.0.0.1(或在 Docker 环境下使用BIND_ADDR=127.0.0.1),并且切勿将该端口转发到互联网上。 - 编辑数据目录下的
config.yaml文件,确保其中配置的机器人id与你的 OpenClaw 代理端 ID 相匹配。该文件发生变动时会自动重新加载。 - 所有配置参数均通过以
DISPATCH_为前缀的环境变量来设定,具体选项可在.env.example中查看:HOST、PORT、DATA_DIR、AGENT_TIMEOUT(默认值为 900 秒)、MAX_CONCURRENCY(默认值为 3)以及GATEWAY_WS。 DISPATCH_MAX_CONCURRENCY用于限制同时运行的代理数量。默认值设为 3,这样可保护运行本地模型的机器。若有第四个请求出现,它会排队等待而非被丢弃。
DisPatch 本身并不包含 OpenClaw。对于代理端而言,它要求同一主机上必须有 OpenClaw 网关才行。即便没有该网关,程序依然能启动并输出相应警告信息。此时线程管理、注入 API、文件服务器、PIN 码锁定机制、各类工具以及模型调用接口均仍可正常使用。我正是采用这种方式来测试压缩包:直接解压后执行 uv sync,选用一个空闲端口,且无需配置网关。
回复是如何送达您的
我们花费大量精力处理各种异常情况:比如回复发送过程中连接中断、服务器重启时任务仍在进行中,或者某个子代理延迟十分钟才给出回复。传输方式由 DISPATCH_GATEWAY_WS 决定。若该参数未设置,则每条消息都会触发一个 openclaw agent,该进程在运行结束后将回复返回。而 shadow则会模拟连接过程并记录本应发送的内容,但实际并不真正发送。当设为 1 时,消息会通过网关套接字发送,回复也会通过该套接字流式传输回来。我目前使用的就是 1 设置。压缩包中该选项默认处于关闭状态,因此在您手动开启之前,回复的送达方式不会发生任何变化。
开启套接字后,网关所接收的所有任务都会被记录到“进行中任务表”中,随后通过网关自身的“等待指定任务完成”机制完成处理。即便实时传输链路中断,任务结束后回复依然能顺利送达;服务器宕机时那些处于处理状态的任务也能在重启后被恢复。只有网关完全未接收过的任务才会被重新发送,从而确保不会出现重复发送的情况。
关于后备机制有一点需要注意:转录文件扫描功能需要读取 OpenClaw 生成的会话文件;不过较新版本的 OpenClaw 已将会话信息存储至数据库中。在此类环境下,DisPatch 会在启动时提示基于文件的后备机制无法运行,此时套接字便成为唯一的回复传输途径。这也是建议开启套接字功能的另一个重要原因。
无论通过哪种途径送达,所有候选回复都会经过同一个去重流程检查:若某回复已被发送过,即便多次出现也只会显示一次。即便 CLI 端发生错误,扫描机制仍会在放弃前执行,因为模型往往在进程崩溃前便已将回复内容写入转录文件了。
双层锁定机制:普通模式与安全模式
未锁定的模式可不是儿戏。在该模式下,系统允许相关程序编辑代码、将更改推送至我的在线网站、运行各种工具并管理所在的服务器。而锁定模式则仅支持常规聊天功能;虽然仍能用于提问或寻求帮助,但无法执行上述操作。由于家庭电话并非始终由成年人使用,因此服务器会强制启用锁定机制。以下是请求的处理流程:
除非在安全设置中手动开启,否则‘记住设备’功能默认处于关闭状态;开启后,可信设备的有效期为30天。点击已标记为可信设备的‘锁定’按钮可使其不再被信任;更改PIN码则会使所有已标记的可信设备均失去信任资格。服务器最多仅能记录10台可信设备。若存储可信设备信息的文件损坏,则所有设备均被视为不可信,不过PIN码验证功能依然可用。
倘若因操作失误导致自己无法登录,可通过两种方式恢复访问权限:使用恢复代码文件,或直接编辑security.yaml配置文件。若security.yaml文件本身已损坏,系统则会保持锁定状态,而不会向局域网内的任何用户开放服务。此设计是出于安全考量而特意如此设定的。
注意事项/易错点
- 注入 API 的字段名为
content。POST /api/inject要求的请求体格式为{"bot_id": "...", "content": "..."}。发送纯text是最常见的集成错误,我也犯过这个错。 - 切勿将长消息作为 CLI 参数传递(即使在回退路径下这也很重要)。Linux 对单个参数的长度限制为 128 KB(
MAX_ARG_STRLEN),过长的消息会导致进程启动失败并出现 E2BIG 错误。正确的做法是将消息写入临时文件,然后传递--message-file参数。千万别为了“简化”操作而又把消息当作参数使用。 - 会话密钥需小写,但机器人 ID 则不必。 OpenClaw 会将会话密钥转换为小写形式,不过你的机器人 ID 可以包含大小写混合字符(如
Alpha、My_Bot)。如果采用区分大小写的匹配方式,虽然其他功能仍能正常运行,但面板显示及延迟回复功能会失效。正确的修复方式是先执行精确匹配,再尝试小写形式作为后备方案。 - CLI 仅返回最终生成的内容块。 由于没有使用套接字通信,智能体在多次工具调用之间输出的内容只会保存在其转录记录中。正因如此才有了转录记录清理机制;即便启用了套接字通信,该机制仍会作为后备措施继续运行。
- 处理 WebSocket 请求时需校验 Origin 字段。 HTTP 中间件不会对 WebSocket 路由生效。DisPatch 会在握手阶段进行身份验证:若
Origin中的主机名与Host不匹配,请求就会被拒绝,这样能有效防止跨站点的 WebSocket 劫持行为。非浏览器客户端不会发送 Origin 字段,因此可顺利通过验证。 - 绝不可将上传的 SVG 文件当作图片来展示。 直接打开 SVG 文件可能会在其所在源站点中执行恶意脚本,从而形成存储型 XSS 漏洞。DisPatch 会拒绝将 SVG 视为媒体文件,且发送给客户端的所有媒体内容均会附带沙箱化 CSP 策略与
nosniff指令。 - Service Worker 更新会导致旧标签页仍运行旧版 JS。 这种现象看起来就像程序出现了回退。解决办法就是在触发
controllerchange事件时自动刷新页面。
实现思路解析
即便您从未运行过我提供的压缩包,整个架构其实由四个可替换的组件构成:
- 聊天后端:负责管理对话历史记录。它由一个小型 Web 服务器构成(此处使用的是 FastAPI 以及以 WAL 模式运行的 SQLite 数据库),还包含一个用于实时更新的 WebSocket 接口,以及一个用于接收消息的普通 HTTP 端点。这个组件取代了传统数据库及众多容器的作用。
- 代理网关:后端程序通过它与其他服务通信。此处使用的是 OpenClaw,但实际上任何能够接收会话 ID、消息内容并返回文本的服务均可胜任此角色。由于它是独立运行的进程,即便发生崩溃或需要升级,也不会影响聊天应用的正常运行。
- 模型服务器:位于网关之后,包括 LM Studio、vLLM 以及 Ollama。这些服务器的管理属于网关的职责范围,与聊天应用并无直接关联。
- 可选的媒体服务:比如运行在另一台机器上的图像生成器,可供各类代理作为工具调用。后端仅需存储其返回的结果即可。
无论您采用何种技术栈,以下原则都同样适用:
- 务必在服务器端强制启用锁定模式,切勿仅依赖 CSS 来实现。
- 将“消息必须仅被发送给用户一次”视为需要解决的传输问题,并为此设计去重机制。
- 如果后续由 AI 代理负责维护前端界面,那么尽量保持前端无需编译即可运行的状态。
相关链接:基于 OpenClaw 的本地 AI 代理堆栈 · DeepSeek Harness 初探 · 利用本地 AI 代理管理个人网站 · 如何搭建自己的 LLM 助手
下载
仅限个人使用免费。如果它替你省下了一下午的时间,欢迎点旁边的咖啡按钮支持一下。