5 Agent Interactions
This chapter describes how to call an Agent, how to control its capabilities per turn, and how to structure agent usage so that your procedures remain testable.
5.1 The Canonical Call Pattern
Agents are callable. You call the agent value like a function:
result = triage_agent({message = "Classify this message."})Important notes:
triage_agentmust be declared astriage_agent = Agent { ... }at top level.- Lookup patterns like
Agent("triage_agent")(...)are deprecated in the current DSL.
5.2 Inputs: message, context fields, and overrides
The call input is a table. The most common field is message:
triage_agent({message = "Please reset my password"})Anything besides message and a small set of override keys is treated as context and may be used for prompt templates or logging.
5.3 Per-turn Overrides (Capability Control)
Per-turn overrides are the core technique for keeping agent behavior safe and deterministic.
5.3.1 Tools
Override tools per call:
-- Full tools turn
triage_agent({message = "Gather facts.", tools = {lookup_customer, done}})
-- No-tools summarization/decision turn
triage_agent({message = "Summarize and decide. No new tool calls.", tools = {}})5.3.2 Generation params
You can also override common generation parameters per call:
triage_agent({
message = "Write the response.",
temperature = 0.2,
max_tokens = 200
})5.4 Reading the Result
Agent calls return a result object. Depending on configuration and backend, you may interact with it in a few common ways:
result.output(most common)triage_agent.output(convenience: last response text)
If you need a stable, typed output contract, prefer a Model for inference or structure outputs via your Procedure schema and validation.
5.5 Making Agents Testable
Agents are non-deterministic; your correctness story should not depend on the exact free-form text.
Instead, structure correctness around:
- tool calls (and tool results)
- explicit procedure state
- bounded loops and stopping conditions (often via a
donetool) - specifications (BDD) that assert observable behavior
5.6 Mocking Agents in Specs (CI-safe)
In CI you usually do not want to call a real LLM. Use Mocks { ... } to provide deterministic agent behavior:
Mocks {
triage_agent = {
tool_calls = {
{tool = "lookup_customer", args = {id = "123"}},
{tool = "done", args = {reason = "Classified"}}
},
message = "billing"
}
}Run specs in mock mode:
tactus test file.tac --mock