2:17 AM. A single inbound notification sat in our Slack #ops channel. A manager at a manufacturing company in Osaka, Japan had left a message on the 5ya.io contact form: "We're considering an AI bot — could we hop on a 30-minute call?" That message sat unanswered for nine hours, all the way until the start of the next business day. In the morning standup, we made the call: we'd build the bot ourselves.
This series is the operating notebook for the AI tools we've built by hand. Episode one — our in-house inbound handling bot.

Why we built it ourselves instead of buying a SaaS chatbot
We spent about a week comparing two off-the-shelf chatbot SaaS products. Either one handled FAQ replies well enough, but more than 70% of the inbound we receive isn't a simple question — it's a BoFu consultation request. For decision-maker-tone questions like "Can we run a PoC in the $700–1,000/month range?" or "Can you show us manufacturing case studies?", pre-scripted flowchart answers gave wildly uneven response quality.
At first I thought a single-shot Claude API script would be enough. Once I actually tried it, other problems surfaced. Intent classification, prior conversation lookup, CRM updates, an internal review queue — the moment I tried to bundle all of those into one call, the prompt crossed 800 lines, and a single failure took the whole pipeline down with it.
The architecture on one page — Claude · LangGraph · OpenRouter
By the fourth draft, we'd narrowed it down to this combination.
- Claude Opus 4.7 — long context and tone stability. Decision-maker inquiries don't want a one-line answer; they want a weighty 4–6 sentence reply.
- LangGraph — a library that lets you draw the state flow directly as nodes and edges. By splitting classify, research, draft, and review into separate nodes, we can resume from the exact failure point.
- OpenRouter — model gateway. We routed the light classification step to Haiku 4.5 and the body writing to Opus 4.7 to keep costs down.
Costs swung a lot with the model switch.
| Model | Input (1M tokens) | Output (1M tokens) |
|---|---|---|
| Claude Opus 4 (older) | $15 | $75 |
| Claude Opus 4.6 / 4.7 | $5 | $25 |
The token cost per reply dropped to roughly one-third. By week four, our cumulative API spend was around $135 — set that against even one person's overnight response hours and the comparison stops being meaningful.
The LangGraph graph — five nodes
Here's the bare skeleton of the graph.
from langgraph.graph import StateGraph, END
graph = StateGraph(InboundState)
graph.add_node("classify", classify_intent)
graph.add_node("research", fetch_context)
graph.add_node("draft", draft_reply_with_claude)
graph.add_node("review_queue", push_to_slack)
graph.add_node("crm_sync", upsert_to_crm)
graph.set_entry_point("classify")
graph.add_conditional_edges(
"classify",
lambda s: "research" if s["intent"] == "lead" else END,
)
graph.add_edge("research", "draft")
graph.add_edge("draft", "review_queue")
graph.add_edge("review_queue", "crm_sync")
graph.add_edge("crm_sync", END)
Two things mattered most. First, the classify node split simple FAQ from leads, sending only leads down the heavy pipe. Second, the review_queue node tossed the bot's draft reply into a Slack channel and blocked the send until a human reviewed it once. We deliberately left the last centimeter of automation to a person — and that's the decision our team is most proud of from the four-week run.
Four weeks of operation, in numbers
Data from April 28 to May 25 — four weeks.
- Inbound handled: 142 (89 FAQ / 53 leads)
- Average draft time: 47 seconds
- Overnight (10 PM–9 AM) response rate: 100% (every case → bot draft → batch human review and send at 9 AM the next business day)
- Revision rate at human review: 31%
- Sent as-is from the bot draft: 69%
That 31% revision rate felt high at first. But pulling each one apart, nearly half were light touches — "add a closing line to the email," "add a suggested meeting slot." Real tone or factual breakdowns happened four times across four weeks. Two of those were the bot quoting our own pricing on its own initiative, and we immediately bolted a guard onto the prompt: "never answer pricing directly — always redirect to a free diagnostic." Honestly, this part leaned more on squeezing the operational rules than on anything a single line of code could clean up.
"100% response rate" sounds grand on paper, but unpacked it just means this: an overnight inquiry from a Japanese decision-maker is sitting as a review-ready draft the moment Korean business hours start. Where there used to be a nine-hour empty seat, there's now a scene with one human touch already applied.
Two sticking points, and the operational rules behind them
Hallucinations never went to zero. Multilingual was also tricky — Korean word order leaked into two replies that were supposed to be in Japanese. We solved both not with code but with an operational rule: that final "one human review before sending" node. Detailed build approaches are organized by scenario on our AI automation services page.
Wrap-up — a bot isn't a tool for cutting headcount
A Korean SME CEO once told us, "Now we don't lose customers during the late-night hours when no one can take their calls." Our four-week run landed in the same place. A bot isn't a tool for cutting headcount — it's closer to infrastructure that keeps you from losing leads during the hours people can't reach.
At 5years+, we build inbound automation bots for Korean and Japanese SMEs on a four-week cycle. A 30-minute diagnostic tailored to your stack (messenger, CRM, product catalog) is free — Free consultation → 5ya.io/contact.
In the next episode, we cover a different shade of automation. Producing five ad videos a week with Runway Gen-4 + Gemini Image — if the sales bot is the seat that catches leads, the video pipeline is the seat that brings them in. Automation only starts to move the revenue curve when both seats are connected.