March 2026 • Rich Robertson

How I Built the AskRich Chatbot for Technical Screening

AskRich is a recruiter-focused chatbot that lets hiring teams ask targeted questions about architecture, delivery outcomes, and leadership scope — with citation-backed answers instead of generic claims.

Why I Built AskRich

Most recruiting conversations start with the same challenge: people want signal quickly. A resume gives breadth, but not always the system details behind impact statements. AskRich was built to shorten that gap.

The goal was simple: give recruiters and hiring managers a way to ask specific technical questions and get direct answers grounded in source material from my portfolio and writing.

What the Experience Is Optimized For

The AskRich page uses prompt starters tuned for realistic recruiter workflows, including project impact, architecture trade-offs, and staff-level ownership examples.

Implementation Notes

The chat UI is intentionally lightweight and dependency-free: plain JavaScript, semantic HTML, and a minimal state model for busy handling, validation, and message rendering.

The client posts questions to a dedicated /api/chat endpoint and expects a structured response containing an answer plus citation metadata. When citations include source URLs, links are sanitized before rendering and opened safely in a new tab.

I built both an embedded page experience and a standalone widget script. The widget mounts a floating launcher, opens a keyboard-accessible dialog, traps focus while open, and restores focus on close for accessibility.

Since the first release, the API layer has shifted from a simple retrieval pipeline to a LangGraph-orchestrated chat workflow with explicit retrieval, filtering, evidence bounding, generation, post-processing, and citation construction nodes. On the edge side, the Cloudflare Worker now supports three runtime modes: upstream (proxy to retrieval API), local (serve from built-in corpus), and openai (direct model path with retrieval-aware constraints).

The Worker also includes response caching for repeated prompt shapes, bounded cache TTL controls, and follow-up resolution logic that normalizes short confirmations (like yes/ok) against recent chat history. That keeps common recruiter flows fast while reducing unnecessary repeated inference work.

High-Level Architecture

At a high level, AskRich is a thin web client over a retrieval-backed chat API. The browser handles input, rendering, and citation display. The API layer handles retrieval, answer synthesis, and structured citation output.

flowchart TD U[Recruiter / Hiring Manager Browser] -->|"HTTPS POST /api/chat
{question, top_k}"| G[AskRich API Gateway] G --> K{Cache hit?} K -->|yes| A[Answer text] K -->|no| M{Worker mode} M -->|upstream| O[LangGraph Orchestrator] M -->|local| W[Worker Local Corpus Path] M -->|openai| X[Direct OpenAI Path] O -->|retrieve relevant context| I[Content Index] O -->|compose grounded response| L[LLM Response Layer] I --> C[Citations + supporting chunks] L --> A[Answer text] W --> A X --> A C --> R[Web UI Message Renderer] A --> R R --> V[Visible answer + source links]

This split keeps the front end lightweight while allowing retrieval quality, ranking strategy, and response composition to evolve independently in the API stack.

Why Citations Matter

The key product decision is citation-backed output. Recruiters can inspect supporting references instead of taking a generated answer at face value. That keeps the tool useful as a screening aid rather than a black-box demo.

It also encourages better questions. Once someone sees where answers come from, they tend to ask more precise follow-ups around architecture constraints, rollout sequencing, and measurable outcomes.

What Is Implemented Today

The system now runs with production-style controls: rate limiting at the edge, structured question and answer event recording, and thumbs-up/thumbs-down feedback capture with explicit privacy and review workflows. That shifted iteration from anecdotal edits to observable answer-quality improvements.

Rate limiting is enforced before chat execution in the Worker on POST /api/chat. Client identity is derived from a one-way hash of request context (cf-connecting-ip/x-forwarded-for/x-real-ip + origin + user-agent), so raw IP values are not used as persistent identifiers.

The current policy combines two guards: an hourly quota (RATE_LIMIT_QPS_HOUR, default 30) and a burst interval (RATE_LIMIT_BURST_SECONDS, default 1). If a request exceeds either guard, the API returns 429 with Retry-After and a stable event ID for traceability.

The limiter uses KV-backed sliding-window state and computes reset time from the oldest in-window request. If KV is unavailable, the implementation degrades gracefully (fail-open) to preserve availability while still keeping normal enforcement active when storage is healthy.

There is also a working analytics and corpus-improvement loop in place: event schema documentation, triage playbooks, lightweight content versioning, and A/B testing patterns for retrieval and prompt changes. In practice, prompt and retrieval updates can be evaluated with explicit hypotheses instead of one-off edits.

Rate Limiting Decision Flow

flowchart TD S[Incoming POST /api/chat] --> F{RATE_LIMIT_ENABLED} F -->|false| P[Process request] F -->|true| K[Load ratelimit state from KV] K --> E{KV read ok?} E -->|no| P E -->|yes| H{Hourly limit exceeded?} H -->|yes| D[Return 429 + Retry-After] H -->|no| B{Burst interval violated?} B -->|yes| D B -->|no| W[Write updated window to KV] W --> P

Request Lifecycle

sequenceDiagram participant H as Hiring Manager participant UI as AskRich Web UI participant W as API Worker participant R as Retrieval Runtime participant C as Corpus/Index H ->> UI: Ask technical question UI ->> W: POST /api/chat W ->> W: Check cached response key alt Cache miss W ->> R: Route request (upstream mode) R ->> C: Retrieve top evidence C -->> R: Ranked context + metadata R -->> W: Answer + citations else Cache hit W -->> W: Return cached answer + citations end W -->> UI: Structured response envelope UI -->> H: Render answer with source links

Quality and Feedback Loop

flowchart LR Q[Recruiter Questions] --> A[Answers + Citations] A --> F[Thumbs Up or Down] F --> E[Event Store] E --> T[Feedback Triage] T --> U[Prompt or Retrieval Updates] U --> V[Variant Evaluation] V --> Q

The feedback loop is event-linked end to end. Each question and answer is assigned stable event IDs, and feedback is attached to that interaction pair. That makes it possible to inspect a specific low-rated answer with its exact question text, citation count, latency, and backend mode instead of debugging in the abstract.

Practically, the loop captures three signal types: question events, answer events, and feedback events. Answer events include response latency and citation counts, which lets triage separate retrieval problems (weak or missing evidence), generation problems (response quality), UX/prompting problems (question ambiguity), and mode-specific behavior differences.

Triage then classifies low-satisfaction interactions into concrete action buckets: corpus gap, retrieval/ranking issue, prompt/format issue, or out-of-scope question pattern. Changes are tested, compared, and only promoted when they improve answer quality without regressing citation clarity.

Feedback Triage Flow

flowchart TD S[Unhelpful Feedback Event] --> L[Load linked question and answer events] L --> C{Primary issue type} C -->|Missing evidence| G[Corpus update] C -->|Weak ranking| R[Retrieval or ranking tuning] C -->|Answer clarity| P[Prompt or response format adjustment] C -->|Out of scope| O[Intent routing or guardrail update] G --> T[Test and compare] R --> T P --> T O --> T T --> D{Improvement holds?} D -->|yes| M[Promote change] D -->|no| B[Rollback or rework]

What I’d Improve Next

Related Reading: Interview Signal in the AI Era

AskRich is about improving recruiter and hiring-manager signal quality. If you want the candidate-side and interviewer-side view of how technical signal changes when AI is allowed in coding interviews, start with Coding With AI in Interviews: Why the Bar Is Higher, Not Lower, continue to What Experienced Engineers Are Actually Being Measured on in AI-Assisted Coding Interviews, and use the series hub Coding Interviews in the AI Era for the full reading path.

Try It

You can use AskRich directly at Ask Rich to explore architecture decisions, migration strategy, and platform outcomes.