5.4 KiB
Roadmap
Not a generic TODO list — this captures the intended architecture progression and why each phase is sequenced that way.
Phase 1 — Telegram AI Foundation ✅ (current)
TypeScript + grammY, Docker dev mode with hot reload, webhook + long-polling,
/start /help, normalized message contract, LLM via LiteLLM, conversation
persistence in Postgres, one controlled n8n path, tests + docs.
Why this order: prove the transport (Telegram webhook) and the AI loop end-to-end before investing in durable context, RAG, or a second channel.
Phase 2 — Durable Context + Business Tools
Progress (2026-08-30):
- ✅ Product catalog awareness —
CatalogRetriever(src/ai/retrieval/catalog.ts) replacesNoopRetriever: SKU-token + name/category keyword lookup over the generatedsrc/data/catalog.ts(259 entries, built bygen_catalog.pyfromcatalog_sku.csv; no prices, no storage paths). Hits are injected into the prompt as "Product facts" with product-page links (https://www.digikedai.com/products/<sku>/); free items (SKU prefix FREE — FREECXM04 = FREE + original paid SKU CXM04, the trial twin) are flagged and routed to/free/. Keyword search chosen over pgvector at this scale (eval criteria below). - ✅ Passive human-handoff in
system.ts— admin contact (Telegram @MrFullStackDev only, no WhatsApp/phone) is offered only when the customer asks for a human or the bot cannot solve the issue; repeat questions are re-answered with one ask-line (deterministicisRepeatQueryon top of memory last_queries); URLs must stand alone on their own line; reply language mirrors the customer (language_code mapped to friendly names). - ✅ Purchase flow: multi-way state machine + inline buttons (第1–3批, 2026-08-31)
— deterministic
pendingPurchasestate machine (mirrors the free-trialpendingTrialspattern) replaces the single admin deep link. Purchase intent is intercepted inmessage:textviaPURCHASE_INTENT_RE(zh/en/ms, SKU-aware; FREE-prefixed trial SKUs are never intercepted) → a two-row inline keyboard: ① 网店下单 (online store / marketplace — neutral words, preferred, row on top) → neutral guidance + 联系 admin / 返回 buttons; ② 找 admin 购买 → admin deep link issued DIRECTLY (fallback, fast). 「返回」re-shows the menu; every callback branch ends withanswerCallbackQuery()(Telegram retry idempotency). Deep-link prefill is a free-text sentence in the customer's language built bybuildAdminPurchaseLink({sku?, paymentPreference?, username?, lang?})— whatever was collected (SKU / payment preference / labelled username), nothing forced; no SKU → generic product message. The URL isencodeURIComponent'd exactly ONCE in code; the prompt carries two static pre-encoded samples (with/without username) and the model only swaps alphanumeric SKU/username — this killed the double-nesting bug (第1批 f27bbb4). 中性词纪律: no Shopee/Lazada/Add-On/TnG/bank-in anywhere in bot copy until the marketplace is live (test-asserted). Full plan:docs/PURCHASE_FLOW_REDESIGN.md. - ✅ Free-trial flow button-ified (第3批, 2026-08-31) —
startSku/confirmReusereplies now carry inline buttons (✅ 确认并开通 / ✏️ 提供新 username / ♻️ 加到现有账号) dispatched into thependingTrialsstate machine; the legacy text path (同意 / 新账号 xxx / 用户名:…) still works unchanged.
Remaining items:
- Enrich user profile & conversation memory (
src/ai/memory). - Explicit tool schemas (product lookup, order lookup, status, free-account) with validation before n8n execution.
- Admin/user authorization + rate limiting; allowlist enforced in production.
- Logging, correlation IDs, observability.
- Formalize Channel/Core contracts so Shopee/Lazada adapters drop in without touching the AI core.
Why now: only once Phase 1 shows what the customers actually ask.
Phase 3 — RAG + Multi-Channel
- Enable
pgvectorin the existingpgvector/pgvector:pg17Postgres (already provisioned) when keyword lookup becomes insufficient. - Ingestion pipeline for docs/FAQs/products/policies.
- Retrieval evaluation + source attribution/citation.
- Shopee adapter (merchant/chat API), then Lazada adapter.
- Channel-specific personas/prompts while keeping shared product/customer context.
- Consider a separate vector DB only if pgvector becomes a real bottleneck.
Why pgvector before Qdrant: vectors live alongside ordinary Postgres data; exact + ANN search; keeps the architecture smaller until scale demands separation.
Criteria for adding new infrastructure
Before introducing any new service, explain operational cost and confirm the existing stack (Postgres, n8n, Traefik, LiteLLM) can't already meet the need. Non-goals to protect: no Qdrant/vector DB without a concrete requirement, no multi-agent swarm, no model fine-tuning, no Dify unless it earns its place.
Risks / open items
- LiteLLM shared key: bot currently uses the mem0 LiteLLM master key. Phase 2 should mint a dedicated virtual key (rate-limit + revoke isolation). See
docs/DECISIONS.md. - Webhook auth:
TELEGRAM_WEBHOOK_SECRETguards the URL path; keep it strong in production. - Free-account workflow: the exact n8n workflow path/schema is still a placeholder — confirm with the actual workflow before wiring it to the LLM as a tool.