Build a Discord AI Bot with Agno (Teams, Memory, Knowledge Base)

A production-ready Discord AI bot with streaming responses, vector knowledge base, Cognee memory, team orchestration, and self-improvement tools.

Build a Discord AI Bot with Agno (Teams, Memory, Knowledge Base)

This guide walks through building a Discord AI bot using Agno. The bot streams responses in real-time, remembers conversations, searches a knowledge base, and can delegate work to specialized agents.

View on GitHub

What This Bot Does

  • Responds when you @mention it in Discord
  • Streams responses (you see the message update as it generates)
  • Stores memories and learns your preferences over time
  • Searches a knowledge base (LanceDb or PgVector)
  • Runs scheduled tasks via cron
  • Delegates complex work to agent teams

Prerequisites

  • Python 3.12+
  • Discord bot token
  • Model API key (any OpenAI-compatible provider)
  • Optional: GitHub token for GitHub tools

If you’re new to Python packaging, check out UV.

Quick Start

git clone https://github.com/bitdoze/bitdoze_bot.git
cd bitdoze_bot
uv sync
python scripts/setup_bot.py

The setup wizard asks for your Discord token, API keys, and optional settings. It creates ~/.bitdoze-bot/ with everything you need.

Discord Bot Setup

  1. Go to discord.com/developers
  2. Create an application, add a bot
  3. Copy the token
  4. Enable Message Content Intent (required)
  5. Invite to your server with appropriate permissions

Project Structure

bitdoze-bot/
  main.py
  config.example.yaml
  docker-compose.yml
  bitdoze_bot/
    agents.py
    discord_bot.py
    cron.py
    heartbeat.py
    discovery_tools.py
    tool_permissions.py
    run_monitor.py
  scripts/
    setup_bot.py
    generate_soul.py
    setup_knowledge.py
  tests/

Core Features

Streaming: Messages update in Discord as the agent generates content. You see progress instead of waiting for a complete response.

Memory: SQLite-backed storage for conversations. Optional Cognee integration for long-term memory with semantic search.

Knowledge Base: Vector search using LanceDb (no setup) or PgVector (requires PostgreSQL). Add documents to workspace/knowledge/ and the bot can reference them.

Teams: Multiple agents that can collaborate. The delivery team might have an architect plan and a software engineer implement.

Self-improvement: Discovery tools let the bot save and search its own learnings. Combined with learned_knowledge: agentic, it decides when to store new insights.

Automation: Heartbeat checks every 30 minutes. Cron jobs run on a schedule from workspace/CRON.yaml.

Tool permissions: Runtime allow/deny rules with audit logging. Block shell access in public channels, allow it in private ones.

Configuration

Environment Variables

DISCORD_BOT_TOKEN=your_discord_token
OPENAI_API_KEY=your_api_key
GITHUB_ACCESS_TOKEN=optional_github_token

Basic Config

model:
  provider: openai_like
  id: stepfun/step-3.5-flash:free
  base_url: https://openrouter.ai/api/v1
  api_key_env: OPENAI_API_KEY
  structured_outputs: false

discord:
  token_env: DISCORD_BOT_TOKEN

runtime:
  streaming_enabled: true
  streaming_edit_interval: 1.5
  agent_timeout: 600

memory:
  mode: automatic
  db_file: data/bitdoze.db
  enable_session_summaries: true

learning:
  enabled: true
  mode: always
  stores:
    user_profile: true
    user_memory: true
    learned_knowledge: agentic

Streaming

Set runtime.streaming_enabled: true to see responses update in real-time. The bot edits the Discord message as content arrives. Falls back to non-streaming for team runs.

Knowledge Base

knowledge:
  enabled: true
  backend: lancedb  # or pgvector
  embedder: text-embedding-3-small
  lance_uri: data/lancedb
  table_name: bitdoze_knowledge

Run python scripts/setup_knowledge.py after adding documents to workspace/knowledge/.

Cognee Memory (Optional)

memory:
  cognee:
    enabled: true
    base_url: http://localhost:8000
    auto_sync_conversations: true
    auto_recall_enabled: true
    auto_recall_limit: 5

Start Cognee with docker compose up -d.

Agents and Routing

agents:
  default: main
  workspace_dir: workspace/agents
  definitions:
    - name: main
      tools: [web_search, website, github, file, discoveries]
    - name: research
      tools: [web_search, website, github]
      skills: [web-research]
  routing:
    rules:
      - agent: delivery-team
        starts_with: ["team:"]
      - agent: research
        contains: ["research:"]

Teams

teams:
  definitions:
    - name: delivery-team
      members: [architect, software-engineer]
      respond_directly: true
      determine_input_for_members: true
      delegate_to_all_members: false
      add_team_history_to_members: true
      num_team_history_runs: 5

Team Configuration

Avoid setting both delegate_to_all_members: true and respond_directly: true unless you want broadcast behavior. The bot will warn you.

Add New Agents

Create a folder in workspace/agents/<name>/:

agent.yaml

name: product-manager
enabled: true
model:
  id: glm-4.7
  base_url: https://api.z.ai/api/coding/paas/v4
  api_key_env: GLM_API_KEY
tools: []
skills: []

AGENTS.md

# Product Manager Agent

Focus on scope, priorities, and delivery risk.

Add to a team in config.yaml:

teams:
  definitions:
    - name: delivery-team
      members: [architect, software-engineer, product-manager]

Use in Discord

Normal mention:

@YourBot help me design a migration plan

Force a specific agent or team:

@YourBot agent:research find papers on distributed systems
@YourBot agent:delivery-team Build and validate this feature
@YourBot team: implement the API with tests

Heartbeat and Cron

workspace/CRON.yaml

enabled: true
timezone: Europe/Bucharest
channel_id: 123456789012345678
jobs:
  - name: daily-status
    cron: "0 9 * * *"
    agent: main
    message: "Send a daily status update."
    session_scope: isolated

Heartbeat runs every 30 minutes using workspace/HEARTBEAT.md. If it returns HEARTBEAT_OK, the message is suppressed.

Docker (PgVector + Cognee)

Optional PostgreSQL with pgvector and Cognee API:

docker compose up -d

This starts PostgreSQL on port 5532 and Cognee on 127.0.0.1:8000.

Tool Permissions

Control which tools can run where:

tool_permissions:
  enabled: true
  default_effect: deny
  rules:
    - effect: allow
      tools: [shell]
      role_ids: [123456789012345678]
  audit:
    enabled: true
    path: logs/tool-audit.jsonl

Production (systemd)

~/.config/systemd/user/bitdoze-bot.service

[Unit]
Description=Bitdoze Bot
After=network.target

[Service]
WorkingDirectory=/home/you/.bitdoze-bot
ExecStart=/home/you/.local/bin/uv run main.py
Restart=always
RestartSec=5
Environment=PYTHONUNBUFFERED=1
EnvironmentFile=/home/you/.bitdoze-bot/.env

[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable --now bitdoze-bot
journalctl --user -u bitdoze-bot -f

Scripts

ScriptPurpose
scripts/setup_bot.pyInteractive setup wizard
scripts/generate_soul.pyGenerate SOUL.md personality
scripts/setup_knowledge.pyInitialize knowledge base

Tests

uv run pytest -q

Ready to Run

You now have a Discord AI bot with memory, knowledge search, team orchestration, and scheduled tasks. Clone the repo, run the setup wizard, and start chatting.