Business Pain Point: Coach Capacity Is the Ceiling
A friend of mine runs a small fitness app with a few thousand registered users, and its core selling point is "customized training plans." But the so-called customization actually works like this:
User fills out a questionnaire (goals, experience, injury history, available equipment, training days per week) → the plan is handwritten by part-time coaches on the backend → coach sends it back via WeChat → customer service enters it into the system → user is notified.
A skilled coach takes an average of 25–45 minutes to write a solid beginner plan, and with back-and-forth communication, users wait an average of 18 hours from payment to receiving their plan. Part-time coaches are paid per plan, at a labor cost of about 30 RMB per plan. During peak season with 80 orders per day, plan generation alone burned 2,400 RMB/day, and coaches couldn't keep up—the user churn rate rose visibly, with nearly 30% of users requesting refunds during the waiting period.
This is a classic case of "labor-intensive personalization": the personalization itself is the product's value, but the generation method doesn't scale.
Solution Choice: AI Generation + Manual Spot-Checks, Not Full Automation
We didn't dare go fully automated. Mistakes in fitness plans can involve safety issues (e.g., scheduling heavy breath-holding movements for users with hypertension), so architecturally we positioned it as "AI draft + rule validation + manual spot-checks":
- AI handles structured generation: converting user questionnaires into plan drafts
- Rule engine handles hard constraints: filtering the exercise library by injury history, validating training frequency and rest days, capping intensity progression
- Manual spot-checks: 100% inspection for the first 1,000 plans, then 5% sampling afterward, plus a one-click "request human review" option for users
Architecture Design
User questionnaire → Plan generation service
│
├─ Structured prompt templates (5 sets by goal type)
├─ User profile assembly (goals/experience/injuries/equipment/time)
│
▼
Unified AI API gateway (multi-model routing)
│ ┌─ Simple plans → lightweight model (cost-first)
│ ├─ Injury history present → flagship model (quality-first)
│ └─ Primary model rate-limited/failing → automatic fallback to backup model
▼
Output parsing (JSON Schema validation + retries)
│
▼
Rule engine (exercise blacklist / rest days / intensity caps)
│
Pass → persist to database → visible to user
Fail → auto-rewrite or route to human queueKey Implementation Steps
- Define the plan as a JSON Schema. Exercise names, sets, reps, rest durations, weekly schedules—everything structured. Model output must pass schema validation, or it's automatically retried (up to 3 times). Doing this step makes all downstream validation, display, and modification much easier.
- Exercise library whitelist. The model can only choose from 300 pre-built exercises, eliminating hallucinated exercises. Each exercise carries tags (joint load, contraindications, equipment requirements), which the rule engine uses for filtering.
- Split prompt templates by scenario: five templates for fat loss / muscle gain / strength / rehab / at-home, rather than one giant prompt for everything. After splitting, output tokens per call dropped by about 40%.
- Tiered model routing: about 70% of simple requests (no injury history, standard goals) go to the lightweight model; complex cases go to the flagship model.
- Gradual rollout: for the first two weeks, all AI results went through human confirmation—whatever coaches changed was logged and fed back into prompt iteration.
Core Generation Code (Simplified)
async def generate_plan(user_profile: UserProfile) -> TrainingPlan:
# 1. Rule engine filters the exercise pool first
pool = action_repo.filter(
exclude_injuries=user_profile.injuries,
equipment=user_profile.equipment,
level=user_profile.experience
)
# 2. Model selection: flagship model if injury history present
model = "premium-model" if user_profile.injuries else "lite-model"
# 3. Unified gateway call handles rate limiting and fallback automatically
resp = await ai_gateway.chat(
model=model,
messages=build_prompt(TEMPLATE[user_profile.goal], user_profile, pool),
response_format={"type": "json_object"}
)
plan = TrainingPlan.parse_raw(resp.content)
# 4. Hard validation: rest days, weekly training volume, intensity progression
violations = rules_engine.check(plan, user_profile)
if violations:
plan = await revise(plan, violations) # rewrite with violations attached
return planEfficiency Ledger: Before and After
| Metric | Before AI | After AI (once stable) |
|---|---|---|
| Time per plan | 25–45 min (manual) | 35–60 sec (incl. validation retries) |
| User wait time | 18 hours average | 40 seconds average, P95 under 3 minutes |
| Labor cost per plan | ~30 RMB | ~0.4 RMB token cost + ~1.5 RMB amortized spot-check cost |
| Daily capacity ceiling | Limited by coach scheduling (~80 plans) | No practical limit |
| Refund rate | Nearly 30% (churn during waiting period) | Dropped to single digits |
Coaches shifted from "writing plans" to "reviewing and handling complex cases"—two people now handle the full daily order volume, and they even launched a premium paid "deep customization by real coaches" tier. AI standardizes the long tail; humans move up the value chain.
Why a Unified AI API Gateway Is Essential
Early on in this project, we connected directly to a model SDK, and within a month we paid the price:
First, model switching costs. Text tasks like fitness plans are extremely price-sensitive to model choice. When Model A raises prices or Model B releases a cheaper new version, direct SDK integration means changing code, authentication, error handling, and running regression tests—at least two days per switch. With a unified gateway, switching is just changing a model name parameter, live in half an hour. In the ledger mentioned at the start of this article, token costs dropped from an estimated 4,000+ RMB/month to around 1,400 RMB, thanks to two painless model routing adjustments.
Second, keys and billing managed in one place. The most common accident for small teams is keys scattered across multiple services. In gateway mode, the application holds only one gateway key, while the keys for dozens of upstream models are all rotated and managed on the gateway side—much smaller attack surface and audit cost.
Third, no need to write your own rate limiting, fallback, and retries. The generation service only cares about prompts and schemas; dirty work like switching to backup models on timeout or auto-queuing on 429s is handled at the gateway layer. In three months since launch, we haven't written a single line of fault-tolerance code for model vendor SDKs.
Rough estimate: the gateway saves us 4–6 hours per week in adaptation and maintenance work—for a team of two or three people, that's a full person-day.
Conclusion
Fitness plan generation is just the tip of the iceberg for the broad category of "structured personalized content"—meal plans, learning paths, travel itineraries all follow nearly the same playbook: JSON Schema + whitelist + rule validation + tiered routing. If you're building a similar product, I recommend starting with a unified AI API gateway as your foundation—don't let model selection and key management turn into your technical debt three months later. If you want to get hands-on, you can start by registering an account at https://api.thistoken.ai/register, get your gateway key working, then come back and build the first version of your generation service following the architecture diagram in this article.
---
Ready to try it yourself? Sign up at https://api.thistoken.ai/register to get your API key and start building.
Bạn muốn thử Token.AI?
Tạo API Key cấp dự án, bật kênh trong bảng điều khiển và định cấu hình định tuyến, ngân sách và nhật ký kiểm tra.
注册 ThisToken.AI 并获取 API Key