Le Duy Khuong

Chuỗi: running-ai-agents-production · Phần 5

AI / Hệ thống agentic

Từ bot cá nhân đến platform cho team — Playbook thực tế

Playbook thực tế scale AI agent cá nhân thành platform cho team — multi-agent architecture, Telegram topic routing, automation stack, và cost optimization từ triển khai thực tế.

2026-03-1912 phút đọcVI

Phần 5 của 5100% hoàn thành

Từ bot cá nhân đến platform cho team — Playbook thực tế

English title: From Personal Bot to Team Platform — A Migration Playbook

Tôi bắt đầu với 1 AI bot cho riêng mình — chat qua Telegram, giúp tra cứu, viết docs, nhắc việc. 2 tuần sau, tôi vận hành 3 instances phục vụ 3 nhóm người khác nhau. Không phải vì lên kế hoạch từ đầu — mà vì nhu cầu tự nhiên scale.

Bài viết này là playbook thực tế cho hành trình đó: từ 1 bot cá nhân → platform cho team, với mọi quyết định kiến trúc, config, và bài học dọc đường.


Phase 0: Bot cá nhân (tuần 1)

Setup ban đầu

  • 1 framework AI agent (open-source)
  • 1 Telegram bot (BotFather)
  • 1 Docker container trên VPS
  • Model: Claude Sonnet
  • DM only — chỉ tôi dùng

Mọi thứ đơn giản

{
  "agents": { "defaults": { "workspace": "~/.openclaw/workspace" } },
  "channels": {
    "telegram": {
      "botToken": "<TOKEN>",
      "dmPolicy": "allowlist",
      "allowFrom": ["tg:<MY_ID>"]
    }
  }
}

Bot hoạt động. Memory lưu daily logs. Heartbeat check-in mỗi 30 phút. Tổng chi phí: ~$30/tháng cho Claude API.


Phase 1: "Cho team thử" (tuần 2) — Sai lầm

Yêu cầu mới

Team công việc (5 người) muốn bot trong group Telegram. Gia đình (4 người) cũng muốn. Tôi nghĩ: "Thêm group ID vào config, done."

Vấn đề xuất hiện

  1. Token cost explosion — 200K context window mặc định + không history limit = $700/tháng (đã viết bài riêng)
  2. Context leak — DMs share 1 session, user A thấy context user B
  3. Tool access — mọi member có thể trigger bot chạy shell commands (!)
  4. Memory exposure — personal notes accessible qua memory_search trong groups

Bài học Phase 1

"Hoạt động" và "an toàn cho multi-user" là 2 thứ hoàn toàn khác nhau.


Phase 2: Tách instances (tuần 3) — Đúng hướng

Quyết định kiến trúc: 1 gateway per trust boundary

VPS (Docker host)
├── openclaw-dso (port 18789)     → Team công việc → Sonnet
├── openclaw-family (port 18791)  → Gia đình → Haiku
└── openclaw-personal (port 18793) → Cá nhân (DM only) → Sonnet

Lý do tách:

  • Team công việc ≠ gia đình ≠ cá nhân (khác trust boundary)
  • Model selection khác (work cần quality, family cần budget)
  • Memory isolation (work decisions không nên leak vào family chat)
  • Cost tracking riêng

Chi phí tách: ~200MB RAM per container. Negligible.

Config per instance

Team instance — hardened:

{
  "agents": {
    "defaults": {
      "sandbox": { "mode": "all" },
      "model": { "primary": "anthropic/claude-sonnet-4-5" }
    }
  },
  "session": { "dmScope": "per-channel-peer" },
  "tools": {
    "deny": ["group:runtime", "group:fs", "group:ui"],
    "elevated": { "enabled": false }
  }
}

Family instance — budget:

{
  "agents": {
    "defaults": {
      "model": { "primary": "anthropic/claude-haiku-4-5-20251001" }
    }
  },
  "channels": {
    "telegram": { "historyLimit": 20 }
  }
}

Personal instance — full access:

{
  "session": { "dmScope": "main" },
  "agents": {
    "defaults": {
      "sandbox": { "mode": "non-main" }
    }
  }
}

Phase 3: Telegram Forum Topics (tuần 4) — Game changer

Phát hiện: per-topic agent routing

Telegram forum supergroups cho phép chia conversation thành topics. Framework hỗ trợ route mỗi topic tới config khác nhau:

Team Group (Forum Supergroup)
├── General (topic 1)      → requireMention: true
├── HITL Approvals (topic N) → requireMention: false (auto-respond)
├── Reports (topic M)      → cron delivery target
└── Dev Discussion (topic X) → enabled: false (human only)
{
  "channels": {
    "telegram": {
      "groups": {
        "<GROUP_ID>": {
          "groupPolicy": "open",
          "requireMention": true,
          "topics": {
            "<HITL_TOPIC>": { "requireMention": false },
            "<REPORTS_TOPIC>": { "requireMention": false },
            "<DEV_TOPIC>": { "enabled": false }
          }
        }
      }
    }
  }
}

Mỗi topic có session riêng: agent:dso:telegram:group:<id>:topic:<threadId>. Hoàn toàn isolated.

Impact

  • HITL topic: Bot tự trả lời mọi message → approval workflow không cần mention
  • Reports topic: Cron jobs deliver kết quả vào đây → notification channel tự động
  • Dev topic: Bot tắt → con người thảo luận tự do
  • General: Bot chỉ respond khi @mentioned → không spam

Phase 4: Automation stack (tuần 5)

3 pillars: Heartbeat + Cron + Hooks

MechanismSchedulePurpose
HeartbeatMỗi 30 phútPeriodic check-in, HEARTBEAT.md checklist
CronCustom scheduleDaily reports, HITL checks, memory reflect
HooksEvent-drivenAudit logging, session backup, context injection

Heartbeat — "Bot chủ động nhắc"

{
  "heartbeat": {
    "every": "30m",
    "target": "telegram",
    "to": "<GROUP_ID>:topic:<REPORTS_TOPIC>",
    "activeHours": { "start": "08:00", "end": "22:00" },
    "lightContext": false
  }
}

Bot đọc HEARTBEAT.md mỗi 30 phút, check nếu có gì cần attention → gửi vào reports topic. Ngoài giờ → skip.

HEARTBEAT_OK = silent ack. Bot chỉ gửi tin khi có nội dung thực sự.

Cron — "Scheduled intelligence"

# Morning HITL check
openclaw cron add \
  --name "HITL Status" \
  --cron "0 9 * * *" \
  --session isolated \
  --message "Check pending HITL approvals. Report status." \
  --announce --channel telegram \
  --to "<GROUP_ID>:topic:<HITL_TOPIC>"
 
# Weekly report
openclaw cron add \
  --name "Weekly Report" \
  --cron "0 18 * * 5" \
  --session isolated \
  --message "Generate weekly activity summary." \
  --announce --channel telegram \
  --to "<GROUP_ID>:topic:<REPORTS_TOPIC>"
 
# Nightly memory reflect
openclaw cron add \
  --name "Memory Reflect" \
  --cron "0 3 * * *" \
  --session isolated \
  --message "Review today's memory. Extract key decisions." \
  --light-context

--session isolated = fresh session mỗi lần chạy. Không carry over context từ lần trước. Clean.

--light-context = chỉ inject HEARTBEAT.md, không full bootstrap → tiết kiệm tokens cho background tasks.

Hooks — "Invisible infrastructure"

Audit log chạy im lặng:

// hooks/audit-log/handler.ts
const handler = async (event) => {
  if (event.type !== "command") return;
  await appendFile("logs/audit.jsonl", JSON.stringify({
    timestamp: event.timestamp.toISOString(),
    action: event.action,
    sessionKey: event.sessionKey,
  }) + "\n");
};

Session backup khi /new:

// hooks/session-backup/handler.ts
const handler = async (event) => {
  if (event.action !== "new") return;
  // Framework bundled hook handles this — just enable it:
  // openclaw hooks enable session-memory
};

Phase 5: Operations (ongoing)

Health monitoring

# Quick check
openclaw status --all
 
# Deep probe (gateway + channels)
openclaw status --deep
 
# Secret audit
openclaw secrets audit --check
 
# Doctor (auto-repair)
openclaw doctor --fix

Cost optimization

LeverImpact
contextTokens: 40000 (thay vì 200K)-80% per-message cost
historyLimit: 20 cho groups-70% context size
Haiku cho family ($0.25/MTok vs $3/MTok)-92% per instance
lightContext: true cho cron-60% per cron run
requireMention: true cho groups-50% total API calls

Trước: ~$700/tháng Sau: ~$90/tháng Tiết kiệm: ~87%

Workspace backup

Workspace = memory of the agent. Backup = non-negotiable.

cd ~/.openclaw/workspace-dso
git init
git add AGENTS.md SOUL.md TOOLS.md IDENTITY.md memory/
git commit -m "backup $(date +%Y-%m-%d)"
git push origin main  # private repo

Topology cuối cùng

VPS (Docker host, 4GB RAM)
│
├── openclaw-dso (:18789)
│   ├── Agent: dso (Sonnet)
│   ├── Telegram: @dso_bot
│   │   ├── DM: allowlist (owner only)
│   │   └── Group: forum supergroup
│   │       ├── General (mention required)
│   │       ├── HITL (auto-respond)
│   │       └── Reports (cron delivery)
│   ├── Heartbeat: 30m → Reports topic
│   ├── Cron: HITL 9AM, Weekly Fri 6PM, Reflect 3AM
│   └── Hooks: audit-log, session-memory
│
├── openclaw-family (:18791)
│   ├── Agent: family (Haiku)
│   ├── Telegram: @family_bot
│   │   ├── DM: allowlist (owner)
│   │   └── Group: family chat (mention required)
│   ├── Heartbeat: disabled
│   └── Cron: none
│
└── openclaw-personal (:18793)
    ├── Agent: claire (Sonnet)
    ├── Telegram: @claire_bot
    │   └── DM only (no groups)
    ├── Heartbeat: 30m → DM
    ├── Cron: daily summary, memory reflect
    └── Hooks: audit-log, session-memory

3 instances, 3 trust boundaries, 3 models, 1 VPS. Total RAM: ~600MB. Total cost: ~$90/tháng.


Bài học tổng hợp

1. Start personal, scale intentional

Đừng over-engineer ngày 1. Bot cá nhân → validate value → scale when demand arrives. Nhưng khi scale, làm đúng: tách trust boundary, hardening, monitoring.

2. Tách instances > hardening 1 instance

200MB RAM per container rẻ hơn nhiều so với phải nhớ 20 config keys cho multi-tenant hardening. Simplicity wins.

3. Forum topics = natural workspace boundaries

Telegram forum topics + per-topic routing = mỗi topic là 1 use case riêng với session riêng. Không cần build UI — Telegram đã là UI.

4. Automation stack = force multiplier

Heartbeat + Cron + Hooks = bot chủ động, có schedule, có audit trail. Không cần viết code — chỉ config.

5. Cost optimization là iterative

Bạn sẽ không tìm ra config tối ưu ngày 1. Monitor → identify waste → tune → repeat. 3 dòng config đầu tiên tiết kiệm 87%. Các optimizations sau đó tiết kiệm thêm 10-20%.


Playbook tóm tắt (cho ai muốn làm tương tự)

WeekAction
1Deploy personal bot. DM only. Validate value.
2Tune costs: contextTokens, historyLimit, model selection.
3Tách instances: 1 per trust boundary. Docker compose.
4Telegram forum topics: per-topic routing.
5Automation: heartbeat + cron. Hooks for audit.
6+Monitor, iterate, optimize.

Không có shortcut. Mỗi tuần 1 bước. Mỗi bước có bài học.


Pillar: 1. Content type: case-study. Engine: ACE-LDK-claire-personal-branding-engine.

LDK

Le Duy Khuong

AI Transformation & Digital Strategy. Writing about agentic systems, engineering leadership, and building in public.