Lesson 04 — Add an LLM model

You are here: Lesson 4 of 8 · ← Integration · Hub · Next: Skill →

Goal

Stop depending on Aiden’s built-in base model alone. Register an LLM secret → provider → model with raw sg_* resources, then pin it on the agent with model_names.

Still the hard way — no aios-foundation module yet.

What you will change

  • sg_secret — vault entry for the LLM API key
  • sg_llm_provider — provider bound to that secret
  • sg_llm_model — named model instance
  • sg_agent.model_names — pin the model on the agent
  • Full root: steps/04-llm-model/

Why it matters

Models are infrastructure too. Encoding which providers and keys a tenant uses keeps every environment reproducible — same as VPCs or DNS.

ELI5: Before, you used the calculator that came in the box. Now you buy a new calculator, put the batteries in the vault, register the brand, and stick a name tag on the machine.

HCL — secret → provider → model → agent

OpenAI path (Anthropic / Gemini are the same shape with different subcategory / provider_type / model_id):

resource "sg_secret" "openai" {
  name        = "aac-openai-vault"
  description = "OpenAI API key for Agent as Code"
  category    = "LLM"
  subcategory = "openai"
  metadata = {
    OPENAI_API_KEY = var.openai_api_key
  }
}

resource "sg_llm_provider" "openai" {
  name            = "aac-openai"
  provider_type   = "openai"
  token_reference = sg_secret.openai.name
}

resource "sg_llm_model" "gpt54" {
  name          = "aac-gpt-5.4"
  provider_name = sg_llm_provider.openai.name
  model_id      = "gpt-5.4-2026-03-05"
  thinking      = false
}

resource "sg_agent" "tutor" {
  # ...
  model_names = [sg_llm_model.gpt54.name]
}

The step folder also shows optional Anthropic / Gemini blocks behind count when those API keys are set.

Apply & verify

cd examples/scenarios/agent-as-code/steps/04-llm-model
export TF_VAR_openai_api_key="sk-..."   # or anthropic / gemini
# keep GitHub vars from lesson 03
tofu init && tofu apply
tofu output model_names

Arrange: Models list in Aiden shows your new model.
Sample prompt (chat with aac-tutor):

Which model are you using right now? Reply with the model name from your configuration.

Assert: Chat works; model_names output lists the model you registered; the reply should match that registered name (not only the built-in base model).

Gotchas

  • Chain order matters: secret → provider (token_reference) → model (provider_name) → agent (model_names).
  • Do not commit API keys; use TF_VAR_* or a secrets backend.
  • When you are tired of copying this trio, wrap it in aios-foundation — that module is exactly these resources with compact() outputs.
  • For Azure OpenAI, proxies, or a custom API base URL, see Custom LLM provider URLs.
  • For Bedrock, see aios-foundation-bedrock after you understand this path.

Checkpoint

  • sg_secret + sg_llm_provider + sg_llm_model applied
  • Agent model_names points at your registered model
  • Chat works without relying only on the built-in base model

Next: Lesson 05 — Add a skill