Skip to main content
Beyond the prompt and actions, defineAgent carries the agent’s LLM binding and its behavioral settings:
agents/qualifier.ts
export const qualifier = defineAgent("qualifier", {
  connector: openai,             // the LLM provider connector
  languageModel: "gpt-4o",       // the model slug
  systemPrompt: "Qualify leads against our ICP.",
  temperature: 0.2,              // 0.0–0.2 deterministic, 0.7+ creative (default 0.2)
  maxSteps: 4,                   // reasoning-step budget (default 8)
  withReasoning: false,          // extended thinking before acting (default false)
  output: { type: "text" },      // or a jsonSchema contract — see below
  evaluator: { rubric: "Did it correctly qualify the lead?", threshold: 0.8 },
  triggers: [{ type: "cron", cron: "0 9 * * *", text: "Qualify yesterday's leads" }],
});
connector and languageModel are both required — defineAgent throws at plan time if either is missing. The connector’s integration (OpenAI, Anthropic, …) determines which model slugs are valid.

Selecting a model

The connector handle picks the provider; languageModel picks the model slug within it. Cargo supports the leading LLM providers — OpenAI, Anthropic, and Google Gemini among them — each behind its own connector. List the model slugs a provider currently exposes rather than hardcoding from memory:
cargo-ai connection integration get openAi   # → available actions and model slugs
Task profileRecommended approach
Complex analysis (qualification, research synthesis)The provider’s most capable model
Simple classification (routing, tagging)A fast, low-cost model
High volume, low stakesPrioritize speed and cost
Low volume, high stakesPrioritize reasoning quality
Start with a powerful model during development to understand what’s possible, then optimize for cost/speed once the agent is working well.

Behavioral parameters

Reasoning steps (maxSteps)

The maximum number of logical sub-tasks the agent can perform to reach a conclusion. Defaults to 8.
SettingEffectUse when
Low (1-3)Fast, direct responsesSimple lookups, single-action tasks
Medium (4-6)Balanced reasoningMost standard workflows
High (7+)Deep, multi-step problem solvingComplex research, multi-source synthesis
Higher reasoning steps increase latency and cost. Only increase if the agent is failing to complete tasks.

Temperature

Controls the creativity and variability of outputs. Defaults to 0.2.
TemperatureBehaviorBest for
0.0 - 0.2Deterministic, precise, consistentData extraction, classification, CRM updates
0.3 - 0.6Balanced creativityGeneral tasks, qualification, research
0.7 - 1.0Creative, variedCopywriting, brainstorming, conversational engagement

Extended thinking (withReasoning)

withReasoning: true lets the model think through the problem before acting — better on hard multi-step tasks, at the cost of latency and tokens. Defaults to false.

Structured output

By default an agent answers in free text (output: { type: "text" }). To make every final answer machine-parseable — for workflows or API consumers downstream — declare a JSON Schema contract:
output: {
  type: "jsonSchema",
  jsonSchema: {
    type: "object",
    properties: {
      score: { type: "string", enum: ["High", "Medium", "Low"] },
      reasoning: { type: "string" },
    },
    required: ["score", "reasoning"],
  },
},

Evaluator

The evaluator is an LLM-as-judge that scores each of the agent’s outputs against a natural-language rubric:
evaluator: {
  rubric: "Did it correctly qualify the lead, with evidence for the score?",
  threshold: 0.8,   // passing bar in [0, 1]
},
Outputs scoring below threshold are flagged, so you can spot quality regressions without reading every conversation. Pair it with prompt iterations: change the systemPrompt, re-deploy, and compare evaluator pass rates.

Triggers

Agents normally respond to messages, but triggers make them start work on their own:
triggers: [
  // On a schedule — `text` is the message the agent receives
  { type: "cron", cron: "0 9 * * *", text: "Qualify yesterday's inbound leads." },

  // On a connector event (e.g. an incoming Slack message)
  { type: "connector", integration: "slack", connector: slack, config: { channel: "#inbound" } },
],
A connector trigger references its connector by handle or connectorRef(uuid); config is integration-specific.

Heartbeat

A heartbeat wakes the agent up on an interval inside an ongoing chat — useful for long-running missions that should make progress without a human prompting each turn:
heartbeat: {
  intervalMinutes: 30,   // delay between heartbeat turns
  maxMessages: 40,       // stop waking up once the chat has this many messages
  prompt: null,          // message sent each turn; null = a generic "continue"
},

Optimizing for cost and speed

Once your agent works correctly, consider:
  1. Reduce maxSteps if tasks complete in fewer steps
  2. Try a faster model and verify quality remains acceptable (the evaluator pass rate is the signal)
  3. Lower temperature for more predictable outputs
  4. Limit resources to reduce context size and processing time