Improving LLM Coding Performance: Post-Training Techniques and Evaluation Practices

    As large language models shift from pre-training scale to post-training refinement, coding agents are making significant leaps in real-world performance. This article explores why reinforcement learning post-training delivers outsized gains, what makes coding tasks uniquely suited to RL, how to build a practical three-layer evaluation system, and how to balance flagship-level capability with budget constraints.

    1. From “Stacking Parameters” to “Stacking Post-Training”: A Repeatedly Validated Path

    Over the past two years, the main thread of large language model competition has been an arms race in parameter count and data scale. But in coding agent scenarios, pure pre-training expansion is hitting clear diminishing returns: base models “know how to write code,” yet they struggle to “get tasks done” — they lack long-horizon planning, don’t iterate through trial and error, and can’t fluently drive a terminal or browser. On hands-on benchmarks that test real command-line fundamentals, early base models often scored embarrassingly low, badly mismatched with their general intelligence level.

    This has produced a clear turning point in the industry: rather than rushing to train an even larger next-generation base model, teams are applying deep reinforcement learning (RL) post-training to existing base models. A typical pattern looks like this: months after a base model is released, the vendor does not ship a larger version. Instead, they run hundreds of days of RL iterations on the same base model while continuously hardening the surrounding sandbox, terminal, and browser tooling. The result is a cross-generational improvement on coding benchmarks and real tasks, often paired with major API price cuts enabled by inference optimization.

    This kind of iteration cadence can be abstracted into a general timeline:

    Phase Typical Actions Problem Addressed
    Base model release Large-scale pre-training, open weights Establish a knowledge and reasoning foundation
    Engineering groundwork CLI/IDE plugins, sandboxes, terminal and browser tooling Build the “hands and feet” for agent scenarios
    Post-training sprint Multi-domain joint reinforcement learning Close gaps in tool use and long-horizon tasks
    Version iteration Price reductions, full weight release Expand ecosystem and cost advantages

    The takeaway for practitioners: when evaluating a model, don’t just ask “who is it and how big is it.” Ask “what has it been post-trained into.”

    2. Why Post-Training Delivers Cross-Generational Gains

    2.1 The Division of Labor Between Pre-Training and Post-Training

    Pre-training solves “what the model knows”: language understanding, code syntax, framework knowledge, and world knowledge. Post-training solves “what to do and how to do it”: following output specifications, proactively using tools, self-recovering after failures, and completing multi-step tasks under constraints. A useful analogy: pre-training builds the engine; post-training installs the transmission and navigation. Horsepower doesn’t change, but the car can finally complete a complex route.

    2.2 Three Keys to RL Post-Training

    First: verifiable rewards. Coding tasks are naturally suited to reinforcement learning because outcomes can be judged automatically by machines: whether code compiles, whether unit tests pass, whether terminal commands execute successfully. A simplified reward function looks like this:

    1. def reward(task, trajectory) -> float:
    2. score = 0.0
    3. if compile_pass(trajectory.patch): # Code compiles
    4. score += 0.3
    5. score += 0.5 * tests_passed_ratio(task) # Ratio of tests passed
    6. if no_regression(task): # No existing test regressions
    7. score += 0.2
    8. return score

    Second: multi-domain joint training. Running RL on code alone leads to “teaching to the test”: the model becomes good at solving exercises but has poor aesthetics, messy planning, and rigid dialogue. Common industry practice is to mix code, math reasoning, tool calling, multi-turn dialogue, and visual aesthetics into joint training, using a unified reward model to constrain policy updates. This prevents single-dimensional capability spikes from causing regressions in general ability.

    Third: co-evolution of environment and model. Agent capability = model × environment. Sandbox stability, the readability of tool error messages, and context truncation policies can all amplify or swallow a model’s true ability. That’s why serious teams iterate on the model and the toolchain simultaneously rather than tuning the model in isolation.

    2.3 Why Frontend and 3D Are “Litmus Tests”

    Frontend and 3D generation tasks simultaneously test three things: code correctness (does it run directly), visual aesthetics (is the layout, color scheme, and animation polished), and spatial reasoning (coordinate systems, lighting, camera motion). These tasks are extremely hard to game through benchmark drilling, which is why more teams are using them to gauge a model’s overall “feel.” Empirically, once aesthetic-dimension preference optimization enters post-training, frontend task performance is often the first to improve — making it a highly sensitive window into the quality of a model’s post-training.

    3. Evaluation Methodology: How to Scientifically “Benchmark” a Model

    Public benchmark scores are a reference; your own evaluation suite is the real basis for decisions. A three-layer evaluation system is recommended:

    3.1 Layer 1: Public Benchmarks — Establish the Floor

    • Comprehensive capability indices: gauge overall intelligence level and generational gaps.
    • Code generation benchmarks: measure function-level correctness and pass@1.
    • Terminal hands-on benchmarks: test command-line fundamentals. These tasks require models to locate failures in real environments, install dependencies, and modify configurations. They are extremely sensitive to post-training quality and are the first-choice indicator for observing whether a model has genuinely improved.

    3.2 Layer 2: Your Own Evaluation Set — Find the Ceiling

    Build 20–50 tasks aligned with your actual work. Four categories are recommended: frontend visual tasks (generate component pages with interactive effects or 3D showcase pages; score manually on fidelity, polish, and code quality), terminal troubleshooting (inject failures into containers and have the model fix them), legacy code refactoring (verify all tests still pass after refactoring), and long-horizon tasks (allow 30+ consecutive tool-calling steps; track completion rate). A skeleton evaluation harness:

    1. import asyncio, json
    2. async def run_case(model, case):
    3. env = Sandbox(image=case.image) # Generic container sandbox
    4. traj = await agent_loop(model, env, case.prompt, max_steps=30)
    5. return {
    6. "id": case.id,
    7. "tests": env.run_tests(case.test_cmd),
    8. "steps": traj.steps,
    9. "tokens": traj.token_usage,
    10. }
    11. async def main():
    12. cases = load_cases("evals/coding.jsonl")
    13. results = await asyncio.gather(*(run_case(MODEL, c) for c in cases))
    14. print(json.dumps(results, ensure_ascii=False, indent=2))

    3.3 Layer 3: Shadow Deployment — Measure Real-World Reception

    Once evaluation passes, pick one or two real projects for a dual-model shadow test: randomly assign the same batch of tickets to the new and old models, then compare pass rates, rework rates, and developer satisfaction after two weeks. Only this step exposes the gap between benchmark scores and production performance.

    4. The Cost Perspective: Balancing Flagship Capability with Budget

    4.1 Understanding Pricing Structure and Hidden Costs

    LLM services typically bill per input/output token, with output unit prices significantly higher than input. Most platforms offer cache discounts for repeated prefixes and discounted tiers for offline batch jobs. Per-task cost can be approximated as:

    1. Cost ≈ input tokens × input unit price + output tokens × output unit price

    The hidden cost of agentic coding lies in the “loop”: a single task often triggers 10–30 rounds of calls, each carrying historical context. The biggest cost lever is therefore not switching models — it’s compressing context. Additionally, new-generation model releases often come with substantial price cuts, driven by inference optimization, operator and compiler improvements, and a market strategy of trading price for volume. For users, this is a tangible dividend.

    4.2 Three Immediately Effective Cost-Saving Measures

    1. Context trimming: keep only task-relevant fields in tool outputs; summarize historical turns.
    2. Tiered routing: send scaffolding generation and simple completions to smaller models; reserve flagship models for architecture design and difficult debugging.
    3. Leverage caching and batch processing: keep system prompts stable to hit prefix caches; route offline evaluations through batch channels.

    If you go the route of privately deploying open-weight models, you must explicitly account for GPU depreciation and concurrency utilization. Typically this only becomes cost-effective in scenarios with strict data compliance requirements and high call volumes. Whether self-hosting or using a managed service such as Baidu AI Cloud, it’s advisable to measure per-task cost with a small amount of traffic first, then scale up gradually.

    4.3 A Quick Decision Table

    Scenario Recommendation
    Sensitive data, high call volume Open weights + private inference
    Fast validation, long-tail calls Managed API + tiered routing
    Budget-constrained teams New-generation cost-effective post-trained models are often the sweet spot
    Extreme capability requirements Top-tier closed models + human fallback

    5. Staying Clear-Headed: Four Reminders Beyond the Scores

    1. Benchmark scores ≠ productivity: leading a leaderboard doesn’t mean leading in your codebase. Your own evaluation suite is non-negotiable.
    2. Beware of benchmark-gaming post-training: over-optimizing against public benchmarks can hurt off-benchmark generalization. Deliberately include non-leaderboard tasks in your evaluation set.
    3. Agent engineering is half the battle: with the same model, poor prompts and tool design can eat half the performance. Optimize your scaffolding before talking about switching models.
    4. Keep human review in the loop: visual aesthetics and architectural trade-offs still lack reliable automated metrics. Critical outputs must have human oversight.

    6. Conclusion

    The next round of LLM competitiveness doesn’t live on the parameter sheet. It lives in post-training recipes, toolchain maturity, and evaluation systems. For developers, building your own evaluation set, understanding the cost structure, and implementing tiered routing are what actually convert “flagship-level capability” into “production-line productivity” — and these are the three investments most worth your time in any technology selection process.