Executing a Recalled Procedure
When a procedure is recalled and injected into the agent's context, the LLM follows the procedure steps. Dynamic parameters from the user's message are substituted into tool argument templates, and conditional steps are evaluated at runtime.
Parameter Substitution
Procedure steps contain {{parameter}} placeholders in their tool argument templates. When the agent executes a step, the LLM fills in these placeholders from information gathered during the conversation:
// Procedure step template:
{
"toolName": "vendor_create",
"toolArgumentTemplate": "{\"name\":\"{{vendor_name}}\",\"contact\":\"{{contact_email}}\",\"contract\":\"{{contract_ref}}\"}"
}
// During execution, after gathering data from user:
// The LLM substitutes:
// {{vendor_name}} → "TechCorp"
// {{contact_email}} → "procurement@techcorp.com"
// {{contract_ref}} → "CTR-2025-001"
// Actual tool call:
{
"name": "vendor_create",
"arguments": {
"name": "TechCorp",
"contact": "procurement@techcorp.com",
"contract": "CTR-2025-001"
}
}
Conditional Step Evaluation
Steps with a Condition are only executed if the condition evaluates to true. Conditions reference the output of previous tool calls:
// Step 2 result: vendor_lookup returned null (vendor not found)
// Step 3 condition: "vendor_lookup.result == null"
// → Condition is true → execute step 3 (vendor_create)
// If Step 2 had found an existing vendor:
// → Condition would be false → skip step 3
// → Execute step 4 (optional): "Report to user that vendor already exists"
Collecting Missing Parameters
If a required parameter hasn't been provided by the user, the agent asks for it before proceeding with that step:
// User: "Onboard a new vendor"
// Agent: "I'll help you onboard a new vendor. To proceed, I need:
// 1. Vendor name
// 2. Primary contact email
// 3. Contract reference number
// Could you provide these details?"
// User: "TechCorp, procurement@techcorp.com, CTR-2025-001"
// → Agent now has all parameters → proceeds with procedure steps
Procedure Execution Trace
Each procedure execution is recorded in the conversation's tool call history with the procedure name attached:
// ToolCallRecord for procedure execution
new ToolCallRecord
{
ToolName = "vendor_create",
Input = JsonDocument.Parse("{\"name\":\"TechCorp\",...}"),
Output = JsonDocument.Parse("{\"vendorId\":\"V-9912\",\"status\":\"Created\"}"),
Succeeded = true,
Duration = TimeSpan.FromMilliseconds(342),
// Procedure context recorded:
ProcedureName = "vendor_onboarding",
ProcedureStepOrder = 3
}