OpenSource-Hub

nanobot

프레임워크

HKUDS/nanobot

경량 오픈 소스 AI Agent 런타임

개요

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

FAQ (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)가 정수 epoch 초를 전달합니다. 오래된 밀리초 타임스탬프는 삭제되고 새로운 타임스탬프는 유지되며 메타데이터 타임스탬프가 초 단위인지 확인하는 테스트를 추가하세요.

원본 Issue #6120
문제 해결
Windows에서 nanobot webui 메모리 누수를 해결하는 방법(유휴 상태일 때 Python 프로세스가 5GB+까지 증가하는 문제)?

이것은 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()를 폴링하고 게이트웨이가 1초마다 클라이언트 상태를 폴링하기 때문에, 유휴 상태에서도 메모리가 지속적으로 증가했습니다.

해결 방법: PR #6507이 포함된 버전으로 nanobot을 업데이트하세요. 이 패치는 FileTime 구조체와 POINTER 타입을 모듈 수준으로 끌어올리고, kernel32 바인딩을 @lru_cache(maxsize=1)로 한 번만 캐시합니다:

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 프로세스를 주기적으로 재시작하세요. 해당 코드 경로는 Windows 전용이므로 Linux/macOS는 영향을 받지 않습니다.

원본 Issue #6506
문제 해결
터미널에서는 정상 작동하지만 nanobot CLI App에서 Obsidian CLI가 "unable to find Obsidian"를 반환하는 문제를 해결하는 방법

이 문제는 nanobot 0.3.5 CLI Apps가 축소된 환경에서 실행되면서 XDG_RUNTIME_DIR을 버리기 때문에 발생합니다. Obsidian은 GNOME/Wayland에서 실행 중인 데스크톱 앱을 찾기 위해 이 변수가 필요합니다. fix(cli-apps): preserve XDG_RUNTIME_DIR for desktop CLIs 수정이 포함된 릴리스로 nanobot을 업그레이드하세요. 해결 방법으로, 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 대신 데스크톱 런처로 연결될 수 있습니다.

원본 Issue #6024
문제 해결
왜 nanobot CLI가 macOS에서 명령줄이 중국어/CJK 문자로 끝날 때 시작 시 UnicodeDecodeError와 함께 크래시가 발생하며, 어떻게 해결할 수 있습니까?

원인: nanobot/cli/process_identity.py가 setproctitle을 임포트하기 전에 무조건 SPT_NOENV=1을 설정합니다. macOS에서는 이로 인해 setproctitle(<=1.3.8)이 argv 길이와 정확히 같은 크기의 버퍼를 사용하게 되고, off-by-one 버그로 마지막 바이트가 누락됩니다(py-setproctitle#167). 마지막 인자가 멀티바이트 UTF-8 문자(CJK/이모지)로 끝나면 시퀀스가 잘리고, 임포트 시점에 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__)" 명령으로 파일 위치를 찾아 변경 사항을 적용하면, CJK 인자를 사용해도 CLI가 정상적으로 시작됩니다. 선택적으로 import/setproctitle 호출을 try/except로 감싸면 프로세스 이름 설정이 절대 치명적인 오류를 일으키지 않도록 할 수 있습니다. 이 패치로 인해 Linux 동작은 변경되지 않습니다.

원본 Issue #6231
문제 해결
Windows에서 NANOBOT_HOME이 무시되어 여러 Nanobot 인스턴스 간 Telegram 충돌이 발생하는 문제를 해결하는 방법은?

영향을 받는 Windows 빌드에서는 Nanobot이 기본 구성 및 워크스페이스를 USERPROFILE에서 확인하므로, 두 인스턴스 모두 C:\Users\<user>\.nanobot\config.json을 로드하고 동일한 Telegram 봇 토큰을 사용하게 됩니다.

**해결 방법:** 각 인스턴스를 별도의 CMD 창에서 서로 다른 USERPROFILE로 시작하세요:

set "USERPROFILE=C:\Nanobot\instance2"
nanobot gateway

필요한 경우 해당 홈을 먼저 초기화/온보딩하고, 각 인스턴스에 별도의 Telegram 봇 토큰을 구성하세요.

영구적인 --home 선택자가 #6128에서 추가되고 있습니다. 사용 가능해지면 다음을 사용하세요:

nanobot --home C:\Nanobot\instance2 onboard
nanobot --home C:\Nanobot\instance2 gateway

원본 Issue #1739