All articles
ArticleMarch 19, 2026

Shipping a Production-Ready Brain+Hands Support Agent (WordPress + Python API)

Shipping a Production-Ready Brain+Hands Support Agent (WordPress + Python API)

This build delivers a support/billing agent you can actually ship. It follows Brain+Hands separation, explicit tool contracts, a deterministic state machine, and secure backend tools. Stack: WordPress (frontend), Python FastAPI (tools + orchestrator), Redis (state/cache), Postgres (KB + logs), vector DB (memory), OpenAI/Groq/Anthropic (LLM).

1) Architecture overview
– Brain (LLM policy): Plans, chooses tools, reasons. No direct DB/API access.
– Hands (tools): Idempotent HTTP endpoints with strict schemas. Observable, rate-limited, auditable.
– Orchestrator: State machine controlling turns, tool calls, retries, and timeouts.
– Memory:
– Short-term: per-session scratchpad (Redis).
– Knowledge: vector search over product docs/FAQ.
– Facts: authoritative store lookups (billing, orders).
– Guardrails: auth, PII redaction, tool allowlist, cost/time budgets, circuit breakers.
– Integration: WordPress plugin sends chat events to orchestrator; streaming tokens back to UI.

2) Contracts first (make tools boring and safe)
Define JSON schemas for every tool. Keep them narrow, idempotent, and testable.

Example tool manifest (slice):
{
“name”: “get_order_status”,
“description”: “Return current order state for a given order_id.”,
“method”: “POST”,
“url”: “https://api.example.com/tools/get_order_status”,
“input_schema”: {
“type”: “object”,
“properties”: {
“order_id”: {“type”: “string”, “pattern”: “^[A-Z0-9-]{6,}$”}
},
“required”: [“order_id”],
“additionalProperties”: false
},
“output_schema”: {
“type”: “object”,
“properties”: {
“status”: {“type”: “string”},
“updated_at”: {“type”: “string”, “format”: “date-time”}
},
“required”: [“status”]
},
“timeouts_ms”: 2500,
“retries”: 1
}

3) Hands: secure Python FastAPI tools
– Enforce schema at the edge.
– Require JWT with narrow scopes.
– Add rate limits and audit logs.

from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel, Field
import time

app = FastAPI(title=”SupportAgentTools”)

class OrderReq(BaseModel):
order_id: str = Field(min_length=6, pattern=r”^[A-Z0-9-]{6,}$”)

class OrderResp(BaseModel):
status: str
updated_at: str | None = None

def auth(scope: str):
def _auth(token=Depends(…)): # your JWT dependency
if scope not in token.scopes:
raise HTTPException(403, “forbidden”)
return token.sub
return _auth

@app.post(“/tools/get_order_status”, response_model=OrderResp)
def get_order_status(req: OrderReq, _=Depends(auth(“order:read”))):
start = time.time()
# query read replica; maintain SLO use respective tools.
– General product usage -> retrieve_docs.
– Anything else -> answer concisely or ask a clarifying question.

6) Orchestrator: a small, reliable state machine
States:
– RECEIVE -> PLAN -> EXECUTE_TOOL? -> OBSERVE -> RESPOND -> END

Pseudo:
def handle_turn(msg, session_id):
budget = Budget(tokens=3000, tools=3, wall_ms=8000)
state = “PLAN”
memory = load_session(session_id)
while budget.ok() and state != “END”:
if state == “PLAN”:
action = llm_policy(memory, tool_manifest)
if action.type == “tool”:
state = “EXECUTE_TOOL”
else:
state = “RESPOND”
elif state == “EXECUTE_TOOL”:
result = call_tool(action.name, action.args, timeout=manifest[action.name].timeouts_ms)
record_observation(result)
state = “OBSERVE”
elif state == “OBSERVE”:
memory.update_with_observation(result)
if need_more_tools(result): state = “PLAN”
else: state = “RESPOND”
elif state == “RESPOND”:
reply = llm_response(memory)
emit_stream(reply)
state = “END”

Controls:
– Max 2 tool calls/turn for latency.
– Tool circuit breaker after 2x p95 failures.
– Token + time budgets enforced per turn.

7) Retrieval that doesn’t hallucinate
– Chunk docs to 300–500 tokens with overlap 50–100.
– Store title, URL, product tags, and last_updated.
– Rerank top 20 -> 5 with a fast cross-encoder or LLM-judge at small context.
– In answers, include “According to ()” and quote minimal lines.<br /> – Evict stale docs with last_updated TTL checks.</p> <p>8) Error handling and fallbacks<br /> – Tool error classes: 4xx user-fixable (show guidance), 5xx transient (retry with jitter), timeout (offer manual escalation).<br /> – If tools unavailable, switch to knowledge-only mode and surface a status note to the user.<br /> – Log: request_id, user_hash, tool_calls, latencies, token_usage, model, success_flag.</p> <p>9) WordPress integration (plugin sketch)<br /> – Shortcode [aiguy_chat] renders chat UI.<br /> – Frontend calls /wp-json/aiguy/v1/chat (nonce protected).<br /> – Server proxy signs JWT to orchestrator and streams chunks back.</p> <p>PHP (very abbreviated):<br /> add_action(‘rest_api_init’, function () {<br /> register_rest_route(‘aiguy/v1’, ‘/chat’, [‘methods’=>’POST’,’callback’=>’aiguy_chat’,’permission_callback’=>’__return_true’]);<br /> });<br /> function aiguy_chat(WP_REST_Request $r) {<br /> $jwt = make_scoped_jwt([‘aud’=>’orchestrator’,’scopes’=>[‘chat:send’]]);<br /> $resp = wp_remote_post(‘https://agent.example.com/chat’, [<br /> ‘headers’=>[‘Authorization’=>”Bearer $jwt”],<br /> ‘body’=>[‘session_id’=>get_session_id(), ‘message’=>$r->get_param(‘message’)],<br /> ‘timeout’=>15<br /> ]);<br /> return rest_ensure_response(wp_remote_retrieve_body($resp));<br /> }</p> <p>10) Models and performance<br /> – Use fast model for planning (e.g., gpt-4o-mini, llama-3.1-70b-instruct via Groq) and a stronger model for final generation when needed.<br /> – Target p95 < 2.5s single-turn with 0–1 tool; < 4.5s with 2 tools.<br /> – Cache retrieval and deterministic tool schemas to reduce tokens.</p> <p>11) Security checklist<br /> – Tool allowlist + strict JSON schemas.<br /> – JWT with narrow scopes + rotation.<br /> – PII redaction before logs; encrypt sensitive fields at rest.<br /> – Separate read/write tools; require user confirmation for writes.<br /> – Rate limit per IP/user/session; WAF on tool API.</p> <p>12) Observability<br /> – OpenTelemetry spans: plan, tool call, observe, generate.<br /> – Emit metrics: latency p50/p95, tool error rate, deflection rate, CSAT.<br /> – Log all prompts/responses with redaction; enable replay in a sandbox.</p> <p>13) Deployment<br /> – Dockerize orchestrator + tools. Separate autoscaling for tools with spiky I/O.<br /> – Blue/green deploy; health checks include LLM warmup and tool canary.<br /> – Backpressure: queue requests when model or DB under load; shed load gracefully with a user-facing “email me results” fallback.</p> <p>14) Minimal smoke test<br /> – Happy path: “Where is my order ABC123?”<br /> – Tool timeout path: inject 2s delay; verify graceful message.<br /> – Hallucination guard: ask for unavailable feature; ensure denial with doc citation.</p> <p>Deliverables you can ship this week<br /> – Tool API (FastAPI) with 3 tools: get_order_status, get_invoice_pdf, retrieve_docs.<br /> – Orchestrator with state machine, budgets, and streaming.<br /> – WordPress plugin with nonce-protected REST route and basic chat UI.<br /> – Vector index with top 20 support articles and citations in answers.<br /> – Dashboards: latency, tool errors, deflection, cost.</p> </div></div><aside class="mt-16 rounded-2xl border border-ink-200 bg-white p-8 sm:p-10"><p class="eyebrow">Next step</p><h2 class="mt-4 font-serif text-[1.5rem] sm:text-[1.75rem] leading-snug text-ink-900">Want this applied to your own business?</h2><p class="mt-3 text-ink-600 leading-relaxed max-w-xl">Reading about a pattern and knowing which one fits your workflows are two different problems. Pick whichever is faster for you.</p><div class="mt-8 flex flex-col sm:flex-row gap-4"><a class="inline-flex items-center justify-center gap-2 rounded-full bg-ember-600 px-5 py-3 text-sm font-medium text-white hover:bg-ember-700 transition-colors" href="/audit">Book a free 30-minute audit →</a><a class="inline-flex items-center justify-center gap-2 rounded-full border border-ink-300 px-5 py-3 text-sm font-medium text-ink-900 hover:border-ink-900 transition-colors" href="/ai-opportunity-report">Or get the <!-- -->$149<!-- --> written report</a></div><p class="mt-5 text-[0.8125rem] text-ink-500 leading-relaxed">The audit is a live call. The report is written, fixed-scope, and delivered within <!-- -->5<!-- --> business days — no call required.</p></aside><section class="mt-16 pt-10 border-t border-ink-200"><p class="eyebrow">Keep reading</p><ul class="mt-6 grid gap-px bg-ink-200 sm:grid-cols-3 rounded-xl overflow-hidden"><li class="bg-paper"><a class="group flex h-full flex-col p-5 hover:bg-white transition-colors" href="/blog/shipping-a-production-ready-support-agent-brain-hands-with-wordpress-frontend-and-django-backend"><span class="font-mono text-[11px] tracking-[0.12em] uppercase text-ink-400">March 12, 2026</span><span class="mt-2 font-serif text-[1.0625rem] leading-snug text-ink-900 group-hover:text-signal-800 transition-colors">Shipping a Production-Ready Support Agent (Brain + Hands) with WordPress Frontend and Django Backend</span><span class="mt-2 text-[0.875rem] text-ink-600 leading-relaxed">A complete, deployable pattern for a production chatbot that actually does work: Brain + Hands separation, tool calling,…</span></a></li><li class="bg-paper"><a class="group flex h-full flex-col p-5 hover:bg-white transition-colors" href="/blog/shipping-a-production-ready-wordpress-support-agent-brain-hands-secure-tools-real-logs"><span class="font-mono text-[11px] tracking-[0.12em] uppercase text-ink-400">March 4, 2026</span><span class="mt-2 font-serif text-[1.0625rem] leading-snug text-ink-900 group-hover:text-signal-800 transition-colors">Shipping a Production-Ready WordPress Support Agent (Brain + Hands, Secure Tools, Real Logs)</span><span class="mt-2 text-[0.875rem] text-ink-600 leading-relaxed">A step-by-step build of a maintainable WordPress support agent that can answer product questions, check orders, and crea…</span></a></li><li class="bg-paper"><a class="group flex h-full flex-col p-5 hover:bg-white transition-colors" href="/blog/building-a-production-ready-support-agent-for-wordpress-brain-hands-architecture"><span class="font-mono text-[11px] tracking-[0.12em] uppercase text-ink-400">February 25, 2026</span><span class="mt-2 font-serif text-[1.0625rem] leading-snug text-ink-900 group-hover:text-signal-800 transition-colors">Building a Production-Ready Support Agent for WordPress (Brain + Hands Architecture)</span><span class="mt-2 text-[0.875rem] text-ink-600 leading-relaxed">A practical blueprint for deploying a real support chatbot on WordPress. Includes Brain + Hands design, tool wiring, mem…</span></a></li></ul><div class="mt-8 rounded-xl border border-ink-200 p-5 sm:p-6"><p class="eyebrow text-ember-600">If you run the business</p><a class="group mt-3 block" href="/blog/ai-customer-service-without-violating-privacy"><span class="font-serif text-[1.125rem] leading-snug text-ink-900 group-hover:text-signal-800 transition-colors">How to Use AI for Customer Service Without Violating Privacy Expectations</span><span class="mt-2 block text-[0.9375rem] text-ink-600 leading-relaxed">Customer service is the most tempting place to apply AI and the most dangerous one to do it carelessly. The same convers…</span></a></div></section><div class="mt-16 pt-10 border-t border-ink-200"><div class="mb-10"><div class="flex items-center gap-3"><span class="text-sm text-ink-500 font-medium">Share:</span><a href="https://x.com/intent/tweet?url=https%3A%2F%2Faiguyinla.com%2Fblog%2Fshipping-a-production-ready-brainhands-support-agent-wordpress-python-api&text=Shipping%20a%20Production-Ready%20Brain%2BHands%20Support%20Agent%20(WordPress%20%2B%20Python%20API)" target="_blank" rel="noopener noreferrer" class="flex h-8 w-8 items-center justify-center rounded-full bg-ink-200 text-ink-600 transition-colors hover:bg-ink-900 hover:text-white" aria-label="Share on X (Twitter)"><svg class="h-4 w-4 fill-current" viewBox="0 0 24 24"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"></path></svg></a><a href="https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Faiguyinla.com%2Fblog%2Fshipping-a-production-ready-brainhands-support-agent-wordpress-python-api&title=Shipping%20a%20Production-Ready%20Brain%2BHands%20Support%20Agent%20(WordPress%20%2B%20Python%20API)" target="_blank" rel="noopener noreferrer" class="flex h-8 w-8 items-center justify-center rounded-full bg-ink-200 text-ink-600 transition-colors hover:bg-[#0A66C2] hover:text-white" aria-label="Share on LinkedIn"><svg class="h-4 w-4 fill-current" viewBox="0 0 24 24"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"></path></svg></a><a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Faiguyinla.com%2Fblog%2Fshipping-a-production-ready-brainhands-support-agent-wordpress-python-api" target="_blank" rel="noopener noreferrer" class="flex h-8 w-8 items-center justify-center rounded-full bg-ink-200 text-ink-600 transition-colors hover:bg-[#1877F2] hover:text-white" aria-label="Share on Facebook"><svg class="h-4 w-4 fill-current" viewBox="0 0 24 24"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.469h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.469h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"></path></svg></a></div></div><a class="text-sm text-ink-500 hover:text-ink-900 transition-colors" href="/blog">← More articles</a></div></article></div></main><footer class="bg-paper border-t border-ink-200"><div class="mx-auto max-w-6xl px-6 lg:px-8 py-16 lg:py-20 grid gap-12 lg:grid-cols-12"><div class="lg:col-span-5"><div class="inline-flex items-baseline gap-2 text-ink-900"><span class="font-serif text-2xl leading-none tracking-tight">AI Guy</span><span class="font-sans text-[0.7rem] uppercase tracking-[0.22em] text-ink-500">in LA</span></div><p class="mt-5 text-ink-600 max-w-md leading-relaxed">Practical AI engineering and consulting for real organizations in Los Angeles. Websites, chatbots, workflow automation, and custom software — built with privacy-first guardrails.</p><div class="mt-8 inline-flex items-center gap-3 rounded-full border border-ink-200 px-3 py-1.5 text-xs text-ink-600"><span class="h-1.5 w-1.5 rounded-full bg-ember-500"></span>Based in Los Angeles, California</div><div class="mt-5 flex flex-col gap-2 items-start"><a href="mailto:info@webmasterandmore.com" class="text-sm font-medium text-ink-700 underline underline-offset-4 decoration-1 hover:text-ink-900 hover:decoration-2">info@webmasterandmore.com</a><a href="https://www.facebook.com/aiguyinla" target="_blank" rel="noopener noreferrer" class="text-sm font-medium text-ink-700 underline underline-offset-4 decoration-1 hover:text-ink-900 hover:decoration-2">Follow AI Guy in LA on Facebook</a><a href="https://x.com/AiGuyinLA" target="_blank" rel="noopener noreferrer" class="text-sm font-medium text-ink-700 underline underline-offset-4 decoration-1 hover:text-ink-900 hover:decoration-2">Follow AI Guy in LA on X</a><a href="https://www.linkedin.com/company/ai-guy-in-la/" target="_blank" rel="noopener noreferrer" class="text-sm font-medium text-ink-700 underline underline-offset-4 decoration-1 hover:text-ink-900 hover:decoration-2">Follow AI Guy in LA on LinkedIn</a></div></div><div class="lg:col-span-4 grid grid-cols-2 gap-8"><nav aria-label="Work"><p class="eyebrow mb-4">Work</p><ul class="space-y-2.5 text-[0.95rem] text-ink-700"><li><a class="hover:text-ink-900 transition-colors" href="/#services">Services</a></li><li><a class="hover:text-ink-900 transition-colors" href="/ai-consultant-los-angeles">AI Consultant LA</a></li><li><a class="hover:text-ink-900 transition-colors" href="/case-studies">Case Studies</a></li><li><a class="hover:text-ink-900 transition-colors" href="/ai-roi-calculator">ROI Calculator</a></li><li><a class="hover:text-ink-900 transition-colors" href="/ai-opportunity-report">AI Opportunity Report</a></li><li><a class="hover:text-ink-900 transition-colors" href="/blog">Blog</a></li></ul></nav><nav aria-label="Company"><p class="eyebrow mb-4">Company</p><ul class="space-y-2.5 text-[0.95rem] text-ink-700"><li><a class="hover:text-ink-900 transition-colors" href="/about">About</a></li><li><a class="hover:text-ink-900 transition-colors" href="/#privacy">Privacy guardrails</a></li><li><a class="hover:text-ink-900 transition-colors" href="/audit">Free audit</a></li></ul></nav></div><div class="lg:col-span-3"><p class="eyebrow mb-4">Get a free audit</p><p class="text-[0.95rem] text-ink-600 leading-relaxed">30 minutes. No pitch. Three practical recommendations for your site and workflows.</p><a class="mt-5 inline-flex items-center gap-2 text-sm font-medium text-ink-900 group" href="/audit"><span class="underline underline-offset-4 decoration-1 group-hover:decoration-2">Book your audit</span><span aria-hidden="true" class="transition-transform group-hover:translate-x-0.5">→</span></a><p class="mt-5 text-[0.85rem] text-ink-500 leading-relaxed">Prefer email?<!-- --> <a href="mailto:info@webmasterandmore.com" class="underline underline-offset-2 hover:text-ink-900">info@webmasterandmore.com</a></p></div></div><div class="border-t border-ink-200"><div class="mx-auto max-w-6xl px-6 lg:px-8 py-6 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 text-xs text-ink-500"><p>© <!-- -->2026<!-- --> AI Guy in LA. Built locally in Los Angeles, CA. Website by<!-- --> <a href="https://webmasterandmore.com/" class="underline underline-offset-2 hover:text-ink-900">Webmaster & More</a>.</p><p class="font-mono tracking-wide uppercase text-[10px] text-ink-400">Privacy-first · Compliance-aware · Human in the loop</p></div></div></footer><button type="button" aria-label="Back to top" tabindex="-1" class="fixed bottom-5 right-5 sm:bottom-8 sm:right-8 z-40 h-11 w-11 sm:h-12 sm:w-12 rounded-full bg-ink-900 text-paper border border-ink-900 shadow-card-lg hover:shadow-card hover:bg-ink-800 hover:-translate-y-0.5 transition-all duration-200 ease-out opacity-0 translate-y-3 pointer-events-none inline-flex items-center justify-center"><svg aria-hidden="true" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 19V5"></path><path d="M5 12l7-7 7 7"></path></svg></button><script src="/_next/static/chunks/webpack-154595e9cefd471e.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/media/4c9affa5bc8f420e-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/_next/static/media/af4bf8399d1aacdf-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n3:HL[\"/_next/static/media/bb3ef058b751a6ad-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n4:HL[\"/_next/static/css/bd16f71b2e0de104.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"5:I[2846,[],\"\"]\n8:I[4707,[],\"\"]\na:I[6423,[],\"\"]\nb:I[9295,[\"972\",\"static/chunks/972-fbe8e47101704ce9.js\",\"185\",\"static/chunks/app/layout-51ab95a8439bdb92.js\"],\"default\"]\nc:I[2972,[\"972\",\"static/chunks/972-fbe8e47101704ce9.js\",\"878\",\"static/chunks/878-f7029bec14cb6a4b.js\",\"703\",\"static/chunks/703-5552f90b7ea731d9.js\",\"308\",\"static/chunks/app/blog/%5Bslug%5D/page-be2023f696e3132b.js\"],\"\"]\nd:I[6640,[\"972\",\"static/chunks/972-fbe8e47101704ce9.js\",\"878\",\"static/chunks/878-f7029bec14cb6a4b.js\",\"703\",\"static/chunks/703-5552f90b7ea731d9.js\",\"308\",\"static/chunks/app/blog/%5Bslug%5D/page-be2023f696e3132b.js\"],\"default\"]\ne:I[9177,[\"972\",\"static/chunks/972-fbe8e47101704ce9.js\",\"185\",\"static/chunks/app/layout-51ab95a8439bdb92.js\"],\"default\"]\nf:I[8003,[\"972\",\"static/chunks/972-fbe8e47101704ce9.js\",\"185\",\"static/chunks/app/layout-51ab95a8439bdb92.js\"],\"\"]\n11:I[1060,[],\"\"]\n9:[\"slug\",\"shipping-a-production-ready-brainhands-support-agent-wordpress-python-api\",\"d\"]\n12:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L5\",null,{\"buildId\":\"yJroNQH7s7mLvZd31UNSv\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"blog\",\"shipping-a-production-ready-brainhands-support-agent-wordpress-python-api\"],\"initialTree\":[\"\",{\"children\":[\"blog\",{\"children\":[[\"slug\",\"shipping-a-production-ready-brainhands-support-agent-wordpress-python-api\",\"d\"],{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"blog\",{\"children\":[[\"slug\",\"shipping-a-production-ready-brainhands-support-agent-wordpress-python-api\",\"d\"],{\"children\":[\"__PAGE__\",{},[[\"$L6\",\"$L7\",null],null],null]},[null,[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"blog\",\"children\",\"$9\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$La\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[null,[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"blog\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$La\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/bd16f71b2e0de104.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"className\":\"__variable_3a6cb3 __variable_d2dc74 __variable_3c557b font-sans bg-paper text-ink-900 antialiased min-h-screen flex flex-col\",\"children\":[[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"LocalBusiness\\\",\\\"name\\\":\\\"AI Guy in LA\\\",\\\"url\\\":\\\"https://aiguyinla.com\\\",\\\"sameAs\\\":[\\\"https://www.facebook.com/aiguyinla\\\",\\\"https://x.com/AiGuyinLA\\\",\\\"https://www.linkedin.com/company/ai-guy-in-la/\\\"],\\\"email\\\":\\\"info@webmasterandmore.com\\\",\\\"contactPoint\\\":{\\\"@type\\\":\\\"ContactPoint\\\",\\\"contactType\\\":\\\"sales\\\",\\\"email\\\":\\\"info@webmasterandmore.com\\\",\\\"areaServed\\\":\\\"US\\\",\\\"availableLanguage\\\":\\\"English\\\"},\\\"description\\\":\\\"AI websites, chatbots, content automation, and custom software development for Los Angeles businesses.\\\",\\\"address\\\":{\\\"@type\\\":\\\"PostalAddress\\\",\\\"addressLocality\\\":\\\"Los Angeles\\\",\\\"addressRegion\\\":\\\"CA\\\",\\\"addressCountry\\\":\\\"US\\\"},\\\"areaServed\\\":{\\\"@type\\\":\\\"City\\\",\\\"name\\\":\\\"Los Angeles\\\"},\\\"knowsAbout\\\":[\\\"AI chatbots\\\",\\\"Workflow automation\\\",\\\"Headless WordPress\\\",\\\"Next.js\\\",\\\"Django\\\",\\\"AI content systems\\\"]}\"}}],[\"$\",\"$Lb\",null,{}],[\"$\",\"main\",null,{\"className\":\"flex-1\",\"children\":[\"$\",\"$L8\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$La\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[\"$\",\"div\",null,{\"className\":\"bg-paper\",\"children\":[\"$\",\"div\",null,{\"className\":\"mx-auto max-w-2xl px-6 lg:px-8 py-32 text-center\",\"children\":[[\"$\",\"p\",null,{\"className\":\"font-mono text-[11px] tracking-[0.18em] uppercase text-ember-600\",\"children\":\"404 · Page not found\"}],[\"$\",\"h1\",null,{\"className\":\"mt-5 font-serif text-[2.5rem] lg:text-[3.5rem] leading-[1.05] tracking-tight text-ink-900 font-medium\",\"children\":\"We could not find that page.\"}],[\"$\",\"p\",null,{\"className\":\"mt-5 text-ink-600 leading-relaxed\",\"children\":\"The link may be broken or the page has moved. Try one of these instead.\"}],[\"$\",\"div\",null,{\"className\":\"mt-9 flex items-center justify-center gap-3\",\"children\":[[\"$\",\"$Lc\",null,{\"href\":\"/\",\"className\":\"inline-flex items-center gap-2 rounded-full bg-ember-600 px-5 py-2.5 text-sm font-medium text-white hover:bg-ember-700 transition-colors\",\"children\":\"Go home →\"}],[\"$\",\"$Lc\",null,{\"href\":\"/blog\",\"className\":\"inline-flex items-center gap-2 rounded-full border border-ink-300 px-5 py-2.5 text-sm font-medium text-ink-900 hover:border-ink-500 hover:bg-paper-100 transition-colors\",\"children\":\"Read the blog\"}]]}]]}]}],\"notFoundStyles\":[]}]}],[\"$\",\"footer\",null,{\"className\":\"bg-paper border-t border-ink-200\",\"children\":[[\"$\",\"div\",null,{\"className\":\"mx-auto max-w-6xl px-6 lg:px-8 py-16 lg:py-20 grid gap-12 lg:grid-cols-12\",\"children\":[[\"$\",\"div\",null,{\"className\":\"lg:col-span-5\",\"children\":[[\"$\",\"div\",null,{\"className\":\"inline-flex items-baseline gap-2 text-ink-900\",\"children\":[[\"$\",\"span\",null,{\"className\":\"font-serif text-2xl leading-none tracking-tight\",\"children\":\"AI Guy\"}],[\"$\",\"span\",null,{\"className\":\"font-sans text-[0.7rem] uppercase tracking-[0.22em] text-ink-500\",\"children\":\"in LA\"}]]}],[\"$\",\"p\",null,{\"className\":\"mt-5 text-ink-600 max-w-md leading-relaxed\",\"children\":\"Practical AI engineering and consulting for real organizations in Los Angeles. Websites, chatbots, workflow automation, and custom software — built with privacy-first guardrails.\"}],[\"$\",\"div\",null,{\"className\":\"mt-8 inline-flex items-center gap-3 rounded-full border border-ink-200 px-3 py-1.5 text-xs text-ink-600\",\"children\":[[\"$\",\"span\",null,{\"className\":\"h-1.5 w-1.5 rounded-full bg-ember-500\"}],\"Based in Los Angeles, California\"]}],[\"$\",\"div\",null,{\"className\":\"mt-5 flex flex-col gap-2 items-start\",\"children\":[[\"$\",\"a\",null,{\"href\":\"mailto:info@webmasterandmore.com\",\"className\":\"text-sm font-medium text-ink-700 underline underline-offset-4 decoration-1 hover:text-ink-900 hover:decoration-2\",\"children\":\"info@webmasterandmore.com\"}],[\"$\",\"a\",null,{\"href\":\"https://www.facebook.com/aiguyinla\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"text-sm font-medium text-ink-700 underline underline-offset-4 decoration-1 hover:text-ink-900 hover:decoration-2\",\"children\":\"Follow AI Guy in LA on Facebook\"}],[\"$\",\"a\",null,{\"href\":\"https://x.com/AiGuyinLA\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"text-sm font-medium text-ink-700 underline underline-offset-4 decoration-1 hover:text-ink-900 hover:decoration-2\",\"children\":\"Follow AI Guy in LA on X\"}],[\"$\",\"a\",null,{\"href\":\"https://www.linkedin.com/company/ai-guy-in-la/\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"text-sm font-medium text-ink-700 underline underline-offset-4 decoration-1 hover:text-ink-900 hover:decoration-2\",\"children\":\"Follow AI Guy in LA on LinkedIn\"}]]}]]}],[\"$\",\"div\",null,{\"className\":\"lg:col-span-4 grid grid-cols-2 gap-8\",\"children\":[[\"$\",\"nav\",\"Work\",{\"aria-label\":\"Work\",\"children\":[[\"$\",\"p\",null,{\"className\":\"eyebrow mb-4\",\"children\":\"Work\"}],[\"$\",\"ul\",null,{\"className\":\"space-y-2.5 text-[0.95rem] text-ink-700\",\"children\":[[\"$\",\"li\",\"/#services\",{\"children\":[\"$\",\"$Lc\",null,{\"href\":\"/#services\",\"className\":\"hover:text-ink-900 transition-colors\",\"children\":\"Services\"}]}],[\"$\",\"li\",\"/ai-consultant-los-angeles\",{\"children\":[\"$\",\"$Lc\",null,{\"href\":\"/ai-consultant-los-angeles\",\"className\":\"hover:text-ink-900 transition-colors\",\"children\":\"AI Consultant LA\"}]}],[\"$\",\"li\",\"/case-studies\",{\"children\":[\"$\",\"$Lc\",null,{\"href\":\"/case-studies\",\"className\":\"hover:text-ink-900 transition-colors\",\"children\":\"Case Studies\"}]}],[\"$\",\"li\",\"/ai-roi-calculator\",{\"children\":[\"$\",\"$Lc\",null,{\"href\":\"/ai-roi-calculator\",\"className\":\"hover:text-ink-900 transition-colors\",\"children\":\"ROI Calculator\"}]}],[\"$\",\"li\",\"/ai-opportunity-report\",{\"children\":[\"$\",\"$Lc\",null,{\"href\":\"/ai-opportunity-report\",\"className\":\"hover:text-ink-900 transition-colors\",\"children\":\"AI Opportunity Report\"}]}],[\"$\",\"li\",\"/blog\",{\"children\":[\"$\",\"$Lc\",null,{\"href\":\"/blog\",\"className\":\"hover:text-ink-900 transition-colors\",\"children\":\"Blog\"}]}]]}]]}],[\"$\",\"nav\",\"Company\",{\"aria-label\":\"Company\",\"children\":[[\"$\",\"p\",null,{\"className\":\"eyebrow mb-4\",\"children\":\"Company\"}],[\"$\",\"ul\",null,{\"className\":\"space-y-2.5 text-[0.95rem] text-ink-700\",\"children\":[[\"$\",\"li\",\"/about\",{\"children\":[\"$\",\"$Lc\",null,{\"href\":\"/about\",\"className\":\"hover:text-ink-900 transition-colors\",\"children\":\"About\"}]}],[\"$\",\"li\",\"/#privacy\",{\"children\":[\"$\",\"$Lc\",null,{\"href\":\"/#privacy\",\"className\":\"hover:text-ink-900 transition-colors\",\"children\":\"Privacy guardrails\"}]}],[\"$\",\"li\",\"/audit\",{\"children\":[\"$\",\"$Lc\",null,{\"href\":\"/audit\",\"className\":\"hover:text-ink-900 transition-colors\",\"children\":\"Free audit\"}]}]]}]]}]]}],[\"$\",\"div\",null,{\"className\":\"lg:col-span-3\",\"children\":[[\"$\",\"p\",null,{\"className\":\"eyebrow mb-4\",\"children\":\"Get a free audit\"}],[\"$\",\"p\",null,{\"className\":\"text-[0.95rem] text-ink-600 leading-relaxed\",\"children\":\"30 minutes. No pitch. Three practical recommendations for your site and workflows.\"}],[\"$\",\"$Ld\",null,{\"href\":\"/audit\",\"location\":\"footer\",\"className\":\"mt-5 inline-flex items-center gap-2 text-sm font-medium text-ink-900 group\",\"children\":[[\"$\",\"span\",null,{\"className\":\"underline underline-offset-4 decoration-1 group-hover:decoration-2\",\"children\":\"Book your audit\"}],[\"$\",\"span\",null,{\"aria-hidden\":true,\"className\":\"transition-transform group-hover:translate-x-0.5\",\"children\":\"→\"}]]}],[\"$\",\"p\",null,{\"className\":\"mt-5 text-[0.85rem] text-ink-500 leading-relaxed\",\"children\":[\"Prefer email?\",\" \",[\"$\",\"a\",null,{\"href\":\"mailto:info@webmasterandmore.com\",\"className\":\"underline underline-offset-2 hover:text-ink-900\",\"children\":\"info@webmasterandmore.com\"}]]}]]}]]}],[\"$\",\"div\",null,{\"className\":\"border-t border-ink-200\",\"children\":[\"$\",\"div\",null,{\"className\":\"mx-auto max-w-6xl px-6 lg:px-8 py-6 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 text-xs text-ink-500\",\"children\":[[\"$\",\"p\",null,{\"children\":[\"© \",2026,\" AI Guy in LA. Built locally in Los Angeles, CA. Website by\",\" \",[\"$\",\"a\",null,{\"href\":\"https://webmasterandmore.com/\",\"className\":\"underline underline-offset-2 hover:text-ink-900\",\"children\":\"Webmaster \u0026 More\"}],\".\"]}],[\"$\",\"p\",null,{\"className\":\"font-mono tracking-wide uppercase text-[10px] text-ink-400\",\"children\":\"Privacy-first · Compliance-aware · Human in the loop\"}]]}]}]]}],[\"$\",\"$Le\",null,{}],[[\"$\",\"$Lf\",null,{\"src\":\"https://www.googletagmanager.com/gtag/js?id=G-05GR424SND\",\"strategy\":\"afterInteractive\"}],[\"$\",\"$Lf\",null,{\"id\":\"ga4-init\",\"strategy\":\"afterInteractive\",\"children\":\"\\n window.dataLayer = window.dataLayer || [];\\n function gtag(){dataLayer.push(arguments);}\\n gtag('js', new Date());\\n gtag('config', 'G-05GR424SND');\\n \"}]]]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[null,\"$L10\"],\"globalErrorComponent\":\"$11\",\"missingSlots\":\"$W12\"}]\n"])</script><script>self.__next_f.push([1,"13:I[5878,[\"972\",\"static/chunks/972-fbe8e47101704ce9.js\",\"878\",\"static/chunks/878-f7029bec14cb6a4b.js\",\"703\",\"static/chunks/703-5552f90b7ea731d9.js\",\"308\",\"static/chunks/app/blog/%5Bslug%5D/page-be2023f696e3132b.js\"],\"Image\"]\n14:\"$Sreact.fragment\"\n16:I[3148,[\"972\",\"static/chunks/972-fbe8e47101704ce9.js\",\"878\",\"static/chunks/878-f7029bec14cb6a4b.js\",\"703\",\"static/chunks/703-5552f90b7ea731d9.js\",\"308\",\"static/chunks/app/blog/%5Bslug%5D/page-be2023f696e3132b.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"10:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"Shipping a Production-Ready Brain+Hands Support Agent (WordPress + Python API) | AI Guy in LA\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"A practical blueprint for a multi-tool customer support agent with strict Brain+Hands separation, deterministic orchestration, secure API tools, and WordPress i\"}],[\"$\",\"meta\",\"4\",{\"name\":\"author\",\"content\":\"Omar\"}],[\"$\",\"link\",\"5\",{\"rel\":\"manifest\",\"href\":\"/manifest.webmanifest\",\"crossOrigin\":\"use-credentials\"}],[\"$\",\"meta\",\"6\",{\"name\":\"robots\",\"content\":\"index, follow\"}],[\"$\",\"link\",\"7\",{\"rel\":\"canonical\",\"href\":\"https://aiguyinla.com/blog/shipping-a-production-ready-brainhands-support-agent-wordpress-python-api\"}],[\"$\",\"link\",\"8\",{\"rel\":\"alternate\",\"type\":\"application/rss+xml\",\"href\":\"https://aiguyinla.com/feed.xml\"}],[\"$\",\"meta\",\"9\",{\"name\":\"google-site-verification\",\"content\":\"M14ImkJLWzYuttb-yJtBlPnbG6tmwhJ_3YIPj3n3Wi0\"}],[\"$\",\"meta\",\"10\",{\"property\":\"og:title\",\"content\":\"Shipping a Production-Ready Brain+Hands Support Agent (WordPress + Python API)\"}],[\"$\",\"meta\",\"11\",{\"property\":\"og:description\",\"content\":\"A practical blueprint for a multi-tool customer support agent with strict Brain+Hands separation, deterministic orchestration, secure API tools, and WordPress i\"}],[\"$\",\"meta\",\"12\",{\"property\":\"og:url\",\"content\":\"https://aiguyinla.com/blog/shipping-a-production-ready-brainhands-support-agent-wordpress-python-api\"}],[\"$\",\"meta\",\"13\",{\"property\":\"og:image\",\"content\":\"https://cms.aiguyinla.com/wp-content/uploads/2026/03/aw-auto-254-1773904594.png\"}],[\"$\",\"meta\",\"14\",{\"property\":\"og:image:width\",\"content\":\"1024\"}],[\"$\",\"meta\",\"15\",{\"property\":\"og:image:height\",\"content\":\"1024\"}],[\"$\",\"meta\",\"16\",{\"property\":\"og:type\",\"content\":\"article\"}],[\"$\",\"meta\",\"17\",{\"property\":\"article:published_time\",\"content\":\"2026-03-19T00:16:04\"}],[\"$\",\"meta\",\"18\",{\"property\":\"article:modified_time\",\"content\":\"2026-03-19T00:16:04\"}],[\"$\",\"meta\",\"19\",{\"name\":\"twitter:card\",\"content\":\"summary_large_image\"}],[\"$\",\"meta\",\"20\",{\"name\":\"twitter:title\",\"content\":\"Shipping a Production-Ready Brain+Hands Support Agent (WordPress + Python API)\"}],[\"$\",\"meta\",\"21\",{\"name\":\"twitter:description\",\"content\":\"A practical blueprint for a multi-tool customer support agent with strict Brain+Hands separation, deterministic orchestration, secure API tools, and WordPress i\"}],[\"$\",\"meta\",\"22\",{\"name\":\"twitter:image\",\"content\":\"https://cms.aiguyinla.com/wp-content/uploads/2026/03/aw-auto-254-1773904594.png\"}],[\"$\",\"link\",\"23\",{\"rel\":\"icon\",\"href\":\"/icon?38e490ba5d6b4ccf\",\"alt\":\"$undefined\",\"type\":\"image/png\",\"sizes\":\"32x32\"}],[\"$\",\"link\",\"24\",{\"rel\":\"apple-touch-icon\",\"href\":\"/apple-icon?598e5c968db298b2\",\"alt\":\"$undefined\",\"type\":\"image/png\",\"sizes\":\"180x180\"}],[\"$\",\"meta\",\"25\",{\"name\":\"next-size-adjust\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\n15:T23e7,"])</script><script>self.__next_f.push([1,"\u003cp\u003eThis build delivers a support/billing agent you can actually ship. It follows Brain+Hands separation, explicit tool contracts, a deterministic state machine, and secure backend tools. Stack: WordPress (frontend), Python FastAPI (tools + orchestrator), Redis (state/cache), Postgres (KB + logs), vector DB (memory), OpenAI/Groq/Anthropic (LLM).\u003c/p\u003e\n\u003cp\u003e1) Architecture overview\u003cbr /\u003e\n\u0026#8211; Brain (LLM policy): Plans, chooses tools, reasons. No direct DB/API access.\u003cbr /\u003e\n\u0026#8211; Hands (tools): Idempotent HTTP endpoints with strict schemas. Observable, rate-limited, auditable.\u003cbr /\u003e\n\u0026#8211; Orchestrator: State machine controlling turns, tool calls, retries, and timeouts.\u003cbr /\u003e\n\u0026#8211; Memory:\u003cbr /\u003e\n \u0026#8211; Short-term: per-session scratchpad (Redis).\u003cbr /\u003e\n \u0026#8211; Knowledge: vector search over product docs/FAQ.\u003cbr /\u003e\n \u0026#8211; Facts: authoritative store lookups (billing, orders).\u003cbr /\u003e\n\u0026#8211; Guardrails: auth, PII redaction, tool allowlist, cost/time budgets, circuit breakers.\u003cbr /\u003e\n\u0026#8211; Integration: WordPress plugin sends chat events to orchestrator; streaming tokens back to UI.\u003c/p\u003e\n\u003cp\u003e2) Contracts first (make tools boring and safe)\u003cbr /\u003e\nDefine JSON schemas for every tool. Keep them narrow, idempotent, and testable.\u003c/p\u003e\n\u003cp\u003eExample tool manifest (slice):\u003cbr /\u003e\n{\u003cbr /\u003e\n \u0026#8220;name\u0026#8221;: \u0026#8220;get_order_status\u0026#8221;,\u003cbr /\u003e\n \u0026#8220;description\u0026#8221;: \u0026#8220;Return current order state for a given order_id.\u0026#8221;,\u003cbr /\u003e\n \u0026#8220;method\u0026#8221;: \u0026#8220;POST\u0026#8221;,\u003cbr /\u003e\n \u0026#8220;url\u0026#8221;: \u0026#8220;https://api.example.com/tools/get_order_status\u0026#8221;,\u003cbr /\u003e\n \u0026#8220;input_schema\u0026#8221;: {\u003cbr /\u003e\n \u0026#8220;type\u0026#8221;: \u0026#8220;object\u0026#8221;,\u003cbr /\u003e\n \u0026#8220;properties\u0026#8221;: {\u003cbr /\u003e\n \u0026#8220;order_id\u0026#8221;: {\u0026#8220;type\u0026#8221;: \u0026#8220;string\u0026#8221;, \u0026#8220;pattern\u0026#8221;: \u0026#8220;^[A-Z0-9-]{6,}$\u0026#8221;}\u003cbr /\u003e\n },\u003cbr /\u003e\n \u0026#8220;required\u0026#8221;: [\u0026#8220;order_id\u0026#8221;],\u003cbr /\u003e\n \u0026#8220;additionalProperties\u0026#8221;: false\u003cbr /\u003e\n },\u003cbr /\u003e\n \u0026#8220;output_schema\u0026#8221;: {\u003cbr /\u003e\n \u0026#8220;type\u0026#8221;: \u0026#8220;object\u0026#8221;,\u003cbr /\u003e\n \u0026#8220;properties\u0026#8221;: {\u003cbr /\u003e\n \u0026#8220;status\u0026#8221;: {\u0026#8220;type\u0026#8221;: \u0026#8220;string\u0026#8221;},\u003cbr /\u003e\n \u0026#8220;updated_at\u0026#8221;: {\u0026#8220;type\u0026#8221;: \u0026#8220;string\u0026#8221;, \u0026#8220;format\u0026#8221;: \u0026#8220;date-time\u0026#8221;}\u003cbr /\u003e\n },\u003cbr /\u003e\n \u0026#8220;required\u0026#8221;: [\u0026#8220;status\u0026#8221;]\u003cbr /\u003e\n },\u003cbr /\u003e\n \u0026#8220;timeouts_ms\u0026#8221;: 2500,\u003cbr /\u003e\n \u0026#8220;retries\u0026#8221;: 1\u003cbr /\u003e\n}\u003c/p\u003e\n\u003cp\u003e3) Hands: secure Python FastAPI tools\u003cbr /\u003e\n\u0026#8211; Enforce schema at the edge.\u003cbr /\u003e\n\u0026#8211; Require JWT with narrow scopes.\u003cbr /\u003e\n\u0026#8211; Add rate limits and audit logs.\u003c/p\u003e\n\u003cp\u003efrom fastapi import FastAPI, Depends, HTTPException\u003cbr /\u003e\nfrom pydantic import BaseModel, Field\u003cbr /\u003e\nimport time\u003c/p\u003e\n\u003cp\u003eapp = FastAPI(title=\u0026#8221;SupportAgentTools\u0026#8221;)\u003c/p\u003e\n\u003cp\u003eclass OrderReq(BaseModel):\u003cbr /\u003e\n order_id: str = Field(min_length=6, pattern=r\u0026#8221;^[A-Z0-9-]{6,}$\u0026#8221;)\u003c/p\u003e\n\u003cp\u003eclass OrderResp(BaseModel):\u003cbr /\u003e\n status: str\u003cbr /\u003e\n updated_at: str | None = None\u003c/p\u003e\n\u003cp\u003edef auth(scope: str):\u003cbr /\u003e\n def _auth(token=Depends(\u0026#8230;)): # your JWT dependency\u003cbr /\u003e\n if scope not in token.scopes:\u003cbr /\u003e\n raise HTTPException(403, \u0026#8220;forbidden\u0026#8221;)\u003cbr /\u003e\n return token.sub\u003cbr /\u003e\n return _auth\u003c/p\u003e\n\u003cp\u003e@app.post(\u0026#8220;/tools/get_order_status\u0026#8221;, response_model=OrderResp)\u003cbr /\u003e\ndef get_order_status(req: OrderReq, _=Depends(auth(\u0026#8220;order:read\u0026#8221;))):\u003cbr /\u003e\n start = time.time()\u003cbr /\u003e\n # query read replica; maintain SLO use respective tools.\u003cbr /\u003e\n\u0026#8211; General product usage -\u0026gt; retrieve_docs.\u003cbr /\u003e\n\u0026#8211; Anything else -\u0026gt; answer concisely or ask a clarifying question.\u003c/p\u003e\n\u003cp\u003e6) Orchestrator: a small, reliable state machine\u003cbr /\u003e\nStates:\u003cbr /\u003e\n\u0026#8211; RECEIVE -\u0026gt; PLAN -\u0026gt; EXECUTE_TOOL? -\u0026gt; OBSERVE -\u0026gt; RESPOND -\u0026gt; END\u003c/p\u003e\n\u003cp\u003ePseudo:\u003cbr /\u003e\ndef handle_turn(msg, session_id):\u003cbr /\u003e\n budget = Budget(tokens=3000, tools=3, wall_ms=8000)\u003cbr /\u003e\n state = \u0026#8220;PLAN\u0026#8221;\u003cbr /\u003e\n memory = load_session(session_id)\u003cbr /\u003e\n while budget.ok() and state != \u0026#8220;END\u0026#8221;:\u003cbr /\u003e\n if state == \u0026#8220;PLAN\u0026#8221;:\u003cbr /\u003e\n action = llm_policy(memory, tool_manifest)\u003cbr /\u003e\n if action.type == \u0026#8220;tool\u0026#8221;:\u003cbr /\u003e\n state = \u0026#8220;EXECUTE_TOOL\u0026#8221;\u003cbr /\u003e\n else:\u003cbr /\u003e\n state = \u0026#8220;RESPOND\u0026#8221;\u003cbr /\u003e\n elif state == \u0026#8220;EXECUTE_TOOL\u0026#8221;:\u003cbr /\u003e\n result = call_tool(action.name, action.args, timeout=manifest[action.name].timeouts_ms)\u003cbr /\u003e\n record_observation(result)\u003cbr /\u003e\n state = \u0026#8220;OBSERVE\u0026#8221;\u003cbr /\u003e\n elif state == \u0026#8220;OBSERVE\u0026#8221;:\u003cbr /\u003e\n memory.update_with_observation(result)\u003cbr /\u003e\n if need_more_tools(result): state = \u0026#8220;PLAN\u0026#8221;\u003cbr /\u003e\n else: state = \u0026#8220;RESPOND\u0026#8221;\u003cbr /\u003e\n elif state == \u0026#8220;RESPOND\u0026#8221;:\u003cbr /\u003e\n reply = llm_response(memory)\u003cbr /\u003e\n emit_stream(reply)\u003cbr /\u003e\n state = \u0026#8220;END\u0026#8221;\u003c/p\u003e\n\u003cp\u003eControls:\u003cbr /\u003e\n\u0026#8211; Max 2 tool calls/turn for latency.\u003cbr /\u003e\n\u0026#8211; Tool circuit breaker after 2x p95 failures.\u003cbr /\u003e\n\u0026#8211; Token + time budgets enforced per turn.\u003c/p\u003e\n\u003cp\u003e7) Retrieval that doesn’t hallucinate\u003cbr /\u003e\n\u0026#8211; Chunk docs to 300–500 tokens with overlap 50–100.\u003cbr /\u003e\n\u0026#8211; Store title, URL, product tags, and last_updated.\u003cbr /\u003e\n\u0026#8211; Rerank top 20 -\u0026gt; 5 with a fast cross-encoder or LLM-judge at small context.\u003cbr /\u003e\n\u0026#8211; In answers, include “According to \u003ctitle\u003e ()” and quote minimal lines.\u003cbr /\u003e\n\u0026#8211; Evict stale docs with last_updated TTL checks.\u003c/p\u003e\n\u003cp\u003e8) Error handling and fallbacks\u003cbr /\u003e\n\u0026#8211; Tool error classes: 4xx user-fixable (show guidance), 5xx transient (retry with jitter), timeout (offer manual escalation).\u003cbr /\u003e\n\u0026#8211; If tools unavailable, switch to knowledge-only mode and surface a status note to the user.\u003cbr /\u003e\n\u0026#8211; Log: request_id, user_hash, tool_calls, latencies, token_usage, model, success_flag.\u003c/p\u003e\n\u003cp\u003e9) WordPress integration (plugin sketch)\u003cbr /\u003e\n\u0026#8211; Shortcode [aiguy_chat] renders chat UI.\u003cbr /\u003e\n\u0026#8211; Frontend calls /wp-json/aiguy/v1/chat (nonce protected).\u003cbr /\u003e\n\u0026#8211; Server proxy signs JWT to orchestrator and streams chunks back.\u003c/p\u003e\n\u003cp\u003ePHP (very abbreviated):\u003cbr /\u003e\nadd_action(\u0026#8216;rest_api_init\u0026#8217;, function () {\u003cbr /\u003e\n register_rest_route(\u0026#8216;aiguy/v1\u0026#8217;, \u0026#8216;/chat\u0026#8217;, [\u0026#8216;methods\u0026#8217;=\u0026gt;\u0026#8217;POST\u0026#8217;,\u0026#8217;callback\u0026#8217;=\u0026gt;\u0026#8217;aiguy_chat\u0026#8217;,\u0026#8217;permission_callback\u0026#8217;=\u0026gt;\u0026#8217;__return_true\u0026#8217;]);\u003cbr /\u003e\n});\u003cbr /\u003e\nfunction aiguy_chat(WP_REST_Request $r) {\u003cbr /\u003e\n $jwt = make_scoped_jwt([\u0026#8216;aud\u0026#8217;=\u0026gt;\u0026#8217;orchestrator\u0026#8217;,\u0026#8217;scopes\u0026#8217;=\u0026gt;[\u0026#8216;chat:send\u0026#8217;]]);\u003cbr /\u003e\n $resp = wp_remote_post(\u0026#8216;https://agent.example.com/chat\u0026#8217;, [\u003cbr /\u003e\n \u0026#8216;headers\u0026#8217;=\u0026gt;[\u0026#8216;Authorization\u0026#8217;=\u0026gt;\u0026#8221;Bearer $jwt\u0026#8221;],\u003cbr /\u003e\n \u0026#8216;body\u0026#8217;=\u0026gt;[\u0026#8216;session_id\u0026#8217;=\u0026gt;get_session_id(), \u0026#8216;message\u0026#8217;=\u0026gt;$r-\u0026gt;get_param(\u0026#8216;message\u0026#8217;)],\u003cbr /\u003e\n \u0026#8216;timeout\u0026#8217;=\u0026gt;15\u003cbr /\u003e\n ]);\u003cbr /\u003e\n return rest_ensure_response(wp_remote_retrieve_body($resp));\u003cbr /\u003e\n}\u003c/p\u003e\n\u003cp\u003e10) Models and performance\u003cbr /\u003e\n\u0026#8211; Use fast model for planning (e.g., gpt-4o-mini, llama-3.1-70b-instruct via Groq) and a stronger model for final generation when needed.\u003cbr /\u003e\n\u0026#8211; Target p95 \u0026lt; 2.5s single-turn with 0–1 tool; \u0026lt; 4.5s with 2 tools.\u003cbr /\u003e\n\u0026#8211; Cache retrieval and deterministic tool schemas to reduce tokens.\u003c/p\u003e\n\u003cp\u003e11) Security checklist\u003cbr /\u003e\n\u0026#8211; Tool allowlist + strict JSON schemas.\u003cbr /\u003e\n\u0026#8211; JWT with narrow scopes + rotation.\u003cbr /\u003e\n\u0026#8211; PII redaction before logs; encrypt sensitive fields at rest.\u003cbr /\u003e\n\u0026#8211; Separate read/write tools; require user confirmation for writes.\u003cbr /\u003e\n\u0026#8211; Rate limit per IP/user/session; WAF on tool API.\u003c/p\u003e\n\u003cp\u003e12) Observability\u003cbr /\u003e\n\u0026#8211; OpenTelemetry spans: plan, tool call, observe, generate.\u003cbr /\u003e\n\u0026#8211; Emit metrics: latency p50/p95, tool error rate, deflection rate, CSAT.\u003cbr /\u003e\n\u0026#8211; Log all prompts/responses with redaction; enable replay in a sandbox.\u003c/p\u003e\n\u003cp\u003e13) Deployment\u003cbr /\u003e\n\u0026#8211; Dockerize orchestrator + tools. Separate autoscaling for tools with spiky I/O.\u003cbr /\u003e\n\u0026#8211; Blue/green deploy; health checks include LLM warmup and tool canary.\u003cbr /\u003e\n\u0026#8211; Backpressure: queue requests when model or DB under load; shed load gracefully with a user-facing “email me results” fallback.\u003c/p\u003e\n\u003cp\u003e14) Minimal smoke test\u003cbr /\u003e\n\u0026#8211; Happy path: “Where is my order ABC123?”\u003cbr /\u003e\n\u0026#8211; Tool timeout path: inject 2s delay; verify graceful message.\u003cbr /\u003e\n\u0026#8211; Hallucination guard: ask for unavailable feature; ensure denial with doc citation.\u003c/p\u003e\n\u003cp\u003eDeliverables you can ship this week\u003cbr /\u003e\n\u0026#8211; Tool API (FastAPI) with 3 tools: get_order_status, get_invoice_pdf, retrieve_docs.\u003cbr /\u003e\n\u0026#8211; Orchestrator with state machine, budgets, and streaming.\u003cbr /\u003e\n\u0026#8211; WordPress plugin with nonce-protected REST route and basic chat UI.\u003cbr /\u003e\n\u0026#8211; Vector index with top 20 support articles and citations in answers.\u003cbr /\u003e\n\u0026#8211; Dashboards: latency, tool errors, deflection, cost.\u003c/p\u003e\n"])</script><script>self.__next_f.push([1,"7:[\"$\",\"div\",null,{\"className\":\"bg-paper\",\"children\":[[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"[{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"BlogPosting\\\",\\\"headline\\\":\\\"Shipping a Production-Ready Brain+Hands Support Agent (WordPress + Python API)\\\",\\\"image\\\":[\\\"https://cms.aiguyinla.com/wp-content/uploads/2026/03/aw-auto-254-1773904594.png\\\"],\\\"datePublished\\\":\\\"2026-03-19T00:16:04\\\",\\\"dateModified\\\":\\\"2026-03-19T00:16:04\\\",\\\"author\\\":{\\\"@type\\\":\\\"Person\\\",\\\"name\\\":\\\"Omar\\\",\\\"url\\\":\\\"https://aiguyinla.com\\\"},\\\"publisher\\\":{\\\"@type\\\":\\\"Organization\\\",\\\"name\\\":\\\"The AI Guy in LA\\\",\\\"logo\\\":{\\\"@type\\\":\\\"ImageObject\\\",\\\"url\\\":\\\"https://aiguyinla.com/icon\\\"}}},{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"BreadcrumbList\\\",\\\"itemListElement\\\":[{\\\"@type\\\":\\\"ListItem\\\",\\\"position\\\":1,\\\"name\\\":\\\"Home\\\",\\\"item\\\":\\\"https://aiguyinla.com/\\\"},{\\\"@type\\\":\\\"ListItem\\\",\\\"position\\\":2,\\\"name\\\":\\\"Blog\\\",\\\"item\\\":\\\"https://aiguyinla.com/blog\\\"},{\\\"@type\\\":\\\"ListItem\\\",\\\"position\\\":3,\\\"name\\\":\\\"Shipping a Production-Ready Brain+Hands Support Agent (WordPress + Python API)\\\",\\\"item\\\":\\\"https://aiguyinla.com/blog/shipping-a-production-ready-brainhands-support-agent-wordpress-python-api\\\"}]}]\"}}],[\"$\",\"article\",null,{\"className\":\"mx-auto max-w-3xl px-6 lg:px-8 pt-12 pb-20 lg:pt-16 lg:pb-28\",\"children\":[[\"$\",\"$Lc\",null,{\"href\":\"/blog\",\"className\":\"inline-flex items-center gap-2 text-sm text-ink-500 hover:text-ink-900 transition-colors\",\"children\":[[\"$\",\"span\",null,{\"aria-hidden\":true,\"children\":\"←\"}],\" All articles\"]}],[\"$\",\"header\",null,{\"className\":\"mt-10\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-center gap-3 text-ink-400\",\"children\":[[\"$\",\"span\",null,{\"className\":\"eyebrow\",\"children\":\"Article\"}],[\"$\",\"span\",null,{\"className\":\"h-px flex-1 bg-ink-200\"}],[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] tabular-nums\",\"children\":\"March 19, 2026\"}]]}],[\"$\",\"h1\",null,{\"className\":\"mt-7 font-serif text-[2.25rem] sm:text-[2.75rem] lg:text-[3.5rem] leading-[1.05] tracking-tight text-ink-900 font-medium\",\"children\":\"Shipping a Production-Ready Brain+Hands Support Agent (WordPress + Python API)\"}],null]}],[\"$\",\"div\",null,{\"className\":\"mt-10 aspect-[16/9] w-full overflow-hidden rounded-2xl border border-ink-200 bg-paper-100 relative\",\"children\":[\"$\",\"$L13\",null,{\"src\":\"https://cms.aiguyinla.com/wp-content/uploads/2026/03/aw-auto-254-1773904594.png\",\"alt\":\"Shipping a Production-Ready Brain+Hands Support Agent (WordPress + Python API)\",\"fill\":true,\"priority\":true,\"sizes\":\"(min-width: 1024px) 768px, 100vw\",\"className\":\"object-cover\"}]}],[\"$\",\"div\",null,{\"className\":\"article mt-12\",\"children\":[[\"$\",\"$14\",\"0\",{\"children\":[[\"$\",\"div\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"$15\"}}],false]}]]}],[\"$\",\"aside\",null,{\"className\":\"mt-16 rounded-2xl border border-ink-200 bg-white p-8 sm:p-10\",\"children\":[[\"$\",\"p\",null,{\"className\":\"eyebrow\",\"children\":\"Next step\"}],[\"$\",\"h2\",null,{\"className\":\"mt-4 font-serif text-[1.5rem] sm:text-[1.75rem] leading-snug text-ink-900\",\"children\":\"Want this applied to your own business?\"}],[\"$\",\"p\",null,{\"className\":\"mt-3 text-ink-600 leading-relaxed max-w-xl\",\"children\":\"Reading about a pattern and knowing which one fits your workflows are two different problems. Pick whichever is faster for you.\"}],[\"$\",\"div\",null,{\"className\":\"mt-8 flex flex-col sm:flex-row gap-4\",\"children\":[[\"$\",\"$Ld\",null,{\"href\":\"/audit\",\"location\":\"blog_post_footer_audit\",\"className\":\"inline-flex items-center justify-center gap-2 rounded-full bg-ember-600 px-5 py-3 text-sm font-medium text-white hover:bg-ember-700 transition-colors\",\"children\":\"Book a free 30-minute audit →\"}],[\"$\",\"$Ld\",null,{\"href\":\"/ai-opportunity-report\",\"location\":\"blog_post_footer_report\",\"className\":\"inline-flex items-center justify-center gap-2 rounded-full border border-ink-300 px-5 py-3 text-sm font-medium text-ink-900 hover:border-ink-900 transition-colors\",\"children\":[\"Or get the \",\"$$149\",\" written report\"]}]]}],[\"$\",\"p\",null,{\"className\":\"mt-5 text-[0.8125rem] text-ink-500 leading-relaxed\",\"children\":[\"The audit is a live call. The report is written, fixed-scope, and delivered within \",5,\" business days — no call required.\"]}]]}],[\"$\",\"section\",null,{\"className\":\"mt-16 pt-10 border-t border-ink-200\",\"children\":[[[\"$\",\"p\",null,{\"className\":\"eyebrow\",\"children\":\"Keep reading\"}],[\"$\",\"ul\",null,{\"className\":\"mt-6 grid gap-px bg-ink-200 sm:grid-cols-3 rounded-xl overflow-hidden\",\"children\":[[\"$\",\"li\",\"240\",{\"className\":\"bg-paper\",\"children\":[\"$\",\"$Lc\",null,{\"href\":\"/blog/shipping-a-production-ready-support-agent-brain-hands-with-wordpress-frontend-and-django-backend\",\"className\":\"group flex h-full flex-col p-5 hover:bg-white transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] tracking-[0.12em] uppercase text-ink-400\",\"children\":\"March 12, 2026\"}],[\"$\",\"span\",null,{\"className\":\"mt-2 font-serif text-[1.0625rem] leading-snug text-ink-900 group-hover:text-signal-800 transition-colors\",\"children\":\"Shipping a Production-Ready Support Agent (Brain + Hands) with WordPress Frontend and Django Backend\"}],[\"$\",\"span\",null,{\"className\":\"mt-2 text-[0.875rem] text-ink-600 leading-relaxed\",\"children\":\"A complete, deployable pattern for a production chatbot that actually does work: Brain + Hands separation, tool calling,…\"}]]}]}],[\"$\",\"li\",\"226\",{\"className\":\"bg-paper\",\"children\":[\"$\",\"$Lc\",null,{\"href\":\"/blog/shipping-a-production-ready-wordpress-support-agent-brain-hands-secure-tools-real-logs\",\"className\":\"group flex h-full flex-col p-5 hover:bg-white transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] tracking-[0.12em] uppercase text-ink-400\",\"children\":\"March 4, 2026\"}],[\"$\",\"span\",null,{\"className\":\"mt-2 font-serif text-[1.0625rem] leading-snug text-ink-900 group-hover:text-signal-800 transition-colors\",\"children\":\"Shipping a Production-Ready WordPress Support Agent (Brain + Hands, Secure Tools, Real Logs)\"}],[\"$\",\"span\",null,{\"className\":\"mt-2 text-[0.875rem] text-ink-600 leading-relaxed\",\"children\":\"A step-by-step build of a maintainable WordPress support agent that can answer product questions, check orders, and crea…\"}]]}]}],[\"$\",\"li\",\"212\",{\"className\":\"bg-paper\",\"children\":[\"$\",\"$Lc\",null,{\"href\":\"/blog/building-a-production-ready-support-agent-for-wordpress-brain-hands-architecture\",\"className\":\"group flex h-full flex-col p-5 hover:bg-white transition-colors\",\"children\":[[\"$\",\"span\",null,{\"className\":\"font-mono text-[11px] tracking-[0.12em] uppercase text-ink-400\",\"children\":\"February 25, 2026\"}],[\"$\",\"span\",null,{\"className\":\"mt-2 font-serif text-[1.0625rem] leading-snug text-ink-900 group-hover:text-signal-800 transition-colors\",\"children\":\"Building a Production-Ready Support Agent for WordPress (Brain + Hands Architecture)\"}],[\"$\",\"span\",null,{\"className\":\"mt-2 text-[0.875rem] text-ink-600 leading-relaxed\",\"children\":\"A practical blueprint for deploying a real support chatbot on WordPress. Includes Brain + Hands design, tool wiring, mem…\"}]]}]}]]}]],[\"$\",\"div\",null,{\"className\":\"mt-8 rounded-xl border border-ink-200 p-5 sm:p-6\",\"children\":[[\"$\",\"p\",null,{\"className\":\"eyebrow text-ember-600\",\"children\":\"If you run the business\"}],[\"$\",\"$Lc\",null,{\"href\":\"/blog/ai-customer-service-without-violating-privacy\",\"className\":\"group mt-3 block\",\"children\":[[\"$\",\"span\",null,{\"className\":\"font-serif text-[1.125rem] leading-snug text-ink-900 group-hover:text-signal-800 transition-colors\",\"children\":\"How to Use AI for Customer Service Without Violating Privacy Expectations\"}],[\"$\",\"span\",null,{\"className\":\"mt-2 block text-[0.9375rem] text-ink-600 leading-relaxed\",\"children\":\"Customer service is the most tempting place to apply AI and the most dangerous one to do it carelessly. The same convers…\"}]]}]]}]]}],[\"$\",\"div\",null,{\"className\":\"mt-16 pt-10 border-t border-ink-200\",\"children\":[[\"$\",\"div\",null,{\"className\":\"mb-10\",\"children\":[\"$\",\"$L16\",null,{\"url\":\"https://aiguyinla.com/blog/shipping-a-production-ready-brainhands-support-agent-wordpress-python-api\",\"title\":\"Shipping a Production-Ready Brain+Hands Support Agent (WordPress + Python API)\"}]}],[\"$\",\"$Lc\",null,{\"href\":\"/blog\",\"className\":\"text-sm text-ink-500 hover:text-ink-900 transition-colors\",\"children\":\"← More articles\"}]]}]]}]]}]\n"])</script></body></html>