The main reason developers hesitate to build agent loops isn’t technical complexity.
It comes down to cost.
Running dozens of automated iterations on standard frontier models drains your budget fast.
Kimi K3 changes that equation.
In this guide, we will break down how an execution loop works, analyze why prompt caching makes K3 ideal for long runs, and walk through two complete implementations (Claude Code and a raw Python setup):
Firstly,
What an Agent Loop Actually Is
Strip away the marketing hype and an agent loop consists of four repeatable steps:
GOAL → ATTEMPT → CHECK → (Passed? Done : Retry)
- Goal: A clear, programmatically checkable condition. “All test suites pass”, “Zero linter warnings”, or “Page render speed stays under 1s”. Never a general request like “improve this module”.
- Attempt: The model performs a single targeted edit or action toward that goal.
- Check: An external tool evaluates the result against your goal. This can be a unit test runner, a linter, or a secondary deterministic script.
- Repeat: Feed the error output back into the next turn. Stop execution when the goal condition evaluates to true or your safety ceiling is reached.
Every extra layer (long-term memory, multi-agent orchestration, or background execution) builds directly on top of this basic pattern.
The Economics: Why Kimi K3 Powers Loops
Agent loops re-process substantial context every turn.
The codebase, project rules, and execution history are re-sent with every API call.
On traditional model APIs, repeating this context costs full price on every iteration. K3 avoids this penalty by offering heavily discounted prompt caching:
- Fresh Tokens: $3.00 / M
- Cached Tokens: $0.30 / M
Consider a typical execution carrying an 800K token prefix alongside 50K new tokens generated per turn:
- Kimi K3: $0.24 (cached) + $0.15 (fresh) = $0.39 per turn
- Standard Frontier Model (e.g., Fable 5): 850K tokens × $10.00/M = $8.50 per turn
A 50-turn overnight run costs approximately $20 on K3 versus over $400 on standard high-end alternatives.
That price difference changes automated agent runs from a high-risk expense into a practical daily workflow.
The Golden Rule for Caching: Keep your static project files, rules, and system prompt as an identical prefix at the top of every turn. Append turn-specific feedback at the bottom to trigger cache hits reliably.
Setup A: Claude Code Integration
If you use Claude Code, agent loops are built into the workflow. You can point the underlying provider to K3 using Moonshot’s official endpoint config:
export ANTHROPIC_BASE_URL=https://api.moonshot.ai/anthropic
export ANTHROPIC_AUTH_TOKEN=${YOUR_MOONSHOT_API_KEY}
export ANTHROPIC_MODEL=kimi-k3
export ANTHROPIC_DEFAULT_OPUS_MODEL=kimi-k3
export ANTHROPIC_DEFAULT_SONNET_MODEL=kimi-k3
export ANTHROPIC_DEFAULT_HAIKU_MODEL=kimi-k3
export CLAUDE_CODE_SUBAGENT_MODEL=kimi-k3
export ENABLE_TOOL_SEARCH=false
export CLAUDE_CODE_AUTO_COMPACT_WINDOW=1048576Once configured, managing the loop requires two commands:
/goalestablishes your objective:"all tests in tests/ pass and code coverage stays above 80%"./loopruns the execution cycle continuously until the check validates successfully.
You can confirm your setup via /status.
The 1M token auto-compact setting ensures long runs avoid unnecessary context trimming, keeping failure histories intact.
Setup B: Raw API Loop (Python)
For custom setups outside CLI tools, here is a complete Python pattern using the standard OpenAI library:
from openai import OpenAI
client = OpenAI(
api_key="YOUR_MOONSHOT_API_KEY",
base_url="https://api.moonshot.ai/v1",
)
# Identical prefix across all turns guarantees cache hits at $0.30/M
STABLE_PREFIX = f"""You are a coding agent operating inside an execution loop.
GOAL: Resolve all failing tests in the codebase.
PROJECT STATE:
{project_dump}
RULES:
- Perform one targeted edit per turn.
- State your edit in two short sentences.
- If all checks pass, output exactly: GOAL_REACHED
"""
history = []
MAX_TURNS = 30
for turn in range(MAX_TURNS):
result = run_tests() # External verification step
if result.passed:
print(f"Goal completed in {turn} turns.")
break
response = client.chat.completions.create(
model="kimi-k3",
messages=[
{"role": "system", "content": STABLE_PREFIX},
*history[-6:], # Maintain the last 3 exchanges
{
"role": "user",
"content": f"Turn {turn}. Test Output:\n{result.output}\nApply the next fix.",
},
],
)
change = response.choices[0].message.content
apply_change(change) # Commit changes to a dedicated branch
history += [
{"role": "user", "content": f"Turn {turn} logs submitted."},
{"role": "assistant", "content": change},
]Essential Implementation Details
- External Check:
run_tests()determines progress. Never rely on the model to self-evaluate its edits. - Trimmed History: Retain only the most recent exchanges. Let your static system prompt carry the primary codebase state.
- Git Isolation: Ensure all updates target a temporary feature branch so main remains protected.
Guardrails and Common Pitfalls
- Set Hard Token Caps: Programmatically track total token spend per execution. Stop the loop if budget thresholds are crossed.
- Detect Stalled Progress: Abort execution if the same test output repeats across 3 consecutive turns.
- Avoid Self-Grading: Relying on responses like “the fix looks complete” leads to broken builds. Keep tests and static checkers strictly external.
- Maintain Prefix Order: Introducing dynamic timestamps or altering file lists inside your prefix breaks prompt caching, pushing turn costs back up to $3.00 / M.
Getting Started (Checklist)
- Acquire a Moonshot API key and top up your account balance.
- Choose Setup A (Claude Code CLI) or Setup B (Python script).
- Set a single verifiable goal on a localized task or bug fix.
- Execute 10 supervised turns to verify cache performance and turn costs.
- Expand turn limits once your validation pipeline is stable.
Easy?
In case we are meeting for the first time, come over here, it’ll be worth the roller coaster of articles that are gonna come up in the next few weeks.