Dual-Core Practice for Cost-Effective AI-Assisted Coding

    AI coding tools are now everyday infrastructure, but bills and delivery speed often fail to improve in proportion. This article explains the efficiency paradox, a planner-versus-executor split, minimal context rules, and shifting acceptance earlier so expensive models are used only for irreversible decisions.

    AI-assisted coding has moved from experiment to daily infrastructure, yet many teams have not seen matching gains in cost or delivery cadence. Stronger models make each call more expensive; longer chats bloat context; faster generation makes review and rework easy to underestimate. Subjectively, writing feels smoother. Objectively, tickets do not close proportionally faster, and debugging can take longer than writing by hand. The issue is rarely that the model is not smart enough. It is using the same expensive capability for architecture judgment, boilerplate, formatting, and log reading—like asking a senior architect to both review designs and repeatedly tighten screws on a production line: capable, but not cost-effective, and no more reliable than a practiced process.

    Admit the efficiency paradox

    Two observations coexist in the industry. Many developers feel copilots raise output. Controlled comparisons in real codebases often find that total time for similar tasks does not fall. Both can be true. The feeling of speed usually comes from an earlier first draft, less typing, and a more continuous flow. Extra wall time comes from “almost correct” code that still needs interface alignment, tests, implicit-assumption hunting, and repeated explanation in the wrong context.

    Waste falls into four types. Decision waste: if scope, error policy, and compatibility are not written first, the model fills gaps with high-probability generic code, and every later change is billed again. Context waste: dumping the whole repo, unrelated logs, and multi-turn chatter dilutes signal; answers get longer and less accurate. Role waste: one session asked both to design and to fix ten type errors will oscillate between architecture and patches. Acceptance waste: without an executable definition of done, judgment is “does this look right,” and debug cost shifts to humans.

    The first cost-control principle is not chasing a more expensive model. It is fewer wasted calls, each with a clear input contract and exit condition.

    Dual core: separate planning from execution

    Split the workflow into a planning core and an execution core.

    The planning core uses a stronger, higher-priced model, but with few calls, tight context, and decision-oriented output. It does not own large implementations. It produces goals and non-goals, blast radius, interface and data contracts, risks and rollback points, task breakdown, and acceptance criteria. A good plan is short enough to read by a human, and every item is checkable later.

    The execution core uses a better price-to-performance, acceptable-latency model and lands work task by task. Its input is not “finish this requirement.” It is a frozen slice of change: which modules to touch, which not to touch, behaviors that must hold, tests to add, and a diff summary on completion. On failure, revise first in this layer with narrower context. Only if the contract itself is wrong do you return to planning.

    Expensive models then do key decisions instead of full-session companionship. Cheaper models do many constrained local edits. Quality comes from verifiable contracts, not model tier.

    Practical session boundaries:

    In planning, discuss only problem definition and trade-offs. Do not generate large implementations. Output four fixed sections: assumptions, approach, task list, acceptance. In execution, take one task at a time. Input includes relevant snippets, constraints, and failure criteria. Output includes change notes, risks, and self-check results. If the same acceptance item still fails after two rounds, stop generating and have a human find the root cause instead of retrying on a false premise.

    Context rules

    More context is not better; traceable context is. Prefer the smallest sufficient context over pasting the whole repository.

    Scope: provide only types, interfaces, callers, and related tests the current task touches, and note source modules. Mark stale snippets so old implementations are not treated as current.

    Constraints: write prohibitions as checkable statements—do not change public response fields, do not add undeclared dependencies, do not swallow existing error codes. Vague “keep the style” is almost untestable.

    Evidence: pair failure logs with expected versus actual output and truncate unrelated stacks. Ask the model to explain the difference before changing code; that is less likely to introduce new branches than “just fix it.”

    Memory: periodically compress long chats into confirmed facts, rejected options, and open questions. Feed the compressed note, not the original chatter, into the next round to save tokens and reduce contradictions.

    Feed documents in structure, not as whole manuals. Prefer a glossary, field meanings, error codes, state machines, sample requests and responses, and known pitfalls. Number entries stably so task cards cite numbers instead of restating prose. Execution then implements by item; planning can check missed constraints.

    Move acceptance earlier

    “Almost correct” is expensive because correctness is postponed to human reading. Turn part of acceptance into machine-checkable gates after model output and before close human review.

    At minimum: lint and format, unit tests or a small regression, contract comparison, and a diff-size threshold. If an execution task suddenly expands beyond the authorized range, fail automatically instead of chatting to patch holes. Humans review plans, failed gates, and out-of-scope diffs—not every generated line.

    A task card can stay plain text, product-agnostic:

    Goal: return a clear error when creating an order with insufficient inventory.
    Non-goals: do not change price calculation or database schema.
    Allowed: validation branch in the order service and corresponding tests.
    Forbidden: new external dependencies; changing success-response fields.
    Acceptance: specified tests pass; insufficient inventory returns the agreed error code; success-path response matches pre-change behavior.
    On failure: if a non-goal file must change, stop and return to planning.

    Such cards are transferable. Whatever general inference service sits underneath, the executor sees the same constraints. Teams that want execution traffic on pay-per-use cloud inference can attach only the execution core to a general model service—for example, model inference from Baidu AI Cloud—for constrained code edits and drafts. Planning, permissions, and audit stay in your own process. Do not assume the cloud understands the business; semantics must come from the task card and document IDs.

    Look at cost and quality together

    Per-call price misleads. More useful metrics: total calls to finish a requirement, total input/output volume, human rework rounds, and how soon defects appear after merge. Dual-core usually aims to reduce the last three, not to make every answer the cheapest possible.

    Planning-core work: cross-module trade-offs, compatibility and migration, security and permission boundaries, failure-mode design. Execution-core work: adding branches to an interface, adding tests, rename and small refactor, local fixes from a known error, turning a confirmed plan into a commit message. Do not close the loop with any model alone on unreproduced production incidents, UX changes without acceptance criteria, or trade-offs that need a business owner.

    Pilot on a low-risk path, such as internal-tool bugfixes. Measure for two weeks: whether plans are short and executable, whether execution often goes out of bounds, whether humans still rewrite large chunks. Frequent overreach is usually task slicing, not model tier. Vague plans plus more budget only write the wrong design into the repo faster.

    Humans become orchestrators

    People do not exit. They confirm the problem is worth doing, approve trade-offs in the plan, and handle exceptions gates cannot express. Models speed drafts and revisions inside bounds. When time moves from “try the model once more” to “write constraints and turn acceptance into gates,” both bills and debug time fall. Use expensive capability for irreversible judgment, cost-effective capability for repeatable execution, and keep context minimal and traceable. That is how AI coding shifts from consuming models to orchestrating a workflow.