项目简介
nanobot 是开源的超轻量级个人 AI Agent 运行时,支持 WebUI、聊天频道、工具、记忆、MCP、模型路由、自动化和部署。核心代码精简易读,方便定制和扩展。
README 预览
\n \n \n\n\n\n \n English |\n 简体中文 |\n 繁體中文 |\n Español |\n Français |\n Bahasa Indonesia |\n 日本語 |\n 한국어 |\n Русский |\n Tiếng Việt\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n\n🐈 **nanobot** is an open-source, ultra-lightweight personal AI agent you can truly own. It keeps the agent core small and readable while giving you the practical pieces for real long-running work: WebUI, chat channels, tools, memory, MCP, model routing, automation, and deployment.\n\n## Start Here\n\n| You want to... | Go to |\n|---|---|\n| Install nanobot with no terminal/config background | [Start Without Technical Background](./docs/start-without-technical-background.md) |\n| Install quickly and get one CLI reply | [Install](#-install) and [Quick Start](#-quick-start) |\n| Open the bundled browser UI | [WebUI](#-webui) |\n| Connect Telegram, Discord, WeChat, Slack, Email, Mattermost, or another chat app | [Chat Apps](./docs/chat-apps.md) |\n| Configure providers, fallback models, Langfuse, MCP, web tools, or security | [Docs](./docs/README.md) and [Configuration](./docs/configuration.md) |\n| Understand or extend the internals | [Architecture](./docs/architecture.md) and [Development](./docs/development.md) |\n| Deploy to the cloud in one click | [Deploy to Render](#deploy-to-render) |\n\n## Deploy to Render\n\nDeploy nanobot's gateway and bundled WebUI as a single web service with persistent memory. Render reads [`render.yaml`](./render.yaml) and prompts for two secrets on deploy: `ANTHROPIC_API_KEY` and `NANOBOT_WEB_TOKEN` (the password that gates the public WebUI — generate a strong random value, e.g. `openssl rand -hex 32`).\n\n> **Note:** The blueprint attaches a persistent disk so sessions, memory, and WebUI history survive restarts. Persistent disks require a paid service (they are not available on Render's free tier).\n\n[](https://render.com/deploy?repo=https://github.com/HKUDS/n
常见问题 (5)
故障排除如何修复 Nanobot 中 WhatsApp replay filter 从不触发以及时间戳显示为遥远未来日期的问题?
单位不匹配的原因是 neonize 提供的 MessageInfo.Timestamp 采用 Unix 毫秒,而 time.time() 和下游元数据使用 Unix 秒。在 nanobot/channels/whatsapp/runtime.py 中读取时间戳后立即对其进行归一化:
timestamp = float(_safe_attr(info, "Timestamp", 0) or 0)
if timestamp >= 1e11: # Unix milliseconds; seconds would be past year 5000
timestamp /= 1000.0
完成此更改后,timestamp < self._started_at 能够正确过滤重放的消息,并且 "timestamp": int(timestamp) 会转发整数形式的 Unix 纪元秒。添加测试以覆盖以下情况:旧的毫秒时间戳被丢弃、较新的时间戳被保留,以及元数据时间戳以秒为单位。
故障排除如何修复 Windows 上的 nanobot webui 内存泄漏问题(Python 进程在空闲时增长到 5GB+)?
这是一个已知 bug,由 nanobot/process_runtime.py 中的 _windows_process_identity() 引起。它在每次调用时都会重新定义一个 ctypes.Structure 子类、POINTER 类型以及一个 WinDLL('kernel32') 绑定。由于 ctypes 将这些对象保存在一个永久性的模块级 _pointer_type_cache 中,每次调用会泄漏约 6.5 KB(约 2.6 MB/分钟,约 3.7 GB/天),垃圾回收器无法回收这些内存。由于 webui 启动器每 0.5 秒轮询一次 runtime.status(),gateway 每 1 秒轮询一次客户端状态,即使处于空闲状态,内存也会持续增长。
修复方法:将 nanobot 更新到包含 PR #6507 的版本。该补丁将 FileTime 结构和 POINTER 类型提升到模块级别,并使用 @lru_cache(maxsize=1) 对 kernel32 绑定只缓存一次:
class _FileTime(ctypes.Structure):
_fields_ = [("low", ctypes.c_uint32), ("high", ctypes.c_uint32)]
_FILE_TIME_PTR = ctypes.POINTER(_FileTime)
@lru_cache(maxsize=1)
def _windows_kernel32():
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
# configure argtypes/restype once here
return kernel32
def _windows_process_identity(pid: int):
if os.name != "nt":
return None
kernel32 = _windows_kernel32()
handle = kernel32.OpenProcess(0x1000, False, pid)
...
如果无法立即升级,可以定期重启 webui 进程作为临时解决方法。Linux/macOS 不受影响,因为该代码路径仅适用于 Windows。
故障排除如何修复 Obsidian CLI 在 nanobot CLI 应用中返回 "unable to find Obsidian",但在终端中却能正常工作的问题?
出现这种情况是因为 nanobot 0.3.5 CLI Apps 在精简的环境中运行,会丢弃 XDG_RUNTIME_DIR;而 Obsidian 需要它来定位 GNOME/Wayland 上正在运行的桌面应用。请将 nanobot 升级到包含修复 fix(cli-apps): preserve XDG_RUNTIME_DIR for desktop CLIs 的版本。作为临时解决方案,可以通过 shell exec 工具运行 Obsidian CLI,显式设置该变量并使用 CLI 启动器路径:
XDG_RUNTIME_DIR=/run/user/$(id -u) /home/<user>/.local/bin/obsidian tags total
例如:
XDG_RUNTIME_DIR=/run/user/1000 /home/alice/.local/bin/obsidian tags counts
使用以下命令确认该值:
echo "$XDG_RUNTIME_DIR"
另外,请确保网关是从桌面会话启动的,以便它继承 XDG_RUNTIME_DIR。使用 /usr/bin/obsidian 可能会解析到桌面启动器,而不是用户安装在 ~/.local/bin/obsidian 的 CLI。
故障排除为什么 nanobot CLI 在 macOS 上启动时,当命令行以中文/CJK 字符结尾时会因 UnicodeDecodeError 而崩溃,以及如何修复?
原因:nanobot/cli/process_identity.py 在导入 setproctitle 之前无条件地设置了 SPT_NOENV=1。在 macOS 上,这会使 setproctitle(<=1.3.8)使用长度恰好等于 argv 的缓冲区,其 off-by-one bug 会丢弃最后一个字节(py-setproctitle#167)。如果最后一个参数以多字节 UTF-8 字符(CJK/emoji)结尾,该字节序列会被截断,导入时 macOS 特有的 getproctitle() 调用便会抛出 UnicodeDecodeError,导致 CLI 在发起任何模型调用之前就被终止。修复方法:仅在 Linux 上设置 SPT_NOENV(在 macOS 上它毫无意义)。编辑 nanobot/cli/process_identity.py:
import sys
def _set_process_title(title: str) -> None:
if sys.platform == "linux":
os.environ.setdefault("SPT_NOENV", "1")
from setproctitle import setproctitle
setproctitle(title)
在你的 uv tool 环境中运行 python -c "import nanobot.cli.process_identity as m; print(m.__file__)" 找到该文件,应用此修改后,CLI 即可在传入 CJK 参数时正常启动。可选做法:将 import/setproctitle 调用包裹在 try/except 中,使进程命名永远不会成为致命错误。此补丁不会改变 Linux 上的行为。
故障排除如何修复 NANOBOT_HOME 被忽略导致在 Windows 上多个 Nanobot 实例之间发生 Telegram 冲突的问题?
在受影响的 Windows 版本中,Nanobot 会根据 USERPROFILE 解析默认配置和工作区,因此两个实例都会加载 C:\Users\<user>\.nanobot\config.json,并使用相同的 Telegram 机器人令牌。
**临时解决方法:**在单独的 CMD 窗口中使用不同的 USERPROFILE 启动每个实例:
set "USERPROFILE=C:\Nanobot\instance2"nanobot gateway
如有需要,请先对该主目录执行初始化/onboard,并为每个实例配置单独的 Telegram 机器人令牌。
#6128 中正在添加一个永久性的 --home 选择器。该功能可用后,请使用:
nanobot --home C:\Nanobot\instance2 onboardnanobot --home C:\Nanobot\instance2 gateway