Back to Articles

Nanobot: Building a Multi-Channel AI Agent That Actually Ships

[ View on GitHub ]

Nanobot: Building a Multi-Channel AI Agent That Actually Ships

Hook

With 41,000+ stars and daily releases, nanobot has become the most actively developed personal AI agent framework—yet most developers haven't heard of it. Here's why that's about to change.

Context

The personal AI agent space is littered with abandoned prototypes and research demos. AutoGPT showed us the promise of autonomous agents but never escaped the terminal. LangChain gave us the building blocks but left production deployment as an exercise for the reader. Meanwhile, developers who wanted to build actual AI assistants faced a brutal reality: integrating with real communication platforms—Discord threads, WeChat work groups, Slack channels—requires navigating a maze of OAuth flows, webhook configurations, and message threading models that have nothing to do with LLMs.

Nanobot emerged from HKUDS (Hong Kong University Data Science lab) as a direct response to this gap. The team observed that most agent frameworks obsess over the agent loop—the ReAct pattern, tool calling, memory systems—while treating deployment as an afterthought. Nanobot inverts this priority. It's built channel-first, treating multi-platform messaging integration as a core architectural concern rather than a plugin. The result is a framework where adding Claude or GPT-4 is trivial, but connecting to WeChat, Feishu, Teams, and Discord is actually solved. For developers building agents that need to exist where users already are—not in yet another chat UI—this changes everything.

Technical Insight

At its core, nanobot implements a channel abstraction layer that normalizes messages across radically different platforms into a unified session model. Each channel adapter handles platform-specific quirks—Discord's thread hierarchy, Telegram's callback queries, WeChat's cryptographic verification—then feeds normalized events into a central event loop. Here's what a minimal Discord bot looks like:

from nanobot import Agent, DiscordChannel
from nanobot.providers import OpenAIProvider

agent = Agent(
    provider=OpenAIProvider(model="gpt-4"),
    system_prompt="You are a helpful assistant with memory.",
    tools=["search", "calculator"],
    memory="dream"  # Enables two-stage memory system
)

channel = DiscordChannel(
    token=os.getenv("DISCORD_TOKEN"),
    agent=agent,
    thread_aware=True  # Maintains separate sessions per thread
)

channel.run()

The thread_aware=True flag is doing heavy lifting here. Discord threads, Slack threads, and WeChat group replies all have different threading models, but nanobot's session manager creates isolated conversation contexts automatically. Under the hood, it maintains a session registry keyed by (channel_id, thread_id, user_id) tuples, handling cleanup and context switching without developer intervention.

The Dream memory system is where nanobot gets genuinely novel. Traditional agent frameworks bolt on vector databases or conversation summarization as afterthoughts. Dream implements a two-stage architecture: short-term memory lives in the active context window, while long-term memory uses an embedding-based retrieval system that doesn't just store conversations—it extracts and indexes 'skills' the agent discovers during operation. When the agent successfully completes a multi-step task, Dream's skill extractor analyzes the tool call sequence and stores it as a retrievable pattern:

# Dream automatically captures this sequence as a reusable skill
await agent.execute("Find the latest Python CVE and check if our dependencies are affected")
# Internally: search -> parse -> cross-reference -> report
# Skill indexed: "CVE dependency check workflow"

# Later conversations retrieve this skill
await agent.execute("Check for new security issues in our stack")
# Dream retrieves the CVE workflow skill and adapts it

This happens transparently. The skill discovery runs in background threads during idle time—nanobot literally 'dreams' about patterns in past conversations to improve future performance. The context compaction system kicks in when conversations approach token limits, using the LLM itself to distill critical information while preserving skill references.

For production deployment, nanobot supports multiple runtime modes. The WebSocket channel creates a bidirectional connection for custom UIs. The OpenAI-compatible API mode exposes an endpoint that mimics OpenAI's chat completion API with SSE streaming, letting you swap nanobot in wherever you're currently hitting OpenAI:

from nanobot.server import APIServer

server = APIServer(
    agent=agent,
    host="0.0.0.0",
    port=8000,
    auth_key=os.getenv("API_KEY")
)

server.run()
# Now curl localhost:8000/v1/chat/completions works like OpenAI

The tool execution sandbox deserves attention. Unlike frameworks that shell out to arbitrary commands, nanobot restricts tool execution to a configured workspace directory and runs shell commands in a restricted environment. You can enable tools like read_file, write_file, and execute_shell, but they're path-restricted and logged through Langfuse integration for observability. The MCP (Model Context Protocol) integration extends this safely—MCP servers run as separate processes, and nanobot communicates through stdio, providing isolation while enabling powerful extensions like database access or API integrations.

The provider abstraction is refreshingly simple. Supporting a new LLM requires implementing a single interface with generate() and stream() methods. The framework already includes adapters for OpenAI, Anthropic, DeepSeek, Gemini, and local models through Ollama, with automatic retry logic, rate limiting, and fallback chains built in.

Gotcha

The elephant in the room is stability. Nanobot ships multiple releases per day—sometimes major feature additions between morning and afternoon. The changelog shows WebSocket support added on a Tuesday, refactored on Wednesday, and extended with new event types by Friday. This velocity is impressive but terrifying for production systems. API contracts haven't solidified. There's no semantic versioning yet, no deprecation policy, and no migration guides between versions. If you deploy nanobot today and pin to a specific commit, you'll quickly diverge from the main branch where bugs are being fixed and features are landing.

The 'ultra-lightweight' branding is misleading once you start using multiple channels. Each channel integration pulls in platform-specific SDKs—discord.py for Discord, python-telegram-bot for Telegram, wechatpy for WeChat. Enabling all channels in a production deployment means megabytes of dependencies and non-trivial memory overhead. The core agent loop is genuinely minimal, but a fully-featured nanobot instance with Dream memory, three channel adapters, and Langfuse observability is not lightweight by any reasonable definition. This isn't necessarily bad—the functionality justifies the footprint—but it sets wrong expectations.

Python 3.11+ requirement cuts off a surprising number of deployment environments. Enterprise Linux distributions and many container base images still ship Python 3.9 or 3.10. You'll need custom builds or user-space Python installations, which complicates deployment automation. The dependency on newer typing features and asyncio improvements makes backporting impractical.

Verdict

Use nanobot if you're building personal AI agents that need to live on multiple communication platforms, especially if you're targeting Asian markets (WeChat, Feishu support is rare). The channel abstractions genuinely solve hard problems, and the Dream memory system is legitimately innovative. It's perfect for experimental projects, personal assistants, or team tools where you control the deployment and can absorb updates weekly. The production deployment paths (systemd services, API mode) are well-designed for self-hosted scenarios. Skip it if you need API stability, are building customer-facing SaaS products, or can't commit to tracking upstream changes. The daily release cadence isn't hyperbole—this codebase moves fast and will break things. Also skip if you actually want minimal dependencies; despite the name, this is a batteries-included framework. For stable, enterprise-grade agent orchestration, stick with LangGraph or Semantic Kernel. For bleeding-edge personal AI that ships to real platforms today, nanobot delivers.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/ai-agents/hkuds-nanobot.svg)](https://starlog.is/api/badge-click/ai-agents/hkuds-nanobot)