Agentic systems that plan, reason, and invoke tools in loops have moved from research demos to production pipelines. Deploying them reliably means solving context growth, latency stacking, and cascading failure modes that do not appear in single-turn chat. This post covers architecture patterns, safety mechanisms, and cost controls we have seen work in production, with concrete code you can adapt today.
Model Selection for Agentic Roles
Not every agent step needs the same horsepower. A supervisor routing tasks to workers has different requirements than a coding agent editing files across a repository. Oxlo.ai hosts models that map cleanly to these tiers.
- Reasoning and planning: DeepSeek R1 671B MoE for deep reasoning, or Kimi K2.6 for advanced reasoning and agentic coding.
- Long-horizon context: DeepSeek V4 Flash with 1M context, or GLM 5 for long-horizon agentic tasks.
- General execution: Llama 3.3 70B or Qwen 3 32B for multilingual agent workflows.
- Fast tool use: Minimax M2.5 for coding and agentic tool use, or Qwen 3 Coder 30B.
Route tasks to the right model at runtime to balance latency and capability.
import openai
import os
client = openai.OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key=os.environ["OXLO_API_KEY"]
)
# Example mapping to Oxlo.ai model tiers
MODEL_MAP = {
"long_context": "deepseek-v4-flash", # DeepSeek V4 Flash, 1M context
"coding": "kimi-k2.6", # Kimi K2.6
"default": "llama-3.3-70b" # Llama 3.3 70B
}
def route_task(prompt, context_length):
if context_length > 100_000:
model = MODEL_MAP["long_context"]
elif any(k in prompt for k in ("refactor", "debug")):
model = MODEL_MAP["coding"]
else:
model = MODEL_MAP["default"]
return client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
tools=tools,
)
Context Budgeting and Loop Control
The biggest surprise in production agentic workloads is context inflation. Every tool response, observation, and intermediate reasoning step gets appended to the conversation history. On token-based providers, cost scales with every loop iteration. Oxlo.ai uses request-based pricing, so one flat cost per API request keeps costs predictable even when tool outputs are long. Still, you should enforce limits to preserve latency and accuracy.
Best practices:
- Hard cap iterations (e.g., max 10 steps).
- Summarize turns older than N steps into a compressed scratchpad.
- Truncate tool outputs (e.g., max 4,000 characters per tool response).
class AgentLoop:
def __init__(self, max_steps=10, max_tool_output=4000):
self.max_steps = max_steps
self.max_tool_output = max_tool_output
self.history = []
def run(self, task):
for step in range(self.max_steps):
response = self.llm(step, task)
if response.finish_reason == "stop":
return response.content
tool_result = self.execute_tool(response.tool_calls)
self.history.append({
"step": step,
"tool_result": tool_result[:self.max_tool_output]
})
Tool Schema Hardening
Function calling is the glue of agentic systems, but schemas drift and models hallucinate parameters. Oxlo.ai supports function calling, JSON mode, and streaming, which you can combine to build strict tool boundaries.
Best practices:
- Version tool schemas in code, not in prompts.
- Validate arguments with Pydantic before execution.
- Use JSON mode when you need structured output without a tool call.
- Set a timeout on every tool invocation.
from pydantic import BaseModel, ValidationError
import json
class SearchArgs(BaseModel):
query: str
top_k: int = 5
def safe_call_tool(name, arguments):
if name == "search":
try:
args = SearchArgs(**json.loads(arguments))
except ValidationError:
return {"error": "Invalid schema"}
return search(**args.dict())
Failure Modes and Retries
Agents fail differently than chatbots. A tool timeout can stall an entire workflow, and a bad parameter can trigger a destructive action. Treat the LLM as an unreliable caller and wrap every external interaction with circuit breakers.
Patterns:
- Idempotency keys for all side-effecting tools.
- Exponential backoff on the LLM client, not just the tool.
- Global timeout across the entire agent loop, not per step.
Oxlo.ai has no cold starts on popular models, so retry storms do not trigger warmup penalties that add latency.
import time
from functools import wraps
def with_retries(max_attempts=3, backoff=2):
def decorator(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
for attempt in range(max_attempts):
try:
return fn(*args, **kwargs)
except Exception as e:
if attempt == max_attempts - 1:
raise
time.sleep(backoff ** attempt)
return wrapper
return decorator
Parallel vs Sequential Execution
When an agent needs to collect data from three APIs, sequential tool calls multiply latency. Where there are no dependencies, fan out.
Oxlo.ai supports streaming and has no cold starts, so parallel invocations scale without hidden warmup costs. Use a supervisor to aggregate results.
import concurrent.futures
def supervisor_plan(task):
plan = llm_generate_plan(task)
with concurrent.futures.ThreadPoolExecutor() as pool:
futures = {
pool.submit(call_tool, step.tool, step.args): step
for step in plan if step.parallel
}
results = {futures[f]: f.result(timeout=30) for f in futures}
return synthesize(results)
Observability and State Management
You cannot debug what you cannot see. Log every intermediate completion, tool argument, and raw tool response. Because Oxlo.ai pricing is flat per request, your cost per step is deterministic, which makes it easier to attribute spend to individual agent trajectories without token math.
Store state externally (Redis, Postgres) so crashes do not lose progress. Checkpoint after every tool call.
def checkpoint(state):
redis.setex(f"agent:{state.run_id}", 3600, json.dumps(state.to_dict()))
def step(state):
response = client.chat.completions.create(
model="qwen-3-32b", # example identifier
messages=state.messages,
tools=state.tools,
)
state.add_turn(response)
checkpoint(state)
return state
Cost Architecture
Token-based pricing penalizes the exact behavior agents exhibit most: appending long tool outputs and reasoning traces back into context. With token-based providers, a single agent loop can consume tens of thousands of tokens per step, and cost scales linearly with that growth.
Oxlo.ai charges one flat cost per API request regardless of prompt length. For agentic workloads, that changes the economics. You can pass full file contents, stack traces, or retrieval chunks into context without a metered penalty on every turn. See https://oxlo.ai/pricing for plan details.
This does not mean you should ignore context limits. Model context windows still bound accuracy, and latency rises with sequence length. It does mean your cost optimization strategy shifts from token trimming to request efficiency: batch work into fewer calls, eliminate redundant loops, and choose the right model tier per step.
Agentic deployment is fundamentally a systems engineering problem. The teams that ship reliably treat the LLM as one component in a larger control loop: bounded iterations, validated schemas, external state, and predictable costs. Oxlo.ai provides the request-based inference layer, the model variety, and the OpenAI-compatible APIs that let you focus on the loop, not the bill.
Top comments (0)