AI-Assisted Development Analysis
Honest assessment of how GenAI tools impacted this project’s software development lifecycle.
Tools & Their Roles
| Tool | Primary Use | Impact |
|---|---|---|
| Claude Code | Dev assistant + in-editor — scaffolding, architecture, code review, debugging | High — ~90–95% of implementation, 100% of tests |
| GitHub Copilot | Deployment debugging — “explain with copilot” feature inside GitHub Actions to diagnose failing CI/CD runs | Medium — streamlined fixing CI failures |
| OpenAI gpt-4o-mini | Runtime LLM — powers the Gloss Assembler & Translator agents | Critical — the core agentic feature |
The cross-provider split is intentional: dev tooling is Anthropic (Claude), runtime LLM is OpenAI. Each one earns its keep in a different layer.
Quantitative Impact
Where AI Tools Were Used
1. Service Scaffolding (Claude Code)
Claude generated FastAPI microservice boilerplate for authService, inferenceService, and agentService:
app/main.pywith router setup, health endpointapp/models.pywith Pydantic schemasapp/auth.pywith JWT middlewareconftest.pyfor test fixturesDockerfileandrequirements.txt
Quality: 7/10 on first pass. Boilerplate was correct; edge cases (JWT refresh logic, error handling) needed manual refinement.
2. Agent Prompt Engineering (Claude Code + iteration)
Claude drafted the system prompts for Gloss Assembler and Translator. Iteration loop:
- Claude generated initial assembler prompt → LLM output was valid JSON but too verbose
- Refined constraints (e.g., “Keep corrections list to max 5 items”)
- Added in-prompt examples for topic-comment ASL grammar
- Final iteration: added explicit instruction “Return ONLY valid JSON, no preamble”
3. Test Generation (Claude Code)
100% of the ~40-test suite was generated by Claude Code. Example:
@pytest.mark.asyncio
async def test_predict_returns_top3():
response = await client.post("/predict", json={...})
assert response.status_code == 200
assert len(response.json()["predictions"]) == 3
Human refinement focused on mocking MLflow loads and adding auth-failure / malformed-input cases.
4. Deployment Debugging (GitHub Copilot in GitHub Actions)
The “explain with copilot” feature inside GitHub Actions made it dramatically faster to diagnose failing CI/CD runs. We’d hit a red workflow, click “Explain”, and get an actionable hypothesis instead of grepping logs.
5. Kubernetes Manifest Generation (Claude Code)
Generated auth-deployment.yaml, inference-deployment.yaml, agent-deployment.yaml, ingress.yaml. Quality: 6/10 — needed manual tuning:
- Replicas and resource requests were guessed
JWT_SECRET_KEYwas initially hardcoded → manually moved to Kubernetes Secrets- Ingress TLS cert configuration was omitted → manually added cert-manager integration
Hallucinations & Corrections
Hallucination 1: SQL Table Column Names
Symptom: The streaming INSERT into the Databricks SQL Warehouse was failing.
Root cause: streaming.py (Claude-generated) dynamically built INSERT statements from the full event dictionary, which included fields like kind and alternatives that weren’t in the original asl.inferenceEvents table schema. This caused UNRESOLVED_COLUMN errors in Databricks.
Resolution:
- Immediate fix: Added the missing columns directly to the Delta tables via
ALTER TABLE. - Proper fix: Later stripped the unnecessary fields before building the
INSERT, so the schema stays clean.
-- Immediate unblock
ALTER TABLE asl.inferenceEvents ADD COLUMN kind STRING;
ALTER TABLE asl.inferenceEvents ADD COLUMN alternatives ARRAY<STRING>;
# Proper fix in streaming.py: whitelist columns before INSERT
ALLOWED_COLS = {"timestamp", "modelName", "sign", "confidence",
"latencyMs", "eventId", "modelVersion"}
clean_event = {k: v for k, v in event.items() if k in ALLOWED_COLS}
Hallucination 2: Nightly-Teardown Workflow
What happened: Claude generated a nightly-teardown.yml workflow intended to tear down the AKS cluster overnight (to save Azure spend) and rebuild it on the first push of the day.
What it actually did: Only deleted the resource group — wiping more than intended and leaving the cluster in an awkward state when it rebuilt.
Resolution: Deleted the workflow and now tear down manually when necessary. The lesson: don’t hand AI tools production resource-management responsibility without strict guardrails.
Agentic Workflow
The agentic layer uses two LLM agents in sequence to turn raw recognizer output into usable English:
Gets recognized signs
Runs forward pass
Returns top-3
Writes to Delta
Displays alternatives
User thumbs-up / down
Or swap alternative
Input: ordered signs + alts
Drop signs < 0.40 conf
Flag 0.40–0.65
Contextual correction
Output: cleaned_gloss + log
Input: ASL-ordered gloss
Output: grammatical English
Show corrections log
Allow user feedback
Agent roles:
- Gloss Assembler — Quality filter + context-aware swap. Drops the low-confidence noise the recognizer can’t suppress.
- Translator — Grammar repair. Re-orders topic-comment ASL into SVO English, inserts copulas/articles.
Decision flow: Browser collects signs → on pause, batches them → assembler cleans → translator reconstructs → UI renders. The user feedback loop closes the cycle.
How it uses APIs/ML: The flow is /predict (inferenceService, ML model) → /translate (agentService, LLM agents). Both agents call OpenAI directly with Pydantic-typed response_format for guaranteed schema compliance.
Challenges & Lessons Learned
💥 Free-Edition Spark Limit
Spark Connect 256 MB model serialization cap broke our Spark ML RF → switched to sklearn RF.
🖥️ Lack of Compute
Our baseline RF accuracy plateaued under 55% → leaned on the pretrained Microsoft Research ST-GCN for production-quality recognition.
📝 Prompt Brittleness
Long or all-low-confidence gloss inputs produced malformed JSON → fixed with structured outputs + retry-once.
🏗️ Infra Tuning
AI-generated K8s manifests guessed resources and leaked secrets → hand-hardened.
AI accelerates the 80% that's boilerplate, but the last 20% — security, infra, environment limits, prompt edge cases — still needs a human. Treat AI output as a first draft to verify, never as truth.
Tips for Future Teams
- ✅ Commit a verified skeleton before splitting work — everyone branches off a known-good base
- ✅ Drop a
CLAUDE.mdof conventions so sessions don’t drift on naming, structure, or style - ✅ Document environment constraints (Databricks Free Edition caps, AKS quotas) so AI doesn’t hallucinate around them
- ✅ Always verify by hand: security code, infra code, and ML model-loading code — the AI gets these wrong most often
Overall Usefulness
Where AI Added Most Value
- Service scaffolding — 90% correct on first try
- Test generation — 100% from Claude, ~40 tests
- Deployment debugging — “Explain with Copilot” in GitHub Actions
- Documentation — first drafts of docstrings and READMEs
Where AI Added Least Value
- Kubernetes manifests — heavy manual refinement
- Security-critical code — needed careful review for edge cases
- Agent prompts — required iterative refinement and validation
- Resource-management workflows — the nightly-teardown hallucination cost real time
Time-Benefit Analysis
- Best case: 40%+ faster on boilerplate, tests, and docs
- Realistic average: 4–6 hours saved per developer per day
- Worst case: Hallucinations like the SQL schema and nightly teardown soaked ~5–6 hours of debugging
Recommendations
- Use Claude Code early for architectural guidance and service scaffolding
- Use Copilot’s “Explain” feature in GitHub Actions for CI debugging — much faster than grepping
- Use LLM APIs (gpt-4o-mini) for domain-specific agents with structured outputs
- Always verify security, infra, and ML-model-loading code by hand
- Document constraints (Databricks Free, AKS quotas) so AI doesn’t hallucinate around them