cd /news/large-language-models/how-i-replaced-llm-calls-with-coding… · home topics large-language-models article
[ARTICLE · art-54884] src=dev.to ↗ pub= topic=large-language-models verified=true sentiment=↑ positive

How I replaced LLM calls with coding agent calls and saved money

A developer proposes replacing LLM API calls with coding agent calls to reduce costs, citing that coding assistants like Codex, Cursor Pro, and GitHub Copilot Pro cost significantly less per million tokens than traditional LLM APIs. The developer provides a Python wrapper to integrate Claude Code CLI as a drop-in replacement for LLM calls, enabling the use of cheaper agent-based inference for building AI agents.

read4 min views1 publishedJul 10, 2026

When building an AI agent, you need LLM calls. It can be done via a remote API or a local API, but either way you need to do it. Whether the agent is a simple conversational agent or a ReAct agent with a bunch of tools, whether it's using a complex graph or a simple RAG, it must be based on the concept of sending prompts to the language model.

But, what if we replace the language model with... another agent? Let's say we already have a smart agent with a bunch of tools that can handle complex problems. Why not use it to build a new agent on top of it? This way we can focus on the specific custom functionality we want to achieve, while already having the common functionalities covered by the underlying agent.

You might think this must be expensive. You get a better performance, so you have to pay for it, right? Well, not necessarily. The catch is that the coding assistants are actually surprisingly cheap when compared to API prices. They offer much more than raw LLM calls, they offer amazing agent functionality, but the cost is actually lower, and it's not a small difference. The cost of LLM calls per 1M tokens is usually between $2 and $7. For coding assistant subscriptions, it's a bit more tricky to calculate because you pay for monthly subscription, but it can be still converted to per 1M tokens cost, and from what LLM just told me it is around $0.08 to $2. That's a huge difference! And the complex agents are cheaper than raw LLM's!

according to ChatGPT:

Service Cost per 1M tokens
Codex / ChatGPT coding plan ~$0.08
Cursor Pro ~$0.08–0.25
GitHub Copilot Pro ~$0.10–0.30
Claude Pro / Claude Code ~$0.74
GPT-5 API ~$2.1
Claude Sonnet API ~$4.2
Claude Opus API ~$7.0

according to Claude:

Service Cost per 1M tokens
Haiku 4.5 (API) $1.80
Sonnet 5 (API, intro thru Aug 31 '26) $3.60
Sonnet 5 (API, standard) $5.40
Opus 4.8 (API) $9.00
Fable 5 (API) $18.00
Claude Code — Pro ~$1.10–$2.15 (est.)
Claude Code — Max 5x ~$2.10–$4.15 (est.)
Claude Code — Max 20x ~$2–$4 (est.)

So, why not use the coding agents to build new agents? The only problem is that they don't have API. But, this is a problem that can be solved by writing a simple wrapper to the agent that will communicate with it via CLI. We just have to install the agent on the machine from which we want to call it and use the wrapper. Simple and brilliant. Here's the code:

"""Claude Code CLI — complete integration module.

Provides plain-text and structured LLM calls via the local `claude` binary,
plus a LangChain-compatible adapter for use with make_llm().

Requires the `claude` binary on PATH.
"""

import json
import subprocess
from typing import Generic, TypeVar

from langchain_core.messages import HumanMessage, SystemMessage
from pydantic import BaseModel

T = TypeVar("T", bound=BaseModel)

_TIMEOUT = 120


def cli_call(system: str, user: str) -> str:
    """Run a plain-text prompt through the Claude CLI and return the response."""
    return _run(system=system, user=user)

def cli_call_structured(system: str, user: str, output_type: type[T]) -> T:
    """Run a structured prompt through the Claude CLI and parse into output_type."""
    schema = json.dumps(output_type.model_json_schema())
    raw = _run(system=system, user=user, json_schema=schema)
    return output_type.model_validate_json(raw)

def _run(system: str, user: str, json_schema: str | None = None) -> str:
    cmd = [
        "claude",
        "--print",
        "--no-session-persistence",
        "--tools", "",
    ]
    if system:
        cmd += ["--system-prompt", system]
    if json_schema:
        cmd += ["--output-format", "json", "--json-schema", json_schema]
    cmd.append(user)

    result = subprocess.run(
        cmd, capture_output=True, text=True, encoding="utf-8", timeout=_TIMEOUT
    )
    if result.returncode != 0:
        stderr = (result.stderr or "").strip()
        raise RuntimeError(f"claude CLI exited {result.returncode}: {stderr}")

    stdout = (result.stdout or "").strip()
    if not stdout:
        raise RuntimeError("claude CLI returned empty output")

    if json_schema:
        envelope = json.loads(stdout)
        payload = envelope.get("result", stdout)
        return payload if isinstance(payload, str) else json.dumps(payload)

    return stdout


class CliResponse:
    def __init__(self, content: str) -> None:
        self.content = content

class ClaudeCliStructured(Generic[T]):
    def __init__(self, output_type: type[T]) -> None:
        self._type = output_type

    def invoke(self, messages: list) -> T:
        system, user = _extract_messages(messages)
        return cli_call_structured(system=system, user=user, output_type=self._type)

class ClaudeCli:
    """LangChain-compatible adapter that delegates to the claude CLI binary."""

    def invoke(self, messages: list) -> CliResponse:
        system, user = _extract_messages(messages)
        return CliResponse(content=cli_call(system=system, user=user))

    def with_structured_output(self, output_type: type[T]) -> ClaudeCliStructured[T]:
        return ClaudeCliStructured(output_type)

def _extract_messages(messages: list) -> tuple[str, str]:
    system = ""
    user = ""
    for m in messages:
        if isinstance(m, SystemMessage):
            system = m.content if isinstance(m.content, str) else ""
        elif isinstance(m, HumanMessage):
            user = m.content if isinstance(m.content, str) else ""
    return system, user
── more in #large-language-models 4 stories · sorted by recency
── more on @codex 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/how-i-replaced-llm-c…] indexed:0 read:4min 2026-07-10 ·