Category: Без рубрики

  • Best Ai Voice Agents

    Best AI Voice Agents: A DevOps Guide to Self-Hosted and Managed Options

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    Voice-driven automation has moved well past simple IVR menus, and teams evaluating the best AI voice agents today are really choosing between managed APIs, self-hosted pipelines, and hybrid architectures. This guide walks through the technical tradeoffs, deployment patterns, and infrastructure decisions that matter when you’re building or buying a voice agent for production use.

    Whether you’re routing customer support calls, building an outbound sales dialer, or wiring a voice interface into an internal tool, the underlying architecture looks similar: speech-to-text, a reasoning layer, text-to-speech, and a telephony or WebRTC transport. What differs is how much of that stack you own versus rent, and that decision shapes cost, latency, and maintenance burden for years.

    What Makes a Voice Agent “Best” for Your Use Case

    There’s no single winner among the best ai voice agents on the market — the right choice depends on call volume, latency tolerance, data residency requirements, and how much engineering time you can dedicate to the stack. Before comparing vendors or open-source frameworks, it helps to break the problem into its component parts.

    Core Components of a Voice Agent Pipeline

    Every voice agent, regardless of vendor, is built from the same functional blocks:

  • Speech-to-text (STT) — converts the caller’s audio into text in near real time
  • Dialogue/reasoning layer — an LLM or rules engine that decides what to say next
  • Text-to-speech (TTS) — converts the response back into natural-sounding audio
  • Telephony or WebRTC transport — carries the audio between the caller and your backend
  • Orchestration layer — handles turn-taking, interruption detection, and session state
  • Latency budget matters more here than in almost any other AI application. Humans notice pauses over roughly 300-500ms in conversation, so every hop in this pipeline needs to be optimized, not just “eventually consistent.”

    Latency and Turn-Taking Considerations

    The best ai voice agents minimize round-trip latency by streaming audio at every stage rather than waiting for complete utterances. Streaming STT, streaming LLM token generation, and streaming TTS synthesis all need to be chained so the caller hears a response starting to form before the full reply has even been computed. If you’re evaluating a vendor or framework, ask specifically how they handle barge-in (the caller interrupting mid-response) and whether STT and TTS run concurrently with the reasoning step or block on it.

    Managed vs Self-Hosted Voice Agent Architectures

    This is the central infrastructure decision for anyone building a production voice product, and it mirrors the classic build-vs-buy tradeoff seen across the broader agentic AI tools landscape.

    Managed API Platforms

    Managed platforms bundle STT, LLM orchestration, and TTS behind a single API, which drastically reduces time-to-first-call. You trade control and per-minute cost for simplicity. This route makes sense for teams that need to ship fast and don’t want to operate telephony infrastructure themselves. For high-quality synthesized speech specifically, many teams pair a managed orchestration layer with a dedicated TTS provider like ElevenLabs, which offers low-latency streaming voices well suited to conversational use cases.

    Self-Hosted Pipelines

    Self-hosting gives you full control over the STT/TTS models, data handling, and cost structure, at the expense of operational complexity. A typical self-hosted stack runs open-source or licensed STT and TTS models behind a small orchestration service, deployed on a VPS or Kubernetes cluster you control. This is a natural fit if you’re already running infrastructure for how to build agentic AI workloads and want to keep voice in the same environment.

    A minimal self-hosted voice agent stack might look like this in Docker Compose:

    version: "3.9"
    services:
      stt:
        image: your-org/stt-service:latest
        ports:
          - "8001:8001"
        environment:
          - MODEL_SIZE=medium
        restart: unless-stopped
    
      orchestrator:
        image: your-org/voice-orchestrator:latest
        ports:
          - "8000:8000"
        depends_on:
          - stt
          - tts
        environment:
          - LLM_ENDPOINT=http://llm:9000
        restart: unless-stopped
    
      tts:
        image: your-org/tts-service:latest
        ports:
          - "8002:8002"
        restart: unless-stopped
    
      llm:
        image: your-org/llm-runtime:latest
        ports:
          - "9000:9000"
        restart: unless-stopped

    If you need a refresher on how the depends_on, restart policies, and networking in that file actually behave, the Docker Compose vs Dockerfile comparison covers the fundamentals well.

    Best AI Voice Agents for Customer Support Use Cases

    Customer support is the most common production deployment for voice agents, and it’s where the tradeoffs between managed and self-hosted approaches become concrete. Support calls tend to have predictable intents (billing, order status, troubleshooting), which makes them a good fit for a constrained dialogue design rather than an open-ended LLM conversation.

    Designing for Predictable Intents

    Rather than letting the LLM freely improvise, most production support agents constrain the model with a defined set of intents and a retrieval layer over your knowledge base. This reduces hallucination risk and keeps responses on-brand. If you’re building this pattern from scratch, it’s worth reviewing the deployment guide for customer service AI agents and the more general AI voice agents for customer service walkthrough, both of which cover the intent-routing and escalation patterns in more depth.

    Escalation and Human Handoff

    No voice agent should trap a caller in an infinite loop. A production-grade design always includes a clear escalation path — either a confidence threshold on intent classification or an explicit “talk to a human” trigger phrase — that hands the call off to a live agent with full conversation context attached. Skipping this is one of the most common reasons voice agent deployments get poor reception from end users.

    Infrastructure and Hosting for Voice Agent Deployments

    Voice workloads have different infrastructure characteristics than typical web APIs: they’re latency-sensitive, often require persistent WebSocket or RTP connections, and benefit from being deployed close to your telephony provider’s points of presence.

    Choosing Compute for Real-Time Audio Processing

    If you’re running STT/TTS models yourself rather than calling a managed API, GPU access becomes relevant for larger models, though CPU-only deployments are workable for smaller, quantized models at modest call volumes. A VPS provider with predictable network performance and the ability to scale vertically is often a better starting point than a fully managed serverless platform, since voice sessions are long-lived and don’t fit a request/response billing model cleanly. DigitalOcean and Hetzner are both reasonable starting points for this kind of workload, offering predictable pricing for always-on compute.

    Networking and Session Persistence

    Because voice sessions are stateful and long-lived, your load balancer and reverse proxy configuration need to support sticky sessions or direct WebSocket passthrough rather than round-robin request distribution. If you’re fronting your voice service with Cloudflare, the Cloudflare Page Rules guide covers some of the routing behavior you’ll need to account for when proxying long-lived connections.

    Evaluating Vendors and Frameworks

    When comparing the best ai voice agents platforms and open-source frameworks, evaluate them against a consistent checklist rather than marketing copy:

  • Does the platform support streaming at every stage of the pipeline, not just batch transcription?
  • What’s the documented median latency from end-of-utterance to first audio byte back?
  • Can you bring your own LLM, or are you locked into their reasoning layer?
  • How is call audio stored, and for how long — this matters for compliance in regulated industries?
  • What happens during a network blip — does the session recover gracefully or drop the call?
  • Framework Lock-In and Portability

    Some platforms tightly couple their STT, LLM, and TTS components, making it hard to swap out one piece later. Others expose each stage as an independently configurable service. If you expect to iterate on voice quality or switch reasoning models over time, prioritize frameworks with clean separation between these layers. This is the same architectural principle that shows up in workflow automation tools — see the n8n vs Make comparison for a similar discussion of coupling versus modularity in a different context.

    Monitoring and Reliability for Production Voice Agents

    Once a voice agent is live, observability becomes critical, since a silent failure in a phone call is far more disruptive to a user than a failed API request they can retry.

    Logging and Debugging Conversational Sessions

    Every turn of a voice conversation should be logged with timestamps for each pipeline stage (STT latency, LLM latency, TTS latency) so you can identify bottlenecks after the fact. If your orchestration layer runs in containers, the patterns in the Docker Compose logs guide apply directly — structured, timestamped logs per service make it far easier to reconstruct what happened during a problematic call.

    Alerting on Degraded Call Quality

    Track metrics like average turn latency, barge-in frequency, and call abandonment rate as leading indicators of pipeline health. A sudden increase in average latency often points to a saturated STT or LLM backend before it shows up as a full outage, giving you a window to scale up before calls start failing outright.

    Here’s a minimal example of checking a self-hosted orchestrator’s health endpoint from a monitoring script:

    #!/bin/bash
    ENDPOINT="http://localhost:8000/health"
    STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$ENDPOINT")
    
    if [ "$STATUS" -ne 200 ]; then
      echo "Voice orchestrator unhealthy: HTTP $STATUS"
      exit 1
    fi
    
    echo "Voice orchestrator healthy"


    Recommended: Ready to put this into practice? ElevenLabs is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    What’s the difference between a voice agent and a traditional IVR system?
    A traditional IVR routes callers through a fixed decision tree using DTMF tones or basic keyword matching. A modern voice agent uses streaming speech recognition and an LLM-based reasoning layer to handle open-ended natural language, making the interaction feel like a real conversation rather than a menu.

    Do I need a GPU to self-host a voice agent?
    Not necessarily. Smaller, quantized STT and TTS models can run acceptably on CPU for moderate call volumes, though larger models or high concurrency will benefit from GPU acceleration. Start with your expected call volume and latency requirements, then benchmark before committing to specific hardware.

    How do the best ai voice agents handle interruptions (barge-in)?
    They run STT continuously in the background even while TTS is playing, and cancel the current response as soon as new speech is detected from the caller. This requires the orchestration layer to support mid-stream cancellation on both the LLM and TTS calls, not just at the start of a turn.

    Is a managed API or self-hosted pipeline better for a small team?
    For most small teams, a managed API is the faster and lower-risk starting point, since it avoids the operational overhead of running STT/TTS/LLM services yourself. Self-hosting becomes more attractive once call volume or data residency requirements make the per-minute cost of managed platforms harder to justify.

    Conclusion

    There’s no universal answer to which of the best ai voice agents you should deploy — the right choice depends on your latency requirements, call volume, compliance constraints, and how much operational overhead your team can absorb. Managed platforms get you to production fastest, while self-hosted pipelines offer more control at the cost of running your own STT, LLM, and TTS infrastructure. Whichever path you choose, treat latency budgeting, escalation design, and observability as first-class requirements from day one, not an afterthought once calls are already flowing. For deeper reference on the underlying protocols, the WebRTC specification and Kubernetes documentation are both worth bookmarking if you’re deploying voice infrastructure at scale.

  • Marketing Ai Agents

    Marketing AI Agents: A DevOps Guide to Self-Hosted Deployment

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    Marketing AI agents are becoming a standard part of how growth and content teams operate, but most of the write-ups on the topic skip the part that actually matters to engineers: how do you deploy, run, and maintain these systems reliably? This guide covers marketing AI agents from an infrastructure perspective — how they’re architected, what they need to run in production, and how to keep them observable and secure once they’re live.

    If you’ve deployed a chatbot, a webhook-driven automation, or a scheduled data pipeline before, you already have most of the mental model you need. Marketing AI agents just combine those patterns with a language model in the decision loop, which introduces some new operational considerations around cost, latency, and failure handling.

    What Are Marketing AI Agents, Technically?

    A marketing AI agent is a piece of software that uses a large language model (LLM) to make decisions and take actions across marketing workflows — things like drafting social posts, segmenting leads, personalizing email sequences, monitoring brand mentions, or generating ad copy variants. Unlike a static automation script, an agent typically has:

  • A goal or instruction set it’s working toward (e.g. “draft three email variants for this campaign and flag any that mention pricing”)
  • Tool access — the ability to call APIs (CRM, email platform, analytics, ad platform) rather than just producing text
  • Some form of memory or state, so it can track what it already did across a session or across scheduled runs
  • A feedback or evaluation loop, ideally with a human or a rule-based gate before anything reaches a live audience
  • The important distinction for infrastructure purposes is that marketing AI agents are not a single deployable artifact — they’re a pipeline. You have an orchestration layer, one or more LLM calls, integrations with third-party marketing tools, and a persistence layer to track state. Each of those pieces has its own failure modes, and treating the whole thing as “the AI” obscures where things actually break.

    Rule-Based vs. LLM-Driven Agents

    Not every task in a marketing workflow needs an LLM call. A useful pattern — one we rely on heavily in our own automation stack — is to default to rule-based logic and only invoke an LLM when the task genuinely requires natural-language generation or judgment calls that rules can’t express. This keeps costs predictable and makes debugging far easier, since a rule-based branch either matched or it didn’t, while an LLM call can behave differently on every run even with the same input.

    Single-Agent vs. Multi-Agent Pipelines

    Simple use cases (e.g. “summarize this week’s campaign performance into a Slack message”) are well served by a single agent making one or two tool calls. More complex use cases — full content production pipelines that go from keyword research through drafting, SEO scoring, and publishing — tend to work better as a chain of narrow, single-purpose agents or scripts, each owning one stage and handing off state explicitly. This mirrors standard microservice design: smaller, testable units beat one large opaque process.

    Architecture Patterns for Deploying Marketing AI Agents

    Most production-grade marketing AI agent deployments share a similar shape regardless of the specific use case:

    1. A trigger — a schedule, a webhook, or a queue consumer
    2. An orchestrator — the process that owns the workflow logic and calls out to the LLM and any tools
    3. Persistent state — a database or file store tracking what’s been done, to make the pipeline resumable and idempotent
    4. Integrations — CRM, email, ad platform, or CMS APIs
    5. Observability — logs, alerts, and a way to audit what the agent actually did

    This is architecturally close to the workflow-automation pattern used by tools like n8n, and if you’re already running n8n for other automations, wiring marketing AI agents into the same instance can be a reasonable starting point rather than standing up a separate service. See our comparison of building AI agents with n8n if you’re evaluating that route.

    Running Agents on a VPS vs. Managed Platforms

    You can run marketing AI agents on a managed SaaS platform, but for teams that want full control over data, cost, and integration depth, self-hosting on a VPS is often the more practical long-term choice. A basic self-hosted stack typically needs:

  • A container runtime (Docker is the default choice for most teams)
  • A process supervisor or orchestrator (Docker Compose for small deployments, systemd units for background workers)
  • A persistence layer (Postgres or SQLite depending on scale)
  • Outbound network access to the LLM provider and any marketing APIs you’re integrating
  • For most small-to-mid-scale marketing AI agent deployments, a modest VPS is enough — you’re rarely CPU-bound, since the LLM inference itself happens remotely unless you’re self-hosting a model. Providers like DigitalOcean or Hetzner both offer VPS tiers that are sufficient for running an orchestration layer plus a small database.

    A Minimal Docker Compose Setup

    Here’s a minimal example of a Docker Compose file for a marketing AI agent worker plus its state database:

    version: "3.9"
    services:
      agent-worker:
        build: ./agent
        restart: unless-stopped
        environment:
          - LLM_API_KEY=${LLM_API_KEY}
          - DATABASE_URL=postgres://agent:agent@db:5432/agent_state
          - POLL_INTERVAL=60
        depends_on:
          - db
    
      db:
        image: postgres:16
        restart: unless-stopped
        environment:
          - POSTGRES_USER=agent
          - POSTGRES_PASSWORD=agent
          - POSTGRES_DB=agent_state
        volumes:
          - agent_db_data:/var/lib/postgresql/data
    
    volumes:
      agent_db_data:

    If you’re new to managing secrets in a setup like this, our Docker Compose secrets guide and Docker Compose env variables guide both cover patterns for keeping API keys out of your version-controlled files.

    Choosing Marketing AI Agents Based on Actual Use Cases

    It’s easy to over-scope a marketing AI agent project. Before building or buying, it’s worth being specific about which task the agent is solving, because “a marketing AI agent” can mean very different systems depending on the job:

  • Content drafting agents — generate first-draft copy for blog posts, ad variants, or email sequences, usually with a human review step before publishing
  • Segmentation and targeting agents — read CRM or analytics data and propose audience segments or send-time recommendations
  • Monitoring agents — watch brand mentions, competitor activity, or campaign performance and surface anomalies
  • Customer-facing agents — chat or voice agents that interact directly with prospects; these carry different risk and compliance considerations than internal-only agents
  • Customer-facing agents in particular deserve extra scrutiny before deployment, since mistakes are visible externally rather than caught in an internal review queue. If you’re building one of those, our guide on customer service AI agents covers the self-hosted deployment side in more depth, and it’s worth also reading up on AI agent security before putting anything customer-facing into production.

    Evaluating Vendor vs. Self-Built Marketing AI Agents

    If you’re comparing an off-the-shelf marketing AI agent platform against building your own, weigh these factors:

  • Data ownership — does the vendor’s platform require sending your CRM or customer data through their infrastructure?
  • Customization ceiling — can you actually adjust the agent’s logic when a workflow doesn’t fit the vendor’s assumptions, or are you stuck with their defaults?
  • Cost model — per-seat pricing vs. usage-based LLM costs behave very differently at scale
  • Exit cost — how hard is it to migrate off the platform if it doesn’t work out?
  • There’s no universally correct answer here; a small team validating a new channel is usually better served by a vendor tool, while a team with existing DevOps capacity and specific integration needs often gets better long-term value from a self-hosted, code-owned pipeline.

    Operating Marketing AI Agents in Production

    Once a marketing AI agent is live, the operational concerns look a lot like running any other background service, with a few additions specific to LLM-driven systems.

    Cost and Rate Limit Management

    LLM API calls are metered, and marketing workflows can generate a surprising volume of calls once they’re running on a schedule across many campaigns or content pieces. Track token usage per run, set a hard budget alert, and prefer batching where the workflow allows it — generating five ad variants in one call is cheaper and often more consistent than five separate calls. Consult your provider’s own documentation for current rate limits and pricing structure, such as the OpenAI API documentation, rather than relying on a cached number in your own notes.

    Observability and Auditing

    Because an LLM’s output isn’t fully deterministic, logging matters more here than in a typical deterministic pipeline. At minimum, log:

  • The exact prompt/input sent to the model
  • The raw output received
  • Any downstream action taken as a result (email sent, CRM field updated, post published)
  • Timestamps and the triggering event
  • This gives you an audit trail if a piece of generated content turns out to be wrong or off-brand, and it makes debugging failed runs far faster than trying to reproduce the issue after the fact.

    Idempotency and Failure Handling

    Marketing AI agents that write to external systems (a CRM, an email platform, a CMS) need to be idempotent by design — a retried run should never send a duplicate email or publish a duplicate post. Claim-and-verify patterns work well here: mark a task as claimed before starting, verify state before acting, and re-check after writing rather than trusting a webhook’s own success response. This is the same discipline used in any reliable publishing pipeline, and it applies directly to marketing AI agents that push content live.


    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Do marketing AI agents replace a marketing team?
    No. Most production deployments use marketing AI agents to draft, filter, or surface information faster, with a human still reviewing anything customer-facing before it ships. Fully autonomous customer-facing agents exist but carry meaningfully higher review and monitoring requirements.

    What’s the difference between a marketing AI agent and a marketing automation tool?
    Traditional marketing automation follows fixed if-this-then-that rules. Marketing AI agents add an LLM into the decision loop, letting the system generate content or make judgment calls that a rules engine can’t express — at the cost of less predictable, harder-to-test behavior.

    Can I self-host marketing AI agents instead of using a SaaS platform?
    Yes. A self-hosted stack usually needs a container runtime, a persistence layer, and outbound access to your LLM provider and marketing integrations. This gives you more control over data and cost but requires you to own the operational burden — monitoring, retries, and security patching.

    How do I control LLM costs in a marketing AI agent pipeline?
    Default to rule-based logic wherever it’s sufficient, batch LLM calls when possible, cache repeated prompts, and set hard usage alerts with your provider. Reserve the most expensive model tiers for tasks that genuinely need stronger reasoning.

    Conclusion

    Marketing AI agents are a genuinely useful addition to a marketing team’s toolkit, but they succeed or fail on the same fundamentals as any other production system: clear task scoping, idempotent writes, good observability, and sane cost controls. Whether you self-host on a VPS or adopt a managed platform, treat the LLM call as one component in a larger pipeline rather than the whole system, and build in a review step anywhere the agent’s output reaches customers directly. Teams that already run infrastructure like n8n or Docker Compose stacks have a natural head start, since the orchestration and deployment patterns carry over directly. For further reading on the underlying container tooling referenced throughout this guide, see the official Docker documentation.

  • Customizable Ai Agents

    Customizable AI Agents: A DevOps Guide to Building Flexible Automation

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    Customizable AI agents let engineering teams shape how autonomous automation behaves instead of accepting a fixed, one-size-fits-all workflow. This guide walks through the architecture, tooling, and deployment patterns you need to build customizable AI agents that fit into an existing DevOps stack rather than fighting against it.

    Most teams start with a hosted chatbot or a rigid no-code agent builder, then hit a wall: the tool can’t call their internal APIs, can’t respect their access controls, or can’t be versioned like the rest of their infrastructure. Customizable AI agents solve this by treating the agent as just another service in your stack — something you build, containerize, test, and deploy the same way you would any other microservice.

    Why Customizable AI Agents Matter for DevOps Teams

    A generic AI agent is easy to demo and hard to operate. It works fine for a single use case shown in a vendor’s marketing video, but real production environments have constraints: internal authentication schemes, rate-limited third-party APIs, compliance requirements around what data can leave your network, and existing observability tooling that every other service already reports into.

    Customizable AI agents address this by exposing the pieces that matter — prompts, tool definitions, memory backends, model selection, and execution limits — as configuration rather than hardcoded behavior. That configurability is what makes an agent maintainable by a team, not just a single engineer who built it.

    Configuration Over Hardcoding

    The core principle behind any customizable AI agent is separating “what the agent can do” from “how it’s currently configured to behave.” Concretely, this means:

  • Tool/function definitions live in a registry file, not inline in code
  • System prompts are loaded from external files or a config store, not string-literals buried in application logic
  • Model provider and model name are environment variables, not constants
  • Rate limits, timeouts, and retry policy are configurable per-tool
  • This pattern mirrors how you’d already manage a Dockerized application — see Docker Compose Env: Manage Variables the Right Way for the same idea applied to container configuration. An agent that reads its personality, tools, and limits from environment and config files can be redeployed for a new use case without a code change.

    Common Failure Modes of Rigid Agents

    Teams that skip customizability tend to hit the same three problems repeatedly: the agent can’t be restricted to a subset of tools per environment (so a staging agent has production-level access), the agent’s prompt can’t be iterated on without a full redeploy, and there’s no way to swap the underlying model provider without rewriting the integration layer. Building customizable AI agents from day one avoids all three.

    Core Architecture for Customizable AI Agents

    A production-ready customizable agent generally has four independent layers: the orchestration loop, the tool layer, the memory/state layer, and the model provider abstraction. Keeping these layers decoupled is what actually delivers on the promise of customizable AI agents — you can swap any one layer without touching the others.

    # agent-config.yaml — example customizable agent definition
    agent:
      name: ops-assistant
      model:
        provider: anthropic
        name: claude-sonnet
        temperature: 0.2
      tools:
        - name: query_metrics
          enabled: true
          timeout_seconds: 10
        - name: restart_service
          enabled: false   # disabled in this environment on purpose
      memory:
        backend: redis
        ttl_seconds: 3600
      limits:
        max_steps: 8
        max_tokens_per_run: 4000

    This kind of declarative config is the difference between an agent you can hand off to another engineer and one that only the original author understands.

    Tool Registries and Permission Scopes

    Every tool the agent can call should be declared explicitly, with its own enable/disable flag and its own permission scope. This is not just good hygiene — it’s the mechanism that lets you run the same agent codebase in three different modes (read-only in staging, full-write in production, sandboxed in a demo environment) purely through configuration. If you’re already running n8n alongside your agent stack, the same idea shows up there too — see How to Build AI Agents With n8n: Step-by-Step Guide for a no-code take on tool scoping.

    Swappable Model Providers

    Hardcoding a specific model SDK call throughout your codebase is the single most common mistake that makes an agent hard to customize later. Wrap model calls behind a thin abstraction (a single function or class) so switching between providers — or between model versions from the same provider — is a config change, not a refactor. Keeping an eye on OpenAI API Pricing: A Developer’s Cost Guide 2026 or your provider’s equivalent is much easier when the provider itself is a config value.

    State and Memory Backends

    Customizable agents need customizable memory too. A short-lived support agent might only need in-process memory scoped to a single conversation; a long-running ops agent might need a Redis or Postgres-backed store that survives restarts. If you’re pairing an agent with Postgres for persistent state, Postgres Docker Compose: Full Setup Guide for 2026 covers the container setup you’ll need.

    Deploying Customizable AI Agents With Docker Compose

    Once the agent’s layers are separated, deployment looks like any other multi-container application. A typical stack pairs the agent process with a memory backend, a reverse proxy, and whatever internal APIs it needs to call.

    # minimal deploy loop for a customizable ai agent stack
    docker compose pull
    docker compose up -d --build
    docker compose logs -f agent

    Keep secrets — model API keys, internal service tokens — out of the compose file itself and out of the agent’s config. Use a .env file that’s excluded from version control, following the same pattern described in Docker Compose Secrets: Secure Config Management Guide.

    Environment-Specific Overrides

    Docker Compose’s override file mechanism is a natural fit for agent customization: a base docker-compose.yml defines the shared shape of the stack, and docker-compose.override.yml (or environment-specific variants) toggles which tools are enabled, which model tier is used, and how aggressive the rate limits are. This keeps a staging agent honest about its reduced permissions without duplicating the entire stack definition.

    Rebuilding After Prompt or Tool Changes

    Because prompts and tool registries usually live in mounted config files rather than baked into the image, most changes to a customizable agent don’t require a rebuild at all — just a restart. When you do change the underlying code (a new tool implementation, a dependency bump), Docker Compose Rebuild: Complete Guide & Best Tips covers the difference between a plain restart and a full rebuild, which matters for keeping deploys fast.

    Customization Patterns That Actually Scale

    Not every customization point is worth exposing. Teams that try to make everything configurable end up with a config schema nobody understands. Focus on the handful of dimensions that genuinely differ across your use cases or environments.

    Prompt Layering Instead of Monolithic Prompts

    Rather than one giant system prompt per agent, split it into layers: a base layer describing tone and safety constraints (rarely changed), a role layer describing the agent’s specific job (changed per use case), and a context layer injected at runtime (changed per request). This layered approach makes customizable AI agents easier to audit — you can diff just the role layer between two agent variants instead of reading two full prompts side by side.

    Per-Tenant Configuration

    If you’re running the same agent codebase for multiple internal teams or external customers, a per-tenant config record (stored in your database, keyed by tenant ID) that overrides tool availability, rate limits, and model tier is far more maintainable than forking the codebase per tenant. This is the same multi-tenancy pattern used in most SaaS backends, just applied to agent behavior instead of application features.

    Guardrails as Configuration, Not Afterthoughts

    Guardrails — what the agent is allowed to do without human approval, what actions require confirmation, what inputs are rejected outright — should be part of the same config surface as everything else, not a separate bolt-on system. A customizable agent that lets you tighten or loosen guardrails per environment is much easier to trust in production than one where guardrails are hardcoded checks scattered through the code.

    Monitoring and Debugging Customizable AI Agents

    An agent that’s fully customizable but invisible to your existing observability stack is still a liability. Every tool call, model call, and decision point should emit structured logs the same way any other service in your infrastructure does.

  • Log every tool invocation with its inputs, outputs, and duration
  • Emit a trace ID per agent run so a multi-step execution can be reconstructed after the fact
  • Track token usage and cost per run, not just per day, so a runaway loop is caught immediately
  • Alert on tool call failures separately from model call failures — they usually have different root causes
  • If your agent runs alongside a broader automation pipeline, the debugging discipline from Docker Compose Logs: The Complete Debugging Guide applies directly — the same “read the logs before you guess” mindset holds whether you’re debugging a container or an agent’s decision trace.

    Setting Sensible Execution Limits

    Every customizable agent needs hard limits: a maximum number of reasoning steps, a maximum token budget per run, and a timeout on the overall execution. These aren’t optional extras — without them, a single malformed input can turn into an expensive, runaway loop. Expose these limits as configuration so different environments (a cheap staging agent vs. a production agent with a larger budget) can set them independently.

    Where to Host the Agent

    Customizable agents that call out to external APIs and maintain persistent state benefit from running on infrastructure you fully control rather than a locked-down serverless platform with execution time limits. A small VPS running Docker Compose is usually sufficient for a single agent or a small fleet of them. Providers like DigitalOcean or Vultr offer VPS tiers well suited to this kind of workload, and both integrate cleanly with a standard Docker Compose deployment.


    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    What makes an AI agent “customizable” rather than just configurable?
    Configurability usually refers to simple settings like temperature or a system prompt string. A truly customizable AI agent goes further — its tools, memory backend, model provider, and guardrails are all swappable independently, without touching the core orchestration code.

    Do customizable AI agents require a specific framework?
    No. You can build one directly on top of a model provider’s SDK — see Kubernetes.io and Docker’s documentation for the underlying container orchestration primitives most agent deployments rely on. Frameworks can speed up development, but the customization principles (separating config from code, layering prompts, scoping tools) apply regardless of framework.

    How do I prevent a customizable agent from being over-permissioned in production?
    Use explicit per-environment tool registries with enable/disable flags, and never let a single config file be shared unchanged across staging and production. Treat tool permissions the same way you’d treat database credentials — scoped, environment-specific, and reviewed before deploy.

    Can I run multiple customizable agents from the same codebase?
    Yes — this is one of the main benefits of separating configuration from code. A single codebase with different config files (different prompts, tools, and limits) can serve multiple distinct agents, which is far easier to maintain than forking the code for each new use case.

    Conclusion

    Building customizable AI agents is less about picking the right model and more about disciplined separation of concerns: config apart from code, tools apart from orchestration, and guardrails apart from business logic. Teams that apply the same rigor they already use for container deployments — versioned config, environment-specific overrides, structured logging — end up with agents that are genuinely maintainable, not just impressive in a first demo. Start with a small, well-scoped set of customization points, deploy it the same way you’d deploy any other service, and expand the configuration surface only as real use cases demand it.

  • Ai Agents For Finance

    AI Agents For Finance: A DevOps Guide to Self-Hosted Deployment

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    Finance teams are under constant pressure to close books faster, catch anomalies earlier, and answer stakeholder questions without waiting on a data analyst’s queue. AI agents for finance are increasingly the mechanism teams use to close that gap: autonomous or semi-autonomous systems that can pull data from ledgers, reconcile transactions, draft reports, and flag exceptions with minimal human prompting on each step. This guide is written for the engineers who actually have to build, deploy, and operate these systems — not for the business stakeholders who ask for them.

    We’ll cover the architecture patterns that work in production, the infrastructure decisions you’ll need to make, and the operational discipline required to keep an autonomous financial system trustworthy.

    What Makes AI Agents For Finance Different From General-Purpose Agents

    A generic chatbot agent can be wrong and the cost is a bad answer. An agent operating on financial data that reconciles accounts, categorizes transactions, or drafts compliance filings carries a much higher cost of error. That changes the engineering requirements substantially.

    Determinism and Auditability Requirements

    Unlike a customer support bot where a slightly-off answer is tolerable, financial workflows typically require:

  • A full audit trail of every action the agent took, including the exact data it read and the exact output it produced
  • Deterministic, reproducible steps wherever possible — the agent should not “guess” at a reconciliation match when a rules-based lookup would do
  • Clear separation between read-only analysis actions and any action that writes to a ledger or triggers a payment
  • Human approval gates before anything financially irreversible happens
  • This is the single biggest mental shift for teams moving from building AI agents for finance and moving from experimentation to production: you are not optimizing for the most impressive demo, you are optimizing for the most boring, predictable, reviewable pipeline that still saves real time.

    Data Sensitivity and Access Control

    Financial data is regulated data in most jurisdictions. Any agent architecture needs to treat credentials to your accounting system, bank feeds, or ERP the same way you’d treat production database credentials — least privilege, rotated regularly, and never embedded directly in prompts or logs. If you’re already running other automation on a VPS, the same Docker Compose Secrets patterns you use for application secrets apply directly here.

    Core Architecture Patterns for AI Agents For Finance

    Most production-grade financial agent systems converge on a handful of architectural patterns rather than a single “agent does everything” design.

    Orchestrator + Specialist Agent Pattern

    Rather than building one large agent that tries to handle invoice matching, expense categorization, and forecasting all in one prompt, most working systems split responsibilities:

  • An orchestrator agent that receives a task, decides which specialist to invoke, and stitches results together
  • A reconciliation specialist that only handles matching transactions across two data sources
  • A categorization specialist that only classifies line items against a chart of accounts
  • A reporting specialist that only formats and summarizes already-verified data
  • This separation keeps each agent’s prompt small, testable, and easier to evaluate independently — a categorization agent’s accuracy can be measured against a labeled dataset without needing to also validate the whole pipeline.

    Tool-Calling Over Free-Form Generation

    For anything involving numbers, prefer giving the agent a tool (a function that queries your database or calls an API) over asking it to generate the number itself from context. Large language models are not reliable calculators, and financial arithmetic needs to be exact. A well-designed agent calls a get_account_balance(account_id) tool and reports what it returns, rather than summing figures itself inside free text.

    Human-in-the-Loop Checkpoints

    Any workflow that touches money movement — approving a payment, closing a period, filing a return — should route through an explicit approval step rather than fully autonomous execution. This is not a limitation of current AI agents for finance; it’s a design choice that keeps the system operable and defensible during an audit.

    Deploying AI Agents For Finance on Self-Hosted Infrastructure

    Many teams start with a managed agent platform and later move to self-hosting once data residency, cost, or customization requirements grow. If you’re evaluating that path, the same self-hosting fundamentals that apply to building agentic AI systems generally apply here, with additional attention paid to network isolation for financial data.

    A Minimal Docker Compose Setup

    A typical self-hosted stack for a financial agent pairs a workflow orchestration layer (such as n8n) with a vector store for retrieval and a Postgres database for transaction storage. Here’s a minimal starting point:

    version: "3.8"
    services:
      orchestrator:
        image: n8nio/n8n:latest
        restart: unless-stopped
        environment:
          - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
          - DB_TYPE=postgresdb
          - DB_POSTGRESDB_HOST=postgres
          - DB_POSTGRESDB_DATABASE=n8n
        ports:
          - "127.0.0.1:5678:5678"
        depends_on:
          - postgres
        volumes:
          - n8n_data:/home/node/.n8n
    
      postgres:
        image: postgres:16
        restart: unless-stopped
        environment:
          - POSTGRES_USER=${POSTGRES_USER}
          - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
          - POSTGRES_DB=n8n
        volumes:
          - pg_data:/var/lib/postgresql/data
    
    volumes:
      n8n_data:
      pg_data:

    Note that the orchestrator port is bound to 127.0.0.1 only — financial automation endpoints should never be exposed directly to the public internet without a reverse proxy and authentication layer in front of them. If you’re new to this pattern, the n8n self-hosted installation guide walks through the full setup, and Postgres Docker Compose covers hardening the database layer specifically.

    Choosing Where to Run It

    Financial workloads often have data residency requirements, so pick a VPS provider and region deliberately rather than defaulting to whatever’s cheapest. If you need a straightforward, well-documented provider to start with, DigitalOcean is a common choice for teams that want predictable pricing and a simple control panel; for teams optimizing hard for cost-per-core, Hetzner is worth comparing against.

    Environment and Secrets Management

    Credentials for accounting platforms (QuickBooks, Xero, NetSuite, Stripe) should live in environment variables injected at container startup, never committed to a repository or hardcoded into a workflow definition. The Docker Compose Env guide covers the mechanics of doing this correctly, including keeping .env files out of version control.

    Building the Reconciliation and Categorization Pipeline

    The most common practical use case for AI agents for finance is automated transaction reconciliation and categorization — matching bank feed data against internal ledger entries and assigning categories consistently.

    Designing the Matching Logic

    Before reaching for an LLM at all, implement deterministic matching first: exact amount + date + counterparty matches should resolve with plain rules, no model call needed. Reserve the agent for the harder cases — fuzzy matches, split transactions, or ambiguous vendor names — where a rules engine alone falls short. This keeps costs down and keeps the majority of your transaction volume fully deterministic and auditable.

    Handling Ambiguous Cases

    When the agent can’t confidently match or categorize a transaction, the correct behavior is to flag it for human review with its reasoning attached, not to guess and move on. A categorization agent that silently mis-tags 2% of transactions creates more cleanup work than the automation saves. Logging every agent decision alongside its input data — similar to how you’d inspect container behavior with Docker Compose Logs — makes it possible to audit these decisions after the fact.

    Testing Against Historical Data

    Before trusting an agent with live transaction data, run it against a labeled historical dataset (a prior quarter’s already-reconciled books) and measure precision and recall on categorization decisions. This gives you a concrete baseline to compare against every time you change the prompt, the model, or the tool definitions — treat prompt changes with the same rigor you’d apply to a code change that touches production data.

    Monitoring, Logging, and Governance for Financial Agents

    Once an agent system is live, operational discipline matters more than the initial build.

    What to Log

    At minimum, persist for every agent action:

  • The input data the agent received (transaction IDs, not full raw dumps, to limit sensitive data sprawl in logs)
  • The tool calls it made and their results
  • The final decision or output produced
  • Whether a human approved, rejected, or modified that output
  • Alerting on Drift

    Categorization accuracy can silently degrade as your chart of accounts changes or as new vendors appear that the agent hasn’t seen before. Set up a periodic job that samples a percentage of agent decisions for manual review and alerts if the disagreement rate crosses a threshold you’ve set for your own risk tolerance.

    Access Auditing

    Treat the agent’s own service account the same way you’d treat any privileged application identity — review what it can read and write on a regular cadence, and remove permissions it no longer needs as workflows evolve. The Docker Compose Volumes guide is useful background if your agent’s persistent state (approval queues, cached categorizations) lives in a mounted volume that also needs its own access review.


    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Do AI agents for finance need to be fully autonomous to be useful?
    No. Most production deployments intentionally keep a human approval step for anything that moves money or finalizes a filing. The value comes from automating the data-gathering, matching, and drafting work, not from removing human judgment on high-stakes decisions.

    Can I run AI agents for finance entirely on self-hosted infrastructure without sending data to a third-party LLM API?
    Yes, if you use a self-hosted or open-weight model. Many teams start with a hosted API for prototyping and later migrate to self-hosted inference once data residency or cost requirements justify the additional operational overhead.

    How do I prevent an agent from making an incorrect financial calculation?
    Give the agent tools that perform calculations against your actual data source rather than asking it to compute figures from text in its context window. Treat the model as a reasoning and orchestration layer, not a calculator.

    What’s the biggest operational risk with agentic finance automation?
    Silent drift — an agent that was accurate when deployed gradually becoming less accurate as your data changes, with nobody noticing until a reconciliation discrepancy surfaces weeks later. Regular sampling and review closes this gap.

    Conclusion

    AI agents for finance are most effective when treated as a disciplined engineering system rather than a black-box automation layer: deterministic where possible, tool-calling instead of free-form arithmetic, logged exhaustively, and gated by human approval before anything financially irreversible happens. Start with a narrow, well-scoped use case like reconciliation, measure it against historical data before trusting it with live transactions, and expand scope only once the operational monitoring around it is solid. For further reading on the underlying orchestration patterns, the n8n documentation and Docker Compose documentation are good starting references for the infrastructure layer this all runs on.

  • Telegram Bot Example

    Telegram Bot Example: A Practical Guide to Building Your First Bot

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    If you’re looking for a working telegram bot example to learn from, this guide walks through the full process: registering a bot, writing the code, deploying it with Docker, and running it reliably in production. Rather than a single toy snippet, you’ll get a complete telegram bot example you can adapt for real projects, along with the reasoning behind each design decision.

    Telegram bots are lightweight, event-driven services that talk to Telegram’s Bot API over HTTPS. They don’t require a browser, a phone number pool, or any special infrastructure beyond a server that can make and receive HTTP requests. That makes them a popular choice for DevOps notification systems, internal tooling, and lightweight customer-facing automation.

    Why Build a Telegram Bot

    Before diving into a telegram bot example, it’s worth understanding what problem this pattern actually solves. Telegram bots are commonly used for:

  • Sending deployment or CI/CD status notifications to a team channel
  • Triggering infrastructure actions (restart a service, pull logs, check disk space) from a chat interface
  • Building lightweight customer support or FAQ automation
  • Relaying alerts from monitoring systems (Prometheus, Grafana, uptime checkers)
  • Acting as a simple front-end for internal admin tools
  • Compared to building a full web dashboard, a Telegram bot is fast to stand up and requires no authentication UI — Telegram already handles identity via chat IDs and usernames. This is why so many infrastructure teams reach for a telegram bot example as their first automation project.

    Bots vs. Webhooks vs. Polling

    Telegram bots can receive updates two ways:

    1. Polling — the bot repeatedly calls getUpdates on the Bot API to check for new messages.
    2. Webhooks — Telegram pushes updates to a public HTTPS endpoint you control.

    Polling is simpler to run locally and behind NAT (no public IP required), while webhooks scale better and reduce latency for high-traffic bots. Most tutorials, including the telegram bot example below, start with polling because it avoids the need for a TLS certificate and a reachable domain during development.

    Registering Your Bot with BotFather

    Every Telegram bot starts with a registration step handled entirely inside Telegram itself, via a special bot called BotFather.

    Getting a Bot Token

    1. Open a chat with @BotFather in Telegram.
    2. Send /newbot and follow the prompts for a name and username (must end in bot).
    3. BotFather returns an API token — a string like 123456789:AAF.... This token is a secret; treat it the same way you’d treat a database password or an API key.
    4. Optionally, use /setdescription, /setuserpic, and /setcommands to configure how your bot appears to users.

    Never commit this token to source control. Store it as an environment variable or in a secrets manager, and rotate it via BotFather’s /revoke command if it ever leaks.

    A Minimal Telegram Bot Example in Python

    The most common starting point for a telegram bot example is a small Python script using the python-telegram-bot library, which wraps the raw Bot API in a friendlier interface.

    python3 -m venv venv
    source venv/bin/activate
    pip install python-telegram-bot --upgrade

    Here’s a minimal, working telegram bot example that responds to /start and echoes back any text message:

    import os
    from telegram import Update
    from telegram.ext import ApplicationBuilder, CommandHandler, MessageHandler, ContextTypes, filters
    
    BOT_TOKEN = os.environ["BOT_TOKEN"]
    
    async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
        await update.message.reply_text("Hello! Send me any message and I'll echo it back.")
    
    async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE):
        await update.message.reply_text(update.message.text)
    
    def main():
        app = ApplicationBuilder().token(BOT_TOKEN).build()
        app.add_handler(CommandHandler("start", start))
        app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, echo))
        app.run_polling()
    
    if __name__ == "__main__":
        main()

    Run it with BOT_TOKEN=<your-token> python3 bot.py, and the bot will start polling for updates immediately. This is the same architecture used by more advanced systems — a routing layer that matches incoming messages to handlers, similar in shape to command-routing seen in larger automation projects like n8n-based AI agent workflows.

    Adding Command Routing

    Real-world bots usually need more than one command. A slightly extended telegram bot example adds a routing table:

    COMMAND_HANDLERS = {
        "status": handle_status,
        "restart": handle_restart,
        "logs": handle_logs,
    }
    
    async def route_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
        command = update.message.text.split()[0].lstrip("/").lower()
        handler = COMMAND_HANDLERS.get(command)
        if handler:
            await handler(update, context)
        else:
            await update.message.reply_text("Unknown command.")

    This pattern — a dictionary mapping command names to functions — scales well for bots with a dozen or more commands and keeps each handler function small and testable.

    Restricting Access by Chat ID

    Most internal-tooling bots should only respond to a known chat ID, not the general public. This is a simple but important safeguard for any telegram bot example intended for infrastructure use:

    ALLOWED_CHAT_ID = int(os.environ["TG_CHAT_ID"])
    
    async def guarded_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
        if update.effective_chat.id != ALLOWED_CHAT_ID:
            return
        await update.message.reply_text("Authorized command received.")

    Without this check, anyone who discovers your bot’s username can message it and trigger handlers — a meaningful risk if any command touches infrastructure, like restarting a service or reading logs.

    Deploying the Bot with Docker

    Once your telegram bot example works locally, the next step is packaging it so it runs reliably and restarts automatically. Docker is a natural fit here, and the process closely mirrors deploying any long-running Python service.

    FROM python:3.12-slim
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    COPY bot.py .
    CMD ["python3", "bot.py"]

    A minimal docker-compose.yml keeps the bot token out of the image itself:

    services:
      telegram-bot:
        build: .
        restart: unless-stopped
        environment:
          - BOT_TOKEN=${BOT_TOKEN}
          - TG_CHAT_ID=${TG_CHAT_ID}

    If you’re new to Compose syntax or need to manage environment variables more carefully, see this guide on managing Docker Compose environment variables. For debugging a bot that isn’t responding, Docker Compose logs are usually the first place to look — docker compose logs -f telegram-bot will show you every incoming update and any stack traces.

    Running as a systemd Service (Non-Docker Alternative)

    If you’d rather not containerize a small bot, a systemd unit is a lightweight alternative that gives you automatic restarts and log integration with journalctl:

    [Unit]
    Description=Telegram Bot
    After=network.target
    
    [Service]
    ExecStart=/opt/telegram-bot/venv/bin/python3 /opt/telegram-bot/bot.py
    Restart=always
    EnvironmentFile=/opt/telegram-bot/.env
    User=telegrambot
    
    [Install]
    WantedBy=multi-user.target

    Both approaches — Docker Compose and systemd — achieve the same goal: a bot process that survives reboots and restarts automatically after a crash. Which one you pick usually comes down to whether the rest of your stack is already containerized.

    Handling Errors and Rate Limits

    A production-grade telegram bot example needs to account for two failure modes that toy examples usually skip: network errors and Telegram’s rate limits.

  • Wrap outgoing reply_text calls in a retry with backoff for transient network failures.
  • Respect Telegram’s per-chat and per-second rate limits — sending many messages in a tight loop will get throttled, and Telegram may return a retry_after value telling you how long to wait.
  • Log every incoming update and outgoing response somewhere durable (a file, or a service like the one described in this Docker Compose logging guide), so you can reconstruct what happened after an incident.
  • Catch and log exceptions inside handlers rather than letting one bad message crash the whole polling loop.
  • async def error_handler(update: object, context: ContextTypes.DEFAULT_TYPE):
        print(f"Update {update} caused error {context.error}")
    
    app.add_error_handler(error_handler)

    Extending the Bot: Webhooks for Production Scale

    Polling works fine for personal or low-traffic bots, but a webhook-based deployment reduces latency and avoids constant outbound polling requests once you’re running at any meaningful scale. Setting a webhook requires a public HTTPS endpoint:

    curl -X POST "https://api.telegram.org/bot${BOT_TOKEN}/setWebhook" \
      -d "url=https://yourdomain.com/telegram/webhook"

    If you’re already running a reverse proxy for other services, adding a webhook route for your bot is usually just one more location block or ingress rule. If you’re hosting on a VPS and need HTTPS termination, Cloudflare Page Rules or a similar edge configuration can simplify certificate management in front of your webhook endpoint.

    Choosing Where to Host Your Bot

    Whether you run polling or webhooks, the bot needs a stable place to live. A small, inexpensive VPS is usually sufficient — Telegram bots are not resource-intensive unless they’re doing heavy media processing. Providers like DigitalOcean or Hetzner offer small instances that comfortably run a bot alongside a few other lightweight services. If you’re also automating deployments or notifications around a broader workflow engine, it’s worth comparing this setup against self-hosting n8n, which can trigger Telegram messages as one step in a larger automation pipeline.

    Testing Your Bot Before Going Live

    Before pointing real users at a telegram bot example you’ve built, run through a short manual checklist:

  • Send /start and confirm the welcome message appears.
  • Send a message from an unauthorized chat ID and confirm it’s silently ignored (if you’ve added access control).
  • Kill the process mid-run and confirm your restart policy (Docker’s restart: unless-stopped or systemd’s Restart=always) brings it back.
  • Check logs after a forced crash to confirm errors are captured, not silently swallowed.
  • If using webhooks, verify the endpoint responds with a 200 status within Telegram’s timeout window, since slow responses can cause Telegram to retry and duplicate updates.
  • Automating some of this with a basic integration test — sending a message via the Bot API and asserting on the bot’s reply — catches regressions before they reach production.


    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Do I need a public IP address to run a Telegram bot?
    No, not if you use polling. Polling-based bots make outbound requests to Telegram’s servers, so they work fine behind NAT or on a machine with no inbound access. Webhooks, by contrast, require a publicly reachable HTTPS endpoint.

    Is the Bot API token the same as my personal Telegram account?
    No. The token BotFather issues is scoped entirely to the bot you created — it has no access to your personal account, contacts, or chats beyond conversations the bot itself is added to.

    Can a Telegram bot example like this be adapted for other chat platforms?
    The overall architecture — an event loop, a routing table for commands, and handler functions — transfers well to platforms like Slack or Discord, though each has its own API and authentication model, so the integration code itself isn’t portable.

    What’s the difference between python-telegram-bot and calling the Bot API directly with requests?
    python-telegram-bot handles update parsing, retries, and the polling/webhook loop for you, which is why most tutorials use it. Calling the raw HTTP API directly works too, and can be simpler for a bot with only one or two commands, but you’ll end up reimplementing parts of what the library already provides.

    Conclusion

    Building a working telegram bot example doesn’t require much infrastructure: a BotFather-issued token, a small script using a library like python-telegram-bot, and a reliable place to run it. The pattern scales naturally — start with polling and a single command handler locally, then move to Docker or systemd for reliability, and finally to webhooks if you need lower latency at higher volume. Whether you’re building a notification bot for a CI/CD pipeline or a lightweight support tool, the same core structure — token, handlers, deployment, monitoring — applies. For further reading on Telegram’s full command surface, see the official Telegram Bot API documentation, and for container deployment details, the Docker documentation covers image building and Compose configuration in depth.

  • Free Vps Hosting No Credit Card

    Free VPS Hosting No Credit Card: A Practical Guide for Developers

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    Looking for free VPS hosting no credit card required so you can test a project without handing over payment details? You’re not alone — many developers want a disposable Linux box to try out a script, learn Docker, or prototype an API without triggering a billing relationship first. This guide walks through what’s realistically available, how to evaluate providers claiming free VPS hosting no credit card, and how to get a usable box running quickly and securely.

    Before diving in, it’s worth setting expectations correctly: genuinely free, no-card, production-grade VPS hosting is rare, and most offers in this space are either extremely limited, time-boxed, or come with real tradeoffs. This article covers the realistic options, the technical setup once you have a box, and the security basics you need regardless of which provider you choose.

    Why “Free VPS Hosting No Credit Card” Is Hard to Find

    Most cloud providers ask for a credit card even on free tiers because it deters abuse — spam, crypto mining, and DDoS launch points are common problems with genuinely anonymous free compute. That’s why services like DigitalOcean, Linode, and Vultr typically require card verification even for trial credit, despite offering low entry prices once you do sign up.

    When you do find free VPS hosting no credit card offers, they usually fall into a few categories:

  • Free-tier cloud instances that only skip the card requirement for a short trial window
  • Community or educational programs (student packs, hackathon credits) with eligibility restrictions
  • Extremely limited-resource “forever free” tiers (shared CPU, capped bandwidth, no root access in some cases)
  • Sandbox/playground environments meant for learning, not hosting real workloads
  • Understanding which category a provider falls into will save you time before you commit to setting anything up.

    Realistic Expectations for Resource Limits

    Even when a provider genuinely offers free VPS hosting no credit card, expect modest specs: often 512MB-1GB RAM, a single shared vCPU, and a small amount of SSD storage. These boxes are fine for learning Linux administration, running a lightweight Node.js or Python service, or testing a Docker container — they are not suitable for production traffic, database-heavy workloads, or anything with uptime guarantees you actually depend on.

    Common Catches to Watch For

    Read the terms before you provision anything. Common restrictions on free VPS hosting no credit card offers include:

  • Automatic account suspension after a fixed number of days
  • No SLA and no guaranteed uptime
  • Restricted outbound ports (mail servers and certain proxy uses are frequently blocked)
  • IP addresses that are already on shared blocklists due to prior abuse by other free-tier users
  • Evaluating Providers Before You Sign Up

    Not every listing that promises “no credit card” is trustworthy, and some sites collect other personal data instead — phone number verification, ID uploads, or aggressive marketing opt-ins. Treat any offer of free VPS hosting no credit card the same way you’d treat any other unfamiliar signup: check for a real support channel, a clear terms-of-service page, and reviews outside the provider’s own marketing site.

    Checking for Root Access and SSH

    A VPS that doesn’t give you root/sudo access and SSH is really just managed hosting with extra steps. Before signing up, confirm the provider explicitly states you’ll get:

  • Full root or sudo access
  • SSH key-based login (not just a web console)
  • A public IP address you can bind services to
  • If any of these are missing, it may still be useful for learning, but it isn’t a general-purpose VPS in the way most developers mean the term.

    Verifying the Provider Isn’t a Resale Scheme

    Some “free VPS” listings are unauthorized resellers running services on top of a legitimate provider’s infrastructure, in violation of that provider’s terms. This is a real risk: your instance can disappear without notice if the underlying account gets suspended. Stick to providers that are transparent about how they fund the free tier — advertising, a freemium upgrade path, or an explicit sponsorship (student programs, open-source grants) are healthier signals than vague claims.

    Setting Up Your Free VPS Securely

    Once you’ve provisioned a box, whether it’s genuinely free VPS hosting no credit card or a trial credit on a paid platform, the initial hardening steps are the same regardless of provider.

    Basic SSH and Firewall Configuration

    Start by disabling password authentication and restricting SSH to key-based login only. A minimal sshd_config change and a basic firewall rule set go a long way:

    # Generate a key pair locally if you don't have one
    ssh-keygen -t ed25519 -C "vps-key"
    
    # Copy your public key to the server
    ssh-copy-id user@your-server-ip
    
    # On the server: disable password auth
    sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
    sudo systemctl restart sshd
    
    # Enable a basic firewall (Ubuntu/Debian)
    sudo ufw allow OpenSSH
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw enable

    This is the same baseline hardening you’d apply on any Linux box, free or paid — see the official OpenSSH documentation for the full set of sshd_config options.

    Installing Docker on a Constrained Free VPS

    Given how limited free VPS hosting no credit card instances usually are on RAM, running services in lightweight containers is often more practical than installing everything directly on the host. The official Docker installation guide covers the exact steps per distribution; a typical Ubuntu install looks like this:

    curl -fsSL https://get.docker.com -o get-docker.sh
    sudo sh get-docker.sh
    sudo usermod -aG docker $USER

    On a 512MB-1GB instance, keep an eye on memory usage — set explicit memory limits on containers so a single runaway process doesn’t crash the whole box:

    services:
      app:
        image: node:20-alpine
        deploy:
          resources:
            limits:
              memory: 256M
        ports:
          - "3000:3000"

    If you later outgrow the free tier and want persistent storage or multiple services, our guide on Docker Compose volumes and Docker Compose environment variables covers the next steps for a more durable setup.

    What to Actually Run on a Free, No-Card VPS

    Given the resource and reliability limits, free VPS hosting no credit card is best treated as a learning and prototyping environment rather than production infrastructure.

    Good Fits

  • Learning Linux server administration, systemd, and basic networking
  • Running a small self-hosted tool for personal use (a link shortener, a bookmark manager)
  • Testing a Docker Compose stack before deploying it somewhere more durable
  • Practicing CI/CD deployment scripts against a disposable target
  • Poor Fits

  • Anything customer-facing with an expected uptime commitment
  • Databases holding data you can’t afford to lose
  • Long-running background jobs that need guaranteed persistence
  • Mail servers (outbound port 25 is blocked on nearly every free tier)
  • Free VPS Hosting No Credit Card vs. Low-Cost Paid Alternatives

    If your project outgrows what a free, no-card instance can offer, the next step is usually a small paid VPS rather than chasing another free trial. Providers like DigitalOcean, Vultr, and Linode all offer entry-level droplets/instances priced low enough to be a reasonable next step once you’re comfortable committing a small monthly budget, and they come with the reliability, support, and full networking control that free tiers typically lack. If you’re weighing whether to stay on a free instance or move to unmanaged paid hosting, our unmanaged VPS hosting guide walks through what changes once you’re responsible for the full stack yourself.

    For projects that need automation glued together — scheduled jobs, webhooks, notifications — once you have a stable VPS (free or paid), tools like n8n self-hosted are worth exploring as a way to automate the operational side of your project.


    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Is truly free VPS hosting with no credit card required actually available?
    Yes, but it’s limited. A handful of providers offer genuinely free, no-card VPS instances, usually with small resource caps, no uptime guarantees, and time-limited or renewable trial periods. Treat these as learning environments rather than something to build a business on.

    Why do most cloud providers require a credit card even for free tiers?
    Card verification is primarily an anti-abuse measure. Free compute without any payment method attached is a common target for spam and mining abuse, so most established providers require a card even if you’re never actually charged during the free period.

    Can I self-host a real website on free VPS hosting no credit card?
    You can host a small, low-traffic personal project, but it’s not a good fit for anything with real visitors or uptime expectations. The lack of an SLA and the shared, often oversubscribed hardware behind free tiers make them unreliable for production sites.

    What happens when a free VPS trial expires?
    Depending on the provider, your instance may be suspended, deleted, or you’ll be prompted to add a payment method to continue. Always check the provider’s policy before deploying anything you’d be upset to lose, and keep backups of any configuration or data that matters.

    Conclusion

    Free VPS hosting no credit card options exist, but they come with real constraints: limited resources, no reliability guarantees, and terms that vary widely between providers. They’re genuinely useful for learning Linux administration, testing Docker Compose setups, and prototyping small projects — just go in with realistic expectations, harden SSH and your firewall immediately, and keep an eye on the provider’s terms so you’re not caught off guard when a trial period ends. When a project outgrows a free instance, moving to a low-cost paid VPS is usually a smoother path than hunting for the next free offer.

  • Build Applications With Ai Agents

    How to Build Applications With AI Agents: A DevOps Guide

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    Teams that build applications with AI agents are shifting how software gets designed, tested, and shipped. Instead of writing every line of logic by hand, developers increasingly pair traditional code with autonomous or semi-autonomous agents that can reason over context, call tools, and take multi-step actions toward a goal. This guide walks through the practical architecture, infrastructure, and operational patterns you need to build applications with AI agents in a way that is maintainable, observable, and safe to run in production.

    This is not a theoretical overview. It’s written for engineers who already run Docker Compose stacks, manage VPS infrastructure, and think about uptime and logging as first-class concerns — because those same disciplines apply directly when you build applications with AI agents.

    What “Building Applications With AI Agents” Actually Means

    Before touching infrastructure, it helps to separate two very different things that both get called “AI agents”:

  • Tool-calling assistants — an LLM that receives a user request, decides which function/tool to call, executes it, and returns a result. Mostly stateless per request.
  • Autonomous agents — a process that maintains state across multiple steps, plans a sequence of actions, and can loop, retry, or escalate without a human in the loop for every decision.
  • Most production systems that build applications with AI agents actually combine both: a tool-calling layer handles individual actions (query a database, call an API, write a file), while an orchestration layer decides what sequence of tool calls achieves the broader goal.

    Core Components of an Agent-Based Application

    Regardless of framework, nearly every agent-based application has the same building blocks:

  • A model interface — the LLM API call itself, with prompt templates and structured output parsing.
  • A tool registry — a defined set of functions the agent is allowed to call, each with a schema.
  • A memory/state store — short-term (conversation context) and long-term (vector store, database) memory.
  • An orchestrator/loop — the code that decides “call the model again, call a tool, or stop.”
  • Guardrails — validation, rate limits, and permission boundaries around what the agent can actually do.
  • If you’re new to the agent concept itself, How to Create an AI Agent: A Developer’s Guide and Building AI Agents: A Practical DevOps Guide both cover the conceptual groundwork this article builds on.

    Choosing an Architecture Before You Build Applications With AI Agents

    A common mistake is picking a framework before deciding on an architecture. The framework is a detail; the architecture determines whether the system is debuggable six months from now.

    Single-Agent vs. Multi-Agent Design

    A single-agent design — one orchestrator, one set of tools, one model — is easier to reason about and should be the default starting point. Multi-agent systems (a “planner” agent delegating to “worker” agents) add real value only when tasks are genuinely parallelizable or require distinct specialized context windows. Multi-agent setups also multiply your debugging surface: every hop between agents is a place where context can be lost or misinterpreted, so don’t reach for one until a single agent has demonstrably hit its limits.

    Synchronous vs. Queue-Based Execution

    For anything beyond a simple chatbot, agent tasks should run through a queue rather than inline in an HTTP request. Long-running agent loops (multiple model calls, tool executions, retries) don’t belong in a request/response cycle with a client waiting on an open connection. A typical pattern:

  • API receives a request and writes a job record to a queue or database table.
  • A worker process picks up pending jobs, runs the agent loop, and writes results back.
  • The client polls or receives a webhook/notification when the job completes.
  • This is the same pattern used by workflow engines like n8n, and if you’re already running n8n for automation, it’s worth reading How to Build AI Agents With n8n: Step-by-Step Guide to see how a visual workflow tool can act as the orchestrator layer instead of custom code.

    Infrastructure to Build Applications With AI Agents Reliably

    Agent workloads have a different resource profile than typical web apps: unpredictable request duration, occasional need for GPU-backed inference (if self-hosting models), and heavier reliance on external API calls that can fail or rate-limit.

    Containerizing the Agent Runtime

    Package the agent runtime, its tool implementations, and its dependencies into a container so the execution environment is reproducible across dev, staging, and production. A minimal Docker Compose setup for an agent worker plus a queue and a database might look like this:

    version: "3.9"
    services:
      agent-worker:
        build: ./agent
        environment:
          - MODEL_API_KEY=${MODEL_API_KEY}
          - QUEUE_URL=redis://queue:6379
          - DATABASE_URL=postgres://agent:agent@db:5432/agent_state
        depends_on:
          - queue
          - db
        restart: unless-stopped
    
      queue:
        image: redis:7-alpine
        volumes:
          - redis_data:/data
    
      db:
        image: postgres:16-alpine
        environment:
          - POSTGRES_USER=agent
          - POSTGRES_PASSWORD=agent
          - POSTGRES_DB=agent_state
        volumes:
          - pg_data:/var/lib/postgresql/data
    
    volumes:
      redis_data:
      pg_data:

    If you need a deeper reference on the Postgres service definition, Postgres Docker Compose: Full Setup Guide for 2026 and Redis Docker Compose: The Complete Setup Guide cover configuration details worth applying here, including persistent volumes and health checks.

    Where to Host the Agent Stack

    A self-managed VPS gives you full control over networking, container runtime versions, and cost — important once you start running background agent workers continuously rather than just serving web requests. Providers like DigitalOcean and Vultr both offer VPS tiers suited to running a Docker Compose stack with an agent worker, a queue, and a database on a single instance for early-stage projects, scaling to multiple instances as load grows.

    Secrets and Environment Management

    Agent workers need API keys for the model provider and often for third-party tools (search APIs, email, CRM systems). Never hardcode these; store them in environment files excluded from version control, and if you’re managing several services with overlapping variables, Docker Compose Env: Manage Variables the Right Way and Docker Compose Secrets: Secure Config Management Guide both cover patterns for keeping credentials out of images and logs.

    Designing the Tool Layer

    The tools an agent can call are the actual boundary of what it can do to your systems and data. When you build applications with AI agents, this layer deserves more design attention than the prompt itself.

    Defining Tool Schemas

    Each tool should have an explicit schema — name, description, and typed parameters — so the model can reliably decide when and how to call it. Vague tool descriptions are one of the most common causes of agents calling the wrong function or passing malformed arguments.

    Limiting Blast Radius

    Give agents the narrowest permissions that let them do their job. A tool that “reads customer records” should not also have delete access. A tool that “writes to a staging table” should not be able to touch production data directly. This mirrors ordinary least-privilege practice in DevOps, and it matters more here because the caller (the model) is probabilistic, not deterministic — see AI Agent Security: A Practical Guide for DevOps for a closer look at this specific risk class.

    Observability When You Build Applications With AI Agents

    Standard application logging is necessary but not sufficient for agent systems. You also need visibility into the reasoning trace — which tools were called, in what order, with what arguments, and what the model’s intermediate outputs were.

    What to Log

  • Every model call: prompt, response, token usage, and latency.
  • Every tool invocation: tool name, arguments, result, and duration.
  • The final decision or output the agent produced, tied back to the originating request ID.
  • Any retries, fallbacks, or human-escalation events.
  • Structured logs (JSON lines) make this queryable later, and if your stack already runs Docker Compose, revisiting Docker Compose Logs: The Complete Debugging Guide or Docker Compose Logging: Complete Setup & Best Practices will help you wire agent logs into the same aggregation pipeline as the rest of your services rather than maintaining a separate system.

    Setting Cost and Latency Budgets

    Agent loops can call the model multiple times per request, and each call has real cost and latency. Set a hard cap on the number of loop iterations and a timeout per job so a misbehaving agent can’t spin indefinitely, consuming API quota or blocking a worker slot.

    # Example: enforce a max-iteration guard inside an agent worker script
    MAX_ITERATIONS=8
    iteration=0
    while [ "$iteration" -lt "$MAX_ITERATIONS" ]; do
      # run one step of the agent loop here
      iteration=$((iteration + 1))
    done

    Testing and Evaluating Agent Behavior

    Unlike deterministic code, an agent’s output can vary between runs given the same input. This changes how you approach testing.

    Golden-Path Test Cases

    Build a small set of representative tasks with known-good expected outcomes (not necessarily exact text matches, but structural checks: did it call the right tool, did it produce output in the right format). Run these against every prompt or model change before deploying.

    Human-in-the-Loop Review for High-Risk Actions

    For actions with real-world consequences — sending an email, modifying a database, making a purchase — insert a confirmation step rather than letting the agent act autonomously, at least until you have enough production evidence to trust the failure rate. This same caution shows up across customer-facing agent deployments; see Customer Service AI Agents: Self-Hosted Deployment Guide for how this plays out in a support context specifically.

    Deployment and Scaling Considerations

    Once the architecture is validated, scaling an agent application mostly follows familiar container-orchestration patterns, with a few agent-specific wrinkles.

    Horizontal Scaling of Workers

    Because agent jobs run through a queue, adding capacity is usually a matter of running more worker containers. Keep the worker process stateless with respect to job data — all state should live in the database or memory store, not in the worker’s local memory — so any worker can pick up any job.

    Rate Limiting Against the Model Provider

    Model APIs enforce rate limits per account or API key. As you scale worker count, make sure your queue consumer respects these limits (backoff and retry) rather than assuming unlimited throughput. This is a frequent source of production incidents when teams build applications with AI agents and scale workers faster than they adjust for upstream API limits.

    For general container orchestration references outside the AI-specific tooling, the Docker documentation and Kubernetes documentation both remain the authoritative sources for scaling patterns, health checks, and resource limits that apply equally to agent workers as to any other containerized service.


    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Do I need a specialized agent framework to build applications with AI agents?
    No. A framework can speed up development, but the core loop — call the model, parse its intended action, execute a tool, feed the result back — can be implemented directly against a model provider’s API. Start simple and adopt a framework only if it solves a concrete problem you’ve already hit.

    How do I prevent an agent from taking unintended destructive actions?
    Restrict the tool layer to the minimum permissions required, add explicit confirmation steps for high-risk actions, and log every tool call so you can audit behavior after the fact. Treat the agent’s tool access the same way you’d treat any external caller’s API permissions.

    Should agent workers run on the same VPS as my main application?
    For small workloads, yes — a single Compose stack with separate services is fine. As agent traffic grows, especially if it involves longer-running jobs or heavier API usage, separating the agent worker onto its own instance or service makes it easier to scale and monitor independently.

    How is building an application with AI agents different from just calling an LLM API in my backend?
    A simple LLM API call is a single request/response with no autonomy over subsequent steps. When you build applications with AI agents, the system itself decides which actions to take, in what order, and can loop or retry based on intermediate results — which requires the orchestration, tool, and observability layers described above.

    Conclusion

    Teams that build applications with AI agents successfully tend to treat the agent loop as just another service in their stack — containerized, queued, logged, and rate-limited like anything else — rather than as a mysterious black box bolted onto the side of an existing application. Start with a single-agent design, define a narrow and well-tested tool layer, log the full reasoning trace, and scale workers using the same container-orchestration patterns you already trust for other production services. The pattern is new, but the operational discipline it requires is not.

  • Ai Agents Developer

    What an AI Agents Developer Actually Builds: Tools, Infrastructure, and Real Workflows

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    An ai agents developer is the person responsible for turning a language model into something that can actually act — call APIs, read databases, trigger deployments, and hand off work between systems — rather than just answer chat messages. This role sits at the intersection of software engineering, DevOps, and applied machine learning, and the day-to-day work looks a lot more like building and operating distributed systems than prompt-tuning a chatbot. This guide covers the tooling, infrastructure decisions, and operational patterns that define the job in 2026.

    The demand for this role has grown alongside the maturity of agent frameworks and orchestration tools, but the underlying discipline is not new. Anyone who has built a webhook-driven pipeline, managed a job queue, or debugged a flaky cron job already has half the skill set. What’s different is the addition of a non-deterministic component — the model itself — sitting in the middle of a system that otherwise needs to behave predictably.

    Core Responsibilities of an AI Agents Developer

    At a high level, the job breaks down into four recurring responsibilities, regardless of which framework or vendor stack a team has chosen.

  • Designing the agent’s decision loop — how it plans, calls tools, and decides when a task is complete
  • Wiring integrations (APIs, databases, internal services) the agent can safely call
  • Building guardrails: input validation, output validation, and hard stops for destructive actions
  • Operating the system in production: logging, monitoring, cost control, and incident response
  • None of these responsibilities are unique to “AI” work in isolation. What makes the role distinct is that the agent’s behavior is probabilistic, so testing and monitoring strategies have to account for output variance in a way traditional deterministic code doesn’t require.

    Decision Loops and Tool Calling

    Most production agents run some variant of a plan-act-observe loop: the model receives a goal and a set of available tools (functions), decides which tool to call, receives the result, and repeats until it determines the task is done or a stopping condition is hit. An ai agents developer needs to define that loop explicitly rather than trusting the model to self-terminate cleanly — unbounded loops are a common source of runaway API costs and are one of the first failure modes new teams hit in production.

    A minimal example of a tool-calling loop, expressed as pseudocode that many frameworks follow under the hood:

    # conceptual loop, not a specific framework's exact API
    while not task_complete and steps < max_steps:
      response = call_model(context, available_tools)
      if response.tool_call:
        result = execute_tool(response.tool_call)
        context.append(result)
      else:
        task_complete = True
      steps += 1

    The max_steps guard above is not optional in a production system — it’s the difference between a bounded, billable task and an agent that loops indefinitely against a paid API.

    Guardrails and Permission Boundaries

    Because an agent can trigger real side effects — sending an email, modifying a record, deploying code — permission boundaries need to be explicit at the tool level, not left to the model’s judgment. Common patterns include:

  • Read-only tools by default, with write/execute tools requiring a separate allow-list
  • A human-in-the-loop confirmation step for any action classified as destructive or irreversible
  • Rate limits and cost ceilings per agent run, enforced outside the model’s own reasoning
  • This is conceptually similar to the principle of least privilege in traditional systems administration, just applied to a component that can decide, at runtime, which of its available actions to take.

    Setting Up the Development Environment

    Before writing any agent logic, most developers need a reproducible local environment that mirrors production closely enough to catch integration issues early. Containerizing the agent and its dependencies is the standard approach.

    Containerizing the Agent Stack

    A typical agent stack includes the agent process itself, a vector store or database for retrieval, and sometimes a message queue for coordinating multi-agent workflows. Defining this as a multi-container setup keeps local development and production environments consistent — the same pattern covered in general terms in guides comparing Dockerfile vs Docker Compose approaches.

    A minimal docker-compose.yml for an agent plus a Postgres-backed memory store might look like:

    version: "3.9"
    services:
      agent:
        build: .
        environment:
          - MODEL_API_KEY=${MODEL_API_KEY}
          - DATABASE_URL=postgres://agent:agent@db:5432/agent_memory
        depends_on:
          - db
      db:
        image: postgres:16
        environment:
          - POSTGRES_USER=agent
          - POSTGRES_PASSWORD=agent
          - POSTGRES_DB=agent_memory
        volumes:
          - agent_db_data:/var/lib/postgresql/data
    volumes:
      agent_db_data:

    For teams that need a deeper reference on the database side of this setup, a dedicated Postgres Docker Compose guide covers volume persistence and connection tuning in more detail than fits here.

    Managing Secrets and Configuration

    Agent stacks tend to accumulate more API keys than a typical web app — one for the model provider, one for each external tool the agent can call, and often separate keys per environment. Keeping these out of version control and out of plain environment files where possible is a baseline requirement, not a nice-to-have, since a leaked key on an agent with write access to production systems is a materially worse incident than a leaked key on a read-only service. A dedicated look at Docker Compose secrets management is worth reading before wiring credentials into any agent container, and general Docker Compose environment variable handling applies directly here too.

    Choosing an Agent Framework or Building From Scratch

    There are two broad paths an ai agents developer takes on a new project: adopt an existing agent framework, or build the orchestration logic directly against a model provider’s API.

    When to Use an Existing Framework

    Frameworks handle the plumbing — tool-call parsing, memory management, retry logic — so a team doesn’t reimplement it per project. This is usually the right default for teams shipping their first agent, since the plan-act-observe loop, error handling for malformed tool calls, and conversation state management are easy to get subtly wrong on a first attempt. Detailed comparisons of the underlying decision, including trade-offs between “agentic AI” as a general pattern versus a specific agent implementation, are covered in a broader guide on agentic AI tools.

    When to Build Custom Orchestration

    Custom orchestration makes sense once a team has specific latency, cost, or compliance requirements that a general-purpose framework doesn’t accommodate well — for example, needing to log every intermediate reasoning step to an internal audit system in a specific schema, or needing tight control over retry behavior for a rate-limited internal API. Teams evaluating whether to build agent logic on top of an existing low-code automation platform instead of writing bespoke orchestration code often start from a workflow-automation angle; a guide on how to build AI agents with n8n walks through that specific path, and a broader comparison of n8n vs Make is useful context if the team hasn’t settled on an orchestration platform yet.

    Infrastructure and Deployment Considerations

    Once an agent works locally, deploying it reliably introduces a different set of concerns than deploying a stateless web service, mainly because agent runs can be long-lived and their resource usage is harder to predict up front.

    Compute Sizing and Hosting

    Agent workloads are often bursty — idle most of the time, then briefly CPU- and memory-intensive during a multi-step tool-calling run. A VPS with burstable performance characteristics is frequently more cost-effective than committing to a large fixed instance, at least for early-stage or moderate-traffic deployments. Providers like DigitalOcean and Vultr both offer VPS tiers that work well for this kind of variable load, and Hetzner is a common choice when cost-per-core is the primary constraint. For teams running an unmanaged setup, a general unmanaged VPS hosting guide covers the baseline responsibilities that come with self-managing the box an agent runs on.

    Logging, Observability, and Cost Tracking

    Because agent behavior is non-deterministic, standard application logs aren’t enough — teams typically need to log the full sequence of model calls, tool calls, and intermediate reasoning for every run, not just errors. This is what makes post-incident debugging possible: reconstructing why an agent chose a particular tool call requires the actual transcript, not just a stack trace. Cost tracking deserves the same rigor, since a single misbehaving agent loop can consume a meaningful chunk of a monthly model API budget in hours if the step limit is misconfigured.

    Common Failure Modes and How to Guard Against Them

    Most production incidents involving agents fall into a small number of recurring categories:

  • Infinite or near-infinite tool-calling loops — mitigated with hard step limits and per-run cost ceilings
  • Hallucinated tool arguments (e.g., a fabricated file path or record ID) — mitigated by validating tool inputs before execution, never trusting the model’s output as pre-sanitized
  • Silent partial failures — an agent reports success after only completing part of a multi-step task, usually caught by requiring explicit verification steps rather than trusting the model’s own “done” signal
  • Credential overreach — an agent tool has broader permissions than the task requires, which turns a minor hallucination into a real incident
  • Building automated checks around these failure modes — rather than relying on manual review of agent transcripts — is what separates a reliable production agent from a demo. The same discipline used for Docker Compose logging practices in traditional services applies directly to capturing agent run transcripts for later review.

    Testing and Iterating on Agent Behavior

    Testing agents is harder than testing traditional code because the same input can produce different valid outputs across runs. Effective approaches usually combine three layers:

    Deterministic Unit Tests for Tools

    Every tool an agent can call should have standard unit tests, independent of the model entirely. If a tool that queries a database or hits an internal API is broken, no amount of prompt engineering will fix the resulting agent behavior — so this layer should be tested exactly like any other piece of application code.

    Scenario-Based Evaluation

    Beyond unit tests, teams typically maintain a set of representative scenarios (a fixed input, an expected class of outcome) and re-run them whenever the prompt, model version, or tool set changes. This catches regressions that wouldn’t show up in a quick manual check, and it’s the closest equivalent agents have to a regression test suite.

    Staged Rollouts

    Rolling out a new agent version to a small percentage of real traffic before a full rollout, combined with close monitoring of tool-call error rates and cost per run, catches issues that scenario testing misses — particularly around edge cases in real user input that a curated test set didn’t anticipate.


    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Do I need a specific framework to become an ai agents developer, or can I use any language?
    No specific framework is required. The core skills — tool-calling loop design, guardrails, and production monitoring — transfer across frameworks and even across languages. Most teams pick a framework based on their existing stack and the maturity of its tool-calling and memory-management support, referenced in the framework comparisons above.

    How is an ai agents developer different from a machine learning engineer?
    A machine learning engineer is typically focused on training, fine-tuning, or evaluating models themselves. An ai agents developer usually works with an existing model (often via API) and focuses on the surrounding system: orchestration, tool integration, guardrails, and production operations — closer to backend/DevOps engineering than to model research.

    What’s the biggest infrastructure mistake teams make when deploying their first agent?
    Skipping hard limits on tool-call loops and cost ceilings. An agent that works fine in a demo can rack up unexpectedly high API costs in production if a step limit isn’t enforced, especially when the agent encounters an edge case it wasn’t tested against.

    Can agent workloads run on a small VPS, or do they need dedicated GPU infrastructure?
    Most agent orchestration workloads are CPU/network-bound, not GPU-bound, since the model inference itself typically happens via an external API call rather than locally. A standard VPS is sufficient for the orchestration layer; GPU infrastructure is only necessary if a team is self-hosting the underlying model as well.

    Conclusion

    Becoming an effective ai agents developer means treating agent systems as production infrastructure from day one — with the same discipline around testing, observability, and permission boundaries that any reliable distributed system requires, plus additional guardrails for the non-deterministic component sitting in the middle of it. The frameworks and model providers will keep changing, but the underlying job — building tool integrations, enforcing safe boundaries, and operating the system reliably once it’s live — stays consistent. Teams that treat agent development as “just prompting” tend to hit reliability and cost problems quickly; teams that treat it as systems engineering with an unusual component tend to ship something that survives contact with real traffic. For further reading on the orchestration side of this work, the Kubernetes vs Docker Compose comparison is a useful next step once an agent stack outgrows a single-host deployment, and the official Docker documentation and Kubernetes documentation remain the most reliable references for the underlying container orchestration primitives this work depends on.

  • Build Ai Agent From Scratch

    How to Build AI Agent From Scratch: A DevOps Guide

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    If you want to build AI agent from scratch rather than wiring together a no-code platform, you need to understand the moving parts: an LLM as the reasoning engine, a tool-execution layer, a state/memory store, and a deployment target that keeps the whole thing running reliably. This guide walks through the architecture, the code you actually need, and the infrastructure decisions that separate a weekend prototype from something you can run in production.

    Plenty of teams reach for a drag-and-drop builder first, and that’s a reasonable starting point for prototyping — see our comparison of how to build AI agents with n8n if you want that route. But once you need custom control flow, non-standard tool integrations, or tight latency budgets, you’ll want to build ai agent from scratch using plain code and a few well-chosen libraries. This article covers that path end-to-end.

    Why Build AI Agent From Scratch Instead of Using a Framework

    There’s no shortage of agent frameworks now, and many of them are genuinely useful. So why would you choose to build ai agent from scratch instead of adopting one wholesale?

  • Full control over the reasoning loop. Frameworks abstract away the exact prompt structure, retry logic, and tool-call parsing. When something misbehaves in production, debugging an abstraction you don’t own is harder than debugging your own code.
  • Smaller dependency surface. Fewer transitive dependencies means fewer surprise breaking changes and a smaller attack surface to audit.
  • Easier to reason about cost and latency. You know exactly how many tokens each step consumes because you wrote the loop.
  • No lock-in. Swapping model providers or hosting environments is simpler when your agent logic isn’t tightly coupled to a specific SDK’s internals.
  • None of this means frameworks are bad — for many teams, a framework is the right tradeoff. But if your use case is narrow, well-defined, or has strict latency/cost constraints, building from scratch is often the more maintainable long-term choice. Our related guide on building AI agents covers the same tradeoff from a slightly different angle if you want a second opinion before committing.

    Core Components You’ll Need

    Whatever framework decision you make, the underlying components are the same:

    1. An LLM client (via an API or a self-hosted model server)
    2. A tool/function registry with clear input/output contracts
    3. A loop that alternates between “ask the model what to do” and “execute the chosen tool”
    4. A memory or state store (short-term conversation history, long-term vector or relational storage)
    5. A deployment and observability layer

    Designing the Agent Loop

    The heart of any agent is the loop: the model receives context, decides on an action, that action executes, and the result feeds back into the next model call. This is sometimes called the ReAct pattern (reason + act), though you don’t need to use that exact name in your code — the concept is simple enough to implement directly.

    The Minimal Reasoning Loop

    Here’s a minimal, dependency-light version in Python using an OpenAI-compatible chat completions API. It’s intentionally small so you can see every decision point:

    import json
    import openai
    
    client = openai.OpenAI()
    
    TOOLS = {
        "get_weather": lambda city: f"Weather data for {city} is unavailable in this demo.",
        "add_numbers": lambda a, b: a + b,
    }
    
    TOOL_SCHEMA = [
        {
            "type": "function",
            "function": {
                "name": "get_weather",
                "description": "Get current weather for a city",
                "parameters": {
                    "type": "object",
                    "properties": {"city": {"type": "string"}},
                    "required": ["city"],
                },
            },
        },
    ]
    
    def run_agent(user_message, max_steps=5):
        messages = [{"role": "user", "content": user_message}]
        for _ in range(max_steps):
            response = client.chat.completions.create(
                model="gpt-4o-mini",
                messages=messages,
                tools=TOOL_SCHEMA,
            )
            choice = response.choices[0].message
            if not choice.tool_calls:
                return choice.content
            messages.append(choice)
            for call in choice.tool_calls:
                fn = TOOLS[call.function.name]
                args = json.loads(call.function.arguments)
                result = fn(**args)
                messages.append({
                    "role": "tool",
                    "tool_call_id": call.id,
                    "content": str(result),
                })
        return "Max steps reached without a final answer."

    This loop is deliberately bare-bones: no retries, no streaming, no persistent memory. That’s the point — start with something you fully understand, then layer complexity on top only where you need it. For the exact reference on function/tool calling parameters, check the OpenAI API documentation.

    Handling Tool Failures and Retries

    Real tools fail — an API times out, a database connection drops, a rate limit kicks in. When you build ai agent from scratch, you own this failure handling directly instead of trusting a framework’s defaults:

    def call_tool_safely(fn, args, retries=2):
        for attempt in range(retries + 1):
            try:
                return fn(**args)
            except Exception as exc:
                if attempt == retries:
                    return f"Tool failed after {retries} retries: {exc}"

    Feed tool failures back into the conversation as plain text rather than swallowing them — the model can often recover gracefully if it knows a step didn’t work, for example by trying a different tool or asking the user for clarification.

    Choosing a Memory Strategy

    An agent without memory re-derives everything from scratch on every call, which is expensive and limits what it can do across a multi-turn conversation. There are two broad memory tiers worth separating:

  • Short-term (conversation) memory — the running message history for the current session. Simplest option: keep it in a list in application memory or a Redis key, trimmed or summarized once it exceeds a token budget.
  • Long-term (knowledge) memory — facts, documents, or past interactions the agent should recall across sessions. Typically backed by a vector database or a relational store with full-text search.
  • Persisting State With Redis or Postgres

    For most self-hosted setups, Redis is a good fit for short-term session state because it’s fast and simple to run alongside your agent process. If you’re already running a Docker Compose stack, our Redis Docker Compose setup guide covers the exact service definition you’ll need. For long-term memory that needs relational queries or joins against other application data, Postgres is a solid default — see the Postgres Docker Compose guide for a working configuration.

    A minimal docker-compose.yml combining both, alongside the agent service itself, looks like this:

    services:
      agent:
        build: .
        environment:
          - OPENAI_API_KEY=${OPENAI_API_KEY}
          - REDIS_URL=redis://redis:6379
          - DATABASE_URL=postgresql://agent:agent@postgres:5432/agent
        depends_on:
          - redis
          - postgres
    
      redis:
        image: redis:7-alpine
        restart: unless-stopped
    
      postgres:
        image: postgres:16-alpine
        restart: unless-stopped
        environment:
          - POSTGRES_USER=agent
          - POSTGRES_PASSWORD=agent
          - POSTGRES_DB=agent
        volumes:
          - pgdata:/var/lib/postgresql/data
    
    volumes:
      pgdata:

    If you need to manage secrets like your OPENAI_API_KEY more carefully than a plain .env file allows, our Docker Compose secrets guide walks through the options.

    Deployment and Infrastructure Choices

    Once the agent logic works locally, you need somewhere reliable to run it. This is where a lot of “from scratch” projects stall — not because the agent code is wrong, but because the deployment story was never planned.

    Picking a VPS and Sizing It Correctly

    An LLM-calling agent is usually not CPU-bound (the model runs remotely via API), so you don’t need a large instance unless you’re also running local embeddings or a vector database with a heavy index. A small, unmanaged VPS is often enough for the agent process itself. DigitalOcean and Vultr both offer straightforward droplet/instance sizing if you want a starting point, and our unmanaged VPS hosting guide covers what “unmanaged” actually means for day-to-day maintenance.

    If you expect to scale the agent horizontally later (multiple workers pulling from a shared task queue), it’s worth sizing for that from day one rather than re-architecting under load.

    Logging, Debugging, and Observability

    Agent behavior is nondeterministic by nature — the same input can produce a different tool-call sequence on different runs. That makes logging non-negotiable. At minimum, log every model call’s input, the chosen tool, the tool’s result, and the final response. If you’re running the agent inside Docker Compose, the Docker Compose logs debugging guide and the related Docker Compose logging guide cover how to keep those logs queryable without them growing unbounded.

  • Log structured JSON, not free text, so you can filter by session ID or tool name later
  • Set a hard step limit on the agent loop (as shown above) to prevent runaway token spend from an infinite tool-calling cycle
  • Capture latency per step so you can tell whether slowness comes from the model call or your own tool code
  • Testing and Iterating on Agent Behavior

    Unlike traditional software, you can’t fully unit-test an LLM’s decisions — but you can and should test everything around it. Write deterministic unit tests for your tool functions (they’re just regular code), and use a small, fixed set of example prompts as a regression suite you re-run whenever you change the system prompt or tool schema. Track whether the agent still picks the right tool for each example after changes — a regression here is easy to miss without a repeatable check.

    Kubernetes-based deployments add real operational overhead for something this small; unless you already run a cluster for other services, a single Compose stack is usually the simpler starting point. Our comparison of Kubernetes vs Docker Compose walks through when the added complexity actually pays off.


    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Do I need a framework at all to build AI agent from scratch?
    No. The core loop — call the model, execute the returned tool call, feed the result back — is only a few dozen lines of code, as shown above. Frameworks add convenience (built-in retries, memory abstractions, multi-agent orchestration) but aren’t required to get a working agent running.

    Which LLM provider should I use for a from-scratch agent?
    Any provider with a stable function/tool-calling API works. Check current pricing and rate limits before committing — our OpenAI API pricing guide is a useful reference point if you’re comparing costs across providers.

    How do I prevent an agent from calling tools in an infinite loop?
    Enforce a hard maximum number of loop iterations (as in the max_steps parameter above), and consider adding a token or cost budget per session that terminates the loop early if exceeded.

    Is it safe to let an agent execute arbitrary tools without review?
    Not by default. Any tool that mutates state (writing to a database, sending an email, calling a paid API) should have its inputs validated before execution, and destructive actions should require an explicit confirmation step rather than running automatically on the model’s first suggestion.

    Conclusion

    To build ai agent from scratch, you don’t need a large stack — you need a clear reasoning loop, a tool registry with strict input/output contracts, a deliberate memory strategy, and infrastructure that’s sized for what the agent actually does (usually light, since the model runs remotely). Start with the minimal loop shown here, add logging before you add features, and only reach for a framework once you’ve hit a concrete limitation that justifies the extra dependency. For further reading on the official model APIs referenced throughout this guide, see the Python official documentation for the language-level tooling used in these examples.

  • Build Ai Agents From Scratch

    How to Build AI Agents From Scratch: A DevOps Deployment Guide

    Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

    If you want to build AI agents from scratch instead of relying on a closed-source framework, you need to understand three things: how an agent reasons about the next action, how it calls tools, and how you actually deploy and monitor that process in production. This guide walks through the architecture, the code, and the operational side of the problem — the parts most tutorials skip once the demo works on a laptop.

    Most articles about agents stop at “call an LLM in a loop.” That’s a fine starting point, but it isn’t a system you can run reliably. Below we cover the core loop, tool execution, state management, deployment with Docker, and the observability you need once the agent is doing real work against real APIs.

    Why Build AI Agents From Scratch Instead of Using a Framework

    Frameworks like LangChain or CrewAI are useful when you want to move fast and don’t mind the abstraction overhead. But there are good reasons teams choose to build ai agents from scratch instead:

  • Full control over the reasoning loop — no hidden retries, no opaque prompt templates you have to reverse-engineer.
  • Smaller dependency surface, which matters a lot when you’re running this in a container with a strict resource budget.
  • Easier debugging, since every step of the loop is code you wrote and can log, trace, and test.
  • No lock-in to a specific framework’s versioning cadence, which can break your agent overnight on an upgrade.
  • That doesn’t mean frameworks are bad — for many teams they’re the right tradeoff. But if you’re a DevOps engineer who wants to understand exactly what’s happening between a user prompt and an API call, building the loop yourself is the fastest way to actually learn how these systems work, and it gives you a codebase you fully own.

    The Core Agent Loop

    At its simplest, an agent is a loop: observe the current state, ask a model what to do next, execute that action, and feed the result back in. When you build ai agents from scratch, this loop is the one piece of code you’ll spend the most time refining.

    def agent_loop(goal, tools, model_client, max_steps=10):
        history = [{"role": "user", "content": goal}]
        for step in range(max_steps):
            response = model_client.chat(history, tools=tools)
            if response.tool_call is None:
                return response.content  # final answer
            result = execute_tool(response.tool_call, tools)
            history.append({"role": "assistant", "content": response.tool_call})
            history.append({"role": "tool", "content": result})
        return "Max steps reached without a final answer."

    This is intentionally minimal. No retries, no memory compression, no parallel tool calls — just the skeleton. Everything else in this article builds on top of it.

    Choosing a Model Provider

    You don’t need to commit to one provider forever, but you do need a consistent interface. Most people who build ai agents from scratch start with the OpenAI API or Anthropic’s API because both have mature tool-calling support and clear documentation. Whichever you pick, isolate the provider-specific code behind a thin client class so you can swap models without rewriting your loop.

    Designing the Tool Layer

    Tools are what separate an agent from a chatbot. A tool is any function the model can request to be executed — searching the web, querying a database, hitting an internal API, or writing a file. When you build ai agents from scratch, the tool layer is where most of the real engineering effort goes, not the prompt.

    Each tool needs three things: a machine-readable schema (so the model knows it exists and what arguments it takes), an execution function, and error handling that returns something useful back into the loop rather than crashing it.

    TOOLS = [
        {
            "name": "get_weather",
            "description": "Get current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"],
            },
        }
    ]
    
    def execute_tool(tool_call, tools):
        try:
            if tool_call.name == "get_weather":
                return fetch_weather(tool_call.arguments["city"])
            return f"Unknown tool: {tool_call.name}"
        except Exception as e:
            return f"Tool error: {str(e)}"

    Guardrails on Tool Execution

    Never let an agent call a tool with unbounded permissions. If a tool can write to a filesystem, delete records, or spend money, put an explicit allowlist and a confirmation step in front of it. A reasonable pattern is to classify each tool as read-only or mutating, and require a human-in-the-loop confirmation for anything mutating until you’ve built enough confidence in the agent’s behavior to relax that.

  • Read-only tools (search, lookup, calculation) can run automatically.
  • Mutating tools (writes, deletes, payments, outbound messages) should require explicit confirmation or a dry-run mode first.
  • Every tool call and its result should be logged with a timestamp and the triggering prompt for later audit.
  • Rate Limiting and Timeouts

    An agent stuck in a loop calling a slow external API can silently rack up cost and latency. Wrap every tool call with a timeout, and cap the number of tool calls per session. This is a small amount of code that prevents most of the runaway-cost incidents teams run into once an agent goes from a demo to something users actually invoke repeatedly.

    Managing State and Memory

    A single-session agent loop is easy. The harder problem when you build ai agents from scratch is state that persists across sessions — remembering what a user asked yesterday, or tracking the status of a long-running multi-step task.

    For most use cases you don’t need a vector database on day one. A simple relational table tracking session_id, role, content, and timestamp is enough to reconstruct conversation history. Only reach for embeddings and semantic search once you have a concrete need to retrieve relevant history that a simple recency window can’t satisfy.

    Trimming Context Without Losing Intent

    As conversations grow, you’ll exceed the model’s context window or just waste tokens on irrelevant history. A common approach is to keep the last N full turns verbatim and summarize everything older into a single condensed block, re-injected at the top of the history. This keeps token usage predictable while preserving enough context for the agent to stay coherent across a long session.

    Build AI Agents From Scratch: Deployment With Docker

    Once the loop and tool layer work locally, the next step is packaging the agent so it runs reliably outside your laptop. This is the part of “build ai agents from scratch” that most tutorials skip entirely, and it’s where a DevOps background actually pays off.

    A minimal agent service needs: the agent process itself, a way to receive triggers (webhook, queue, or scheduler), and persistent storage for state. Docker Compose is a reasonable starting point for a single-host deployment before you need anything like Kubernetes.

    version: "3.9"
    services:
      agent:
        build: .
        restart: unless-stopped
        environment:
          - MODEL_API_KEY=${MODEL_API_KEY}
          - DATABASE_URL=postgres://agent:agent@db:5432/agent
        depends_on:
          - db
        ports:
          - "8080:8080"
      db:
        image: postgres:16
        restart: unless-stopped
        environment:
          - POSTGRES_USER=agent
          - POSTGRES_PASSWORD=agent
          - POSTGRES_DB=agent
        volumes:
          - agent_pgdata:/var/lib/postgresql/data
    volumes:
      agent_pgdata:

    If you’re new to the Compose file format itself, the Postgres Docker Compose setup guide and the Docker Compose Env guide cover the surrounding details — secrets handling, environment variable precedence, and volume persistence — that this snippet assumes you already know.

    Running the Agent as a Long-Lived Service

    If your agent needs to poll a queue or run on a schedule rather than respond to a single webhook, wrap the loop in a service with a clear retry policy and restart behavior. Docker’s restart: unless-stopped covers crash recovery, but you still need your own logic for “what happens if the model API is down for five minutes” — usually an exponential backoff with a cap, rather than a tight retry loop that burns through your rate limit.

    For teams that don’t want to write this orchestration layer themselves, it’s worth comparing against a visual workflow tool. The guide on how to build AI agents with n8n shows the same core loop implemented as a workflow instead of raw code — useful context even if you ultimately decide to build ai agents from scratch in your own codebase, since it clarifies which parts of the problem are genuinely hard versus just boilerplate.

    Hosting Considerations

    Wherever you run this, you want predictable CPU and a static IP for outbound webhook calls. A small VPS is enough for most single-agent workloads — you don’t need a Kubernetes cluster until you’re running many agents concurrently or need horizontal autoscaling. Providers like DigitalOcean offer straightforward droplet sizing if you want to start with a single box before deciding whether to scale out.

    Observability and Debugging

    An agent that fails silently is worse than one that crashes loudly. Every production agent needs structured logging of the full decision trace: the prompt sent, the tool selected, the arguments, the result, and the final output. Without this, debugging a bad decision means guessing.

    Log each step as a structured event rather than free text, so you can query it later:

    echo '{"session_id":"abc123","step":2,"tool":"get_weather","args":{"city":"Berlin"},"result":"12C, cloudy"}' \
      | tee -a agent_trace.jsonl

    A JSONL trace file like this is a low-effort starting point. As the system matures, ship these events to a real log aggregator so you can search and alert on patterns like repeated tool failures or sessions that hit max_steps without resolving.

    Testing the Agent Loop

    Unit-test the tool functions in isolation — they’re regular functions, so this is straightforward. For the loop itself, write scenario tests that feed a scripted sequence of model responses (mocked, not live API calls) and assert the loop takes the expected path. This catches regressions in your control flow without burning API credits on every test run, and it’s the same testing discipline you’d apply to any other stateful service.

    Common Pitfalls When You Build AI Agents From Scratch

    A few mistakes show up repeatedly in early agent implementations:

  • No upper bound on loop iterations, leading to runaway cost when the model gets stuck in a reasoning loop.
  • Tool errors returned as exceptions instead of structured results, which crashes the whole session instead of letting the agent recover.
  • Secrets (API keys, database credentials) hardcoded instead of injected via environment variables — see the Docker Compose Secrets guide for a cleaner pattern.
  • No idempotency on mutating tool calls, so a retried step can duplicate a side effect like sending a message twice.
  • Treating the model’s tool-call arguments as fully trusted input instead of validating them before execution, which is effectively the same class of bug as trusting unvalidated user input in a web app.
  • Keeping these in mind from the start saves a rewrite later. Most of them are standard software engineering discipline — logging, validation, idempotency — applied to a system where one of the callers happens to be a language model instead of a human.


    Recommended: Ready to put this into practice? DigitalOcean is a tool we use for exactly this, and we have a real, disclosed affiliate relationship with them.

    FAQ

    Do I need a framework to build AI agents from scratch?
    No. A framework can save time on boilerplate, but the core loop — call model, execute tool, feed result back — is a few dozen lines of code. Many teams choose to build ai agents from scratch specifically to avoid framework lock-in and keep the reasoning loop fully inspectable.

    How many tools should a single agent have?
    Keep it focused. An agent with a large, unfocused tool list tends to make worse tool-selection decisions than one with a small, well-described set. Start with the minimum set needed for the task and add tools only when there’s a clear gap.

    How do I prevent an agent from taking destructive actions?
    Classify tools as read-only or mutating, and require explicit confirmation or a dry-run step before any mutating tool executes. Log every tool call so you can audit what happened after the fact.

    Should I run the agent on a VPS or a serverless platform?
    Either works. A VPS with Docker Compose is simpler to reason about and debug for a single agent or small fleet. Serverless makes more sense once you have bursty, infrequent invocations where paying for an always-on container doesn’t make sense.

    Conclusion

    Learning to build ai agents from scratch means understanding the reasoning loop, the tool execution layer, state management, and the deployment and observability work that turns a demo into a system you can trust. None of these pieces are individually complex, but skipping any of them — especially guardrails on tool execution and structured logging — is what turns an agent from a useful automation into a production incident. Start with the minimal loop shown here, add tools deliberately, and invest in tracing early; it’s far easier to build that discipline in from the start than to retrofit it once the agent is already handling real traffic. For deeper reference on the model side, the Anthropic API documentation and OpenAI API documentation are both good starting points once your own loop is solid enough to plug either provider into.