← Back to Home
💼

AI Technical Sales Co-Pilot

Describe a prospect's tech stack in plain English — get back a structured Cloudflare migration plan, component mapping, cost comparison, and 3-phase migration path. Grounded in a 80-chunk RAG knowledge base of real product documentation.

View Live App ↗ Live
Workers Workers AI Vectorize KV D1 Hono

The Problem

Before a customer call, a Solutions Engineer needs to know: which Cloudflare products map to what the prospect is currently using, what the migration complexity looks like, and how to frame the cost comparison. That research takes 30-60 minutes manually — and the quality varies by how well the SE knows each product area.

The alternative is a hallucinating chatbot that confidently makes up product names and pricing. That's worse than doing it manually.

What I Built

Two agents with a keyword-based orchestrator that routes requests without an LLM call:

Research Agent — given a company name, it searches the web (DuckDuckGo), scrapes their homepage for tech stack signals, fetches recent news (NewsAPI), and synthesizes a structured company profile with Cloudflare opportunities. Takes 10-15 seconds. Replaces 30-60 minutes of manual pre-call research.

Architecture Agent — given a tech stack description ("They use AWS Lambda, CloudFront, S3, and Auth0"), it extracts every component via keyword map (no LLM needed for extraction), queries a 80-chunk Vectorize knowledge base for each component in parallel, maps each to its Cloudflare equivalent with migration complexity, generates a 3-phase migration plan, and estimates cost savings. Takes 25-40 seconds for 3-5 components.

The knowledge base has 80 hand-written chunks covering 20 Cloudflare products — 4 chunk types per product: overview, competitor comparison, pricing tiers, and use cases. Grounding the architecture agent in this KB means it never invents product names or pricing figures.

Architecture

POST /api/v1/copilot
        │
        ▼
    ORCHESTRATOR
    ├─ Keyword classifier (regex, 0ms) ─→ skips LLM for obvious patterns
    ├─ LLM fallback (Workers AI, 5-10s) ─→ for ambiguous messages
    ├─ Route to agent
    ├─ KV: store session history (fire-and-forget)
    └─ D1: write audit log (fire-and-forget)
        │
        ├──────────────────┬──────────────────┐
        ▼                  ▼
  Research Agent    Architecture Agent
  ├─ Web search     ├─ Keyword extraction (regex map)
  ├─ Web scraper    ├─ Vectorize RAG (parallel queries)
  └─ News API       └─ 3-phase migration plan
Technical Deep Dive

Orchestrator design: keyword-first, LLM-fallback

Most requests contain obvious patterns ("Research Stripe", "They use Lambda"). A regex keyword classifier handles these in 0ms — no LLM call. Only genuinely ambiguous messages trigger a Workers AI classification call (~5-10s). This optimization cuts response time by 5-10s for 80%+ of requests. The architecture agent also extracts tech stack components via keyword map rather than LLM — same idea applied to component extraction.

Parallel Vectorize queries

For a 5-component tech stack, the architecture agent fires 5 Vectorize queries simultaneously with Promise.all. Each query returns the top-2 relevant chunks for that component. Results are deduplicated and capped at 10 total chunks to keep the prompt under ~4,000 tokens. Total Vectorize query time: ~1-3s regardless of component count.

Knowledge base construction

80 chunks covering 20 Cloudflare products, each with 4 chunk types: overview (what it is, key features), comparison (vs specific named competitors), pricing (exact tiers with real dollar amounts), and use-case (startup and enterprise scenarios). Hand-written rather than scraped — scraped docs produce inconsistent chunks that embed poorly. Each chunk is ~250-400 words, sized for the BGE-base-en-v1.5 embedding model's optimal input length.

Session memory with KV

Conversation history is stored per session ID in KV. Each session key stores a JSON array of turns. KV reads are sub-10ms globally, and history is injected into the prompt on every request for continuity across multiple questions in the same research session.

Live Endpoints

GET /health Health check — returns version and active agents POST /api/v1/copilot Main endpoint — send a message, get agent output GET /session/:id Retrieve conversation history for a session
# Research a company
curl -X POST https://ai-sales-copilot.stephenmack96.workers.dev/api/v1/copilot \
  -H "Content-Type: application/json" \
  -d '{"session_id":"demo-001","message":"Research Stripe"}'

# Design an architecture
curl -X POST https://ai-sales-copilot.stephenmack96.workers.dev/api/v1/copilot \
  -H "Content-Type: application/json" \
  -d '{"session_id":"demo-002","message":"They use Lambda, CloudFront, S3, and Auth0"}'

Cloudflare Products Used

Workers — Hono router, orchestrator, agent dispatch, web scraping, news API integration. All compute at the edge with zero cold starts.

Workers AI — Llama 3 8B for chat generation, BGE-base-en-v1.5 for embedding 80 product chunks. LLM fallback for intent classification when keyword matching is insufficient.

Vectorize — 80 vectors, cosine similarity. Parallel queries per component, results merged by score and capped at 10 chunks for prompt injection.

KV — Session history storage. One key per session ID, JSON array of conversation turns. Sub-10ms reads globally.

D1 — Audit log: every agent run logged with latency, session ID, and model used.

Performance

Query Components Latency
Single component lookup 1 ~24s
Vercel + Supabase + Auth0 3 ~36s
Lambda + CloudFront + S3 + RDS + VPN 5 ~42s

Latency is dominated by Workers AI (Llama 3 8B) generation time. Routing, embedding, and Vectorize queries account for under 3s total. Streaming (not implemented in this version) would reduce perceived latency significantly.

What I Learned

Career Relevance