Beyond the prompt and actions, defineAgent carries the agent’s LLM binding and its behavioral settings:
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 profile | Recommended approach |
|---|
| Complex analysis (qualification, research synthesis) | The provider’s most capable model |
| Simple classification (routing, tagging) | A fast, low-cost model |
| High volume, low stakes | Prioritize speed and cost |
| Low volume, high stakes | Prioritize 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.
| Setting | Effect | Use when |
|---|
| Low (1-3) | Fast, direct responses | Simple lookups, single-action tasks |
| Medium (4-6) | Balanced reasoning | Most standard workflows |
| High (7+) | Deep, multi-step problem solving | Complex 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.
| Temperature | Behavior | Best for |
|---|
| 0.0 - 0.2 | Deterministic, precise, consistent | Data extraction, classification, CRM updates |
| 0.3 - 0.6 | Balanced creativity | General tasks, qualification, research |
| 0.7 - 1.0 | Creative, varied | Copywriting, 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:
- Reduce
maxSteps if tasks complete in fewer steps
- Try a faster model and verify quality remains acceptable (the
evaluator pass rate is the signal)
- Lower
temperature for more predictable outputs
- Limit resources to reduce context size and processing time