Back to Portfolio
Capability CaseBuilding

AI Business Agent Console: a support agent that cites, asks, and waits

An AI support assistant added to an existing business system: answers from policy documents with citations, looks up orders through MCP tools, drafts replies — and never changes data without human approval.

Capability case built on synthetic data — not paid client work.

Role
Solo — product, design, architecture, full-stack and AI engineering, testing
Stack
Next.js 16TypeScriptMCP TypeScript SDKDeepSeekAlibaba Qwen embeddingsOpenAI / Gemini adaptersPostgreSQL + pgvectorDrizzleZodVitestDocker

Overview

  • Challenge: a store's support team wants AI to look things up and draft replies, but is afraid it will invent policy or take actions on its own.
  • Solution: an agent that answers only from cited policy, calls business tools through an MCP server, drafts replies, and pauses before any write until a different person approves the exact action.
  • Results: a real end-to-end run with DeepSeek and Qwen embeddings, from question to approved ticket; 98 automated tests and 12 deterministic evaluation cases passing.

Support workbenchSupport workbench

The challenge

The scenario is a fictional home-goods online store. The numbers are typical for a store this size and are assumptions, not client data.

  • Team: 12 people, 3 in customer support, around 300 tickets a day — most about refunds, shipping and memberships.
  • Today: agents switch between policy documents (which change often) and the order system. New hires quote outdated policy.
  • What the owner asked for: "I want AI to gather the facts and draft the reply, but it must never refund on its own or make up policy."

That turns into five acceptance criteria:

  1. Every conclusion links to the policy text and version it relied on.
  2. If the policy doesn't cover it, the answer is "insufficient evidence — hand to a human", never a guess.
  3. Refunds, tickets and other data changes need approval from a different person.
  4. Every run shows what it cost and how long it took.
  5. The model vendor can be swapped for price or compliance reasons.

What I built

A case-first workbench, not a chat box. The queue, the case under investigation, the approval card with its exact arguments, the step trace and provider readiness all sit on one screen.

Workbench: from wireframe to final UIWorkbench: from wireframe to final UI

A bounded agent. It runs as a state machine, not an open loop: classify → retrieve policy → look up customer, order and subscription → analyze → draft → risk check → wait for approval or execute. Hard limits: 8 steps, 5 model calls, 6 tool calls, 60-second timeout, no automatic retry of writes.

Tools behind a real MCP boundary.

ToolRiskApproval
Look up customer / order / subscription, search policyLowNo
Draft customer emailMediumNo — drafts only, never sends
Create support ticketHighAlways

Technical highlights

Agent Console architectureAgent Console architecture

What a client worries aboutHow the console handles it
HallucinationCitation IDs are assigned before generation; the model can only cite retrieved text; low evidence returns "insufficient evidence"
Unwanted actionsTools are risk-tiered; writes need a signed, one-time approval bound to the exact arguments
Permissions and data isolationWorkspace identity is injected by the system — the model can never pass it — and roles are checked before every tool call
Prompt injectionRetrieved documents are treated as untrusted; instruction-like text is flagged and can't expand tool access
PrivacyLogs redact emails, phone numbers, tokens and API keys
Runaway costStep, call and time budgets; tokens and cost recorded per run
Vendor lock-inSeparate generation and embedding contracts; DeepSeek, Qwen, OpenAI and Gemini adapters

Two defects only showed up against real providers — strict MCP output validation rejected internal metadata, and DeepSeek's thinking mode could use up the token budget without an answer. Both were fixed, which is why the live run mattered.

Quality & testing

LayerResult
Automated tests98 passing — tool schemas, approval replay and self-approval, risk policy, chunking, retrieval, redaction, provider adapters
Evaluations12 deterministic cases: retrieval, citation validity, tool choice, argument accuracy, approval, role denial, tenant isolation, injection
MCP protocolReal Streamable HTTP path verified: web → MCP → approval → MCP → TICKET-0001
Live providersDeepSeek generation + Alibaba qwen3.7-text-embedding (1024-d) end to end; missing keys report not_run, never a made-up score

Results & limits

Original specShipped in V1
PDF, DOCX, Markdown, TXT up to 10 MBUTF-8 .txt and .md up to 2 MB
Hybrid full-text + vector retrievalVector retrieval; pgvector schema ready for production
Four roles with row-level securityFixed operator / approver identities in the demo
Live comparison of all providersDeepSeek + Qwen verified live; OpenAI and Gemini built against the same contract

The public demo runs on a deterministic demo provider so clicking costs nothing; the live-model run is shown in the video.

How I delivered it

StepWhat was produced
RequirementsOne concrete support question, roles, tool risk table, acceptance criteria
PrototypePage flow and wireframes for the workbench and the run / approval view
UICase-first layout, evidence next to every conclusion, approval beside its arguments
ArchitectureWeb app + independent MCP server, pluggable providers, pgvector
BuildSpec-first with AI coding agents; verified against real providers
TestingUnit tests, deterministic evaluations, MCP protocol and live-provider runs
LaunchTwo Docker services on Render (in progress)

Planning something similar?

Write down the context, core features, budget and timeline. It takes a few minutes and gives us a concrete starting point.

Start a Project Brief