Deep dive: LLM pipeline
4,455 military job codes, translated into tech careers
A veteran types in their military job code and gets a guide to the tech roles it maps to, with skills, certifications and salary data that names its source.
- 4,455job codes indexed across five service branches
- 4,201codes with a generated tech pathway (94%)
- 35tech roles in the taxonomy, each with a BLS SOC code
- 0model calls at request time
- Role
- Designed and built the pipeline and the pages that render it
- Stack
- TypeScript, Vercel AI SDK, Zod schemas, Google Gemini, Next.js static generation
- Model
gemini-2.0-flash, named in each generator script- Data
- Lightcast, Census ACS 2023 estimates, a curated fallback table
- Shipped
- Pathways generator merged 2 May 2026 (#1104)
The problem
A military job code tells a civilian recruiter almost nothing. A veteran leaving the service knows what they did, and usually does not know which software roles value it or what those roles pay. Vets Who Code answers that question one conversation at a time. There are thousands of job codes across the Army, Navy, Air Force, Marine Corps and Coast Guard, and nobody can hold all of them in their head.
What it has to do
- Cover every code it can. A veteran who looks up their own code should find it.
- Return the same structure every time. Pages are generated from the data, so free-form model output is not acceptable.
- Say where each salary came from. A veteran is making a career decision on these numbers.
- Cost nothing per page view. The organization cannot pay for a model call each time someone reads a guide.
Approach and architecture
The pipeline runs offline in stages. Each stage reads the previous stage’s JSON, asks Gemini for an object that must match a Zod schema, and writes JSON back to the repository. The site then builds static pages from those files.
Data model
| File | Keyed by | Entries |
|---|---|---|
job-codes-index.json | Job code | 4,455 |
cognitive-skills-map.json | Job code | 4,392 |
military-systems-map.json | Job code | 4,386 |
cert-equivalencies.json | Job code | 4,350 |
career-pathways-map.json | Job code | 4,231 |
training-pipeline.json | Job code | 4,203 |
tech-pathways-map.json | Job code, joined to role and salary | 4,201 |
tech-roles-taxonomy.json | Role, with BLS SOC code | 35 |
Key tradeoffs
Generate offline, commit the output
Model output is generated ahead of time and reviewed as a diff, then served as static pages. A guide loads with no model latency and no token cost, and a model outage cannot take a page down. The cost is freshness: a guide is as current as the last run. Recorded as DR-005.
Salary data falls back in three tiers and labels itself
The pipeline asks Lightcast first, then Census ACS, then a curated table. Each record carries a dataSource field so the page can show which tier answered. The pipeline always completes, and a reader can tell a live figure from a curated one. Recorded as DR-006.
Small batches, resumable runs
Generators work in batches of 10 with a one-second pause, and the pathways step merges into existing output. A failed run resumes where it stopped instead of paying to regenerate four thousand entries.
Measurable outcome
- 4,201 job codes have a published guide with roles, certifications, demand and salary.
- Each guide carries Occupation structured data so search engines and AI assistants can read it (#1407).
- The same data produces a curriculum gap report that ranks tech roles by how many job codes map to them. Data Analyst leads with 3,796 codes, then Security Engineer with 3,723.
Evals, cost, latency, fallback and limits
| Evals | Output is validated against a Zod schema on every call. There is no labelled accuracy set yet. See v2. |
|---|---|
| Cost | Zero at request time. Generation cost per run is not recorded yet. |
| Latency | Zero model latency for readers. Pages are static. |
| Fallback | Salary: Lightcast, then Census ACS, then curated. Generation: resumable from existing output. |
| Known limits | 254 indexed codes have no tech pathway. Mappings are model-generated and schema-checked, and have not been reviewed code by code by a subject-matter expert. |
AI collaboration note
The model writes the per-code content. I own the schemas that constrain it, the role taxonomy it has to map into, the salary sourcing and the decision about what gets published. Generated files are committed and reviewed like any other change.
What I’d change in v2
- Build an accuracy set. Have veterans from each branch grade a sample of guides for their own job codes, and track the score across model versions.
- Record tokens and cost for each generation run alongside the output.
- Move the model name to one shared constant. It is currently repeated in each script.
- Close the 254-code gap or state on the page why a code has no pathway.
Walk me through it
- Why job code translation is the first question every transitioning veteran asks.
- The stages, and why each one writes a file a person can read.
- How a Zod schema turns a language model into a function with a return type.
- The three salary tiers and why the page shows which one answered.
- What the gap report shows about demand by role.
- What is not measured yet, and how I would measure it.