Software Engineering 2026

Agents and tool calling

Agents are LLMs that take actions through tools. Instead of one response, they run a loop: decide, call a tool, read the result, decide again. The staff decision for any workflow is how much of that loop you let the model control.

The agent loop

Flowchart

Deterministic vs autonomous workflows

DeterministicAutonomous
Fixed sequence of toolsModel decides the order
Predictable, easy to testAdapts to context
Fewer model calls, lower costMore calls, higher cost
Use for: pipelines, ETL, paymentsUse for: open-ended investigation

Default to deterministic. Add autonomy only when evals support it. Most business workflows are a fixed sequence with one or two steps that need judgment. Put the model only at those steps.

Tool calling basics

Tools are functions the model can call, described by a name, a description, and an input schema:

// Tool definition (Anthropic format)
const tools = [{
  name: "get_order_status",
  description: "Look up the current status of an order by its ID",
  input_schema: {
    type: "object",
    properties: {
      order_id: { type: "string", description: "Order ID, e.g. ord_123" }
    },
    required: ["order_id"]
  }
}];

// Implementation: your code, your permissions
async function get_order_status({ order_id }) {
  const order = await db.orders.findById(order_id);
  return { status: order.status, updated_at: order.updatedAt };
}

Deterministic workflows with tools

Flowchart
# Deterministic pipeline: code controls the order, the model does one creative step
async def process_order(order_id: str):
    order = await tools.fetch_order(order_id)

    validation = await tools.validate_order(order)
    if not validation.valid:
        return {"error": validation.errors}

    pricing = await tools.calculate_pricing(order)
    payment = await tools.process_payment(order, pricing)

    # The only model call
    confirmation = await llm.generate(f"Write a friendly order confirmation for {order}")
    return {"status": "success", "message": confirmation}

Hybrid approach: constrained autonomy

Let the model choose tools, but only from the set that fits the current phase:

TOOLS_BY_PHASE = {
    "research":  ["web_search", "read_file", "query_database"],
    "implement": ["write_file", "run_tests", "lint_code"],
    "review":    ["read_file", "static_analysis", "security_scan"],
    "deploy":    ["build", "deploy_staging", "run_smoke_tests"],
}

response = await llm.chat(messages, tools=TOOLS_BY_PHASE["implement"])

Tool design best practices

DoDon't
Descriptive names (create_github_pr)Vague names (do_thing)
Clear parameter descriptionsAssume the model knows your schema
Return structured dataReturn unformatted strings
Include error states in the resultLet tools throw unhandled errors
Idempotent operationsSide effects without confirmation
Least privilege per toolOne tool that can do anything

Least privilege is the security model. An agent with a write-anything tool is one bad prompt, or one prompt injection, away from an incident.

Error handling in tool calls

Return errors as data, so the model can recover instead of the loop crashing:

async function risky_tool(params) {
  try {
    const result = await doRiskyOperation(params);
    return { success: true, data: result };
  } catch (error) {
    return {
      success: false,
      error: error.message,
      suggestion: "Check the ID format and try again"
    };
  }
}

Trace every tool call with inputs, outputs, latency, and cost. You can't debug, secure, or bill what you can't see.

Example prompts for agent development

Deterministic pipeline:
"Build an invoice processor that runs in this exact order:
1. extract_pdf  2. validate_invoice  3. check_duplicates  4. insert_record
5. confirmation email (the only model step)
No deviation. Return an error if any step fails."

Tool design:
"Design tool schemas for our inventory system: get_product(sku),
update_stock(sku, quantity), reserve_stock(sku, quantity, order_id).
Idempotent. Structured errors."

Constrained agent:
"Build a support agent that can ONLY use: lookup_order, check_shipping_status,
create_support_ticket, escalate_to_human. It must never have refund or
cancellation tools."

Standardize tool contracts across teams: shared definitions and error shapes, so agents compose instead of each team rebuilding the same tools slightly differently.

On this page