Advanced Start Follow the Ax story through selected runnable examples. cpp quick-start advanced-start website/content-src/templates/advanced-start.md quick-start Advanced Start

Advanced Start

Advanced Start is built from runnable C++ examples. The story below follows the same source files that appear under Examples, so code changes start in src/examples/cpp/.

C++ Typed Generation

Start with a typed contract: the model receives named inputs and Ax parses named outputs.

Runs a small typed generation program against OpenAI.

C++
#include "axllm/axllm.hpp"
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>


int main() {
  const char* key = std::getenv("OPENAI_API_KEY");
  if (key == nullptr || std::string(key).empty()) key = std::getenv("OPENAI_APIKEY");
  if (key == nullptr || std::string(key).empty()) {
    std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n";
    return 2;
  }
  const char* model = std::getenv("AX_OPENAI_MODEL");
  axllm::OpenAICompatibleClient client(axllm::object({
      {"api_key", key},
      {"model", model == nullptr || std::string(model).empty() ? "gpt-5.4-mini" : model},
      {"model_config", axllm::object({{"temperature", 0}})},
  }));
  axllm::AxGen program = axllm::ax("question:string -> answer:string");
  axllm::Value output = program.forward(client, axllm::object({{"question", "In one sentence, explain Ax as a language-agnostic LLM programming library."}}));
  std::cout << axllm::stringify(output) << "\n";
}

C++ Grounded Support Agent

Move to an agent when the model needs a runtime loop and a final typed answer.

Answers a support question grounded in a handbook that is kept out of the model prompt via contextFields.

C++
#include "axllm/axllm.hpp"
#include "axllm/runtime/quickjs/quickjs_runtime.hpp"
#include <cstdlib>
#include <iostream>

int main() {
  const char* key = std::getenv("OPENAI_API_KEY");
  if (key == nullptr || std::string(key).empty()) key = std::getenv("OPENAI_APIKEY");
  if (key == nullptr || std::string(key).empty()) {
    std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n";
    return 2;
  }
  const char* model = std::getenv("AX_OPENAI_MODEL");
  axllm::OpenAICompatibleClient client(axllm::object({
      {"api_key", key},
      {"model", model == nullptr || std::string(model).empty() ? "gpt-5.4-mini" : model},
      {"model_config", axllm::object({{"temperature", 0}})},
  }));

  // The handbook can be arbitrarily large. Listing it in `contextFields` keeps it
  // in the agent's runtime so it never inflates the model prompt -- the agent reads
  // it through code, not through tokens. That is the whole point of an Ax agent
  // over a plain gen() call: the source material stays out of the context window.
  std::string handbook =
      "# Acme Cloud -- Support Handbook\n"
      "\n"
      "## Billing\n"
      "- Invoices are issued on the 1st of each month and are due net-15.\n"
      "- Plan downgrades take effect at the END of the current billing cycle, not immediately.\n"
      "- Refunds are issued to the original payment method within 5 business days.\n"
      "\n"
      "## Access\n"
      "- Seats can be added by any workspace Owner under Settings -> Members.\n"
      "- SSO (SAML) is available on Enterprise; SCIM provisioning is Owner-only.\n"
      "\n"
      "## Incidents\n"
      "- Status and uptime are published at status.acme.example.\n"
      "- Sev-1 incidents page the on-call within 5 minutes; updates post every 30 minutes.\n"
      "\n"
      "## Data\n"
      "- Exports are available in CSV and JSON from Settings -> Data.\n"
      "- Deleted workspaces are recoverable for 30 days, then permanently purged.";

  auto assistant = axllm::agent(
      "question:string, handbook:string -> answer:string, citations:string[] \"Handbook sections the answer relies on\"",
      // Keep the handbook in the runtime, out of the prompt.
      axllm::object({
          {"contextFields", axllm::array({"handbook"})},
          {"runtime", axllm::object({{"language", "JavaScript"}})},
      }));

  axllm::runtime::quickjs::QuickJsCodeRuntime runtime;
  axllm::Value result = assistant.forward(
      client,
      axllm::object({
          {"question", "A customer downgraded their plan today. When does it take effect, and can they get a refund for the current cycle?"},
          {"handbook", handbook},
      }),
      axllm::object({{"runtime", axllm::Core::code_runtime_ref(runtime)}, {"max_actor_steps", 12}}));

  std::cout << axllm::stringify(result) << "\n";
}

C++ Sequential Flow

Use a flow when the application should own the order of multi-step work.

Runs a two-step Ax flow against OpenAI.

C++
#include "axllm/axllm.hpp"
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>


int main() {
  const char* key = std::getenv("OPENAI_API_KEY");
  if (key == nullptr || std::string(key).empty()) key = std::getenv("OPENAI_APIKEY");
  if (key == nullptr || std::string(key).empty()) {
    std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n";
    return 2;
  }
  const char* model = std::getenv("AX_OPENAI_MODEL");
  axllm::OpenAICompatibleClient client(axllm::object({
      {"api_key", key},
      {"model", model == nullptr || std::string(model).empty() ? "gpt-5.4-mini" : model},
      {"model_config", axllm::object({{"temperature", 0}})},
  }));
  axllm::AxGen step = axllm::ax("documentText:string -> summaryText:string");
  axllm::AxFlow program = axllm::flow(axllm::object({{"id", "examples.sequentialFlow"}}))
      .execute("step", step)
      .map("note", [](axllm::Value) { return axllm::object({{"note", "Mapped flow state after the provider-backed step."}}); })
      .returns(axllm::object({{"step", "step"}, {"note", "note"}}));
  axllm::Value output = program.forward(client, axllm::object({{"documentText", "Ax gives developers signatures, provider clients, agents, flows, tracing, and optimization."}}));
  std::cout << axllm::stringify(output) << "\n";
}

C++ Text To Speech

Add audio when the same provider-backed contract should accept or produce speech.

Generates speech audio through OpenAI.

C++
#include "axllm/axllm.hpp"
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>
#include <variant>


int main() {
  const char* key = std::getenv("OPENAI_API_KEY");
  if (key == nullptr || std::string(key).empty()) key = std::getenv("OPENAI_APIKEY");
  if (key == nullptr || std::string(key).empty()) {
    std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n";
    return 2;
  }
  const char* model = std::getenv("AX_OPENAI_MODEL");
  axllm::OpenAIResponsesClient client(axllm::object({
      {"api_key", key},
      {"model", model == nullptr || std::string(model).empty() ? "gpt-5.4-mini" : model},
      {"model_config", axllm::object({{"temperature", 0}})},
  }));
  axllm::Value speech = client.speak(axllm::object({{"text", "Ax turns LLM prompts into typed programs."}, {"voice", "alloy"}, {"format", "mp3"}}));
  axllm::Value audio_value = axllm::Core::get(speech, "audio");
  double audio_len = audio_value.is_string() ? static_cast<double>(std::get<std::string>(audio_value.data).size()) : 0.0;
  std::cout << axllm::stringify(axllm::object({{"format", axllm::Core::get(speech, "format")}, {"audioBytesBase64", audio_len}})) << "\n";
}

C++ AxGen Optimization

Close the loop by measuring examples and applying optimizer artifacts to the program.

Runs a baseline OpenAI prediction and applies an optimizer artifact.

C++
#include "axllm/axllm.hpp"
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>

struct ExampleOptimizer : axllm::OptimizerEngine {
  std::string name() const override { return "example"; }
  std::string version() const override { return "1"; }
  axllm::Value optimize(axllm::Value request) override { return optimize(std::move(request), nullptr); }
  axllm::Value optimize(axllm::Value, axllm::OptimizerEvaluator*) override {
    return axllm::object({{"componentMap", axllm::object({{"priority::instruction", "Classify operational risk. Use high for production-impacting urgency."}})}, {"metadata", axllm::object({{"source", "axgen"}})}});
  }
};

int main() {
  const char* key = std::getenv("OPENAI_API_KEY");
  if (key == nullptr || std::string(key).empty()) key = std::getenv("OPENAI_APIKEY");
  if (key == nullptr || std::string(key).empty()) {
    std::cerr << "Set OPENAI_API_KEY or OPENAI_APIKEY to run this example.\n";
    return 2;
  }
  const char* model = std::getenv("AX_OPENAI_MODEL");
  axllm::OpenAICompatibleClient client(axllm::object({
      {"api_key", key},
      {"model", model == nullptr || std::string(model).empty() ? "gpt-5.4-mini" : model},
      {"model_config", axllm::object({{"temperature", 0}})},
  }));
  axllm::AxGen program = axllm::ax("emailText:string -> priority:class \"high, normal, low\", rationale:string", axllm::object({{"id", "priority"}, {"instruction", "Classify the email priority."}}));
  axllm::Value baseline = program.forward(client, axllm::object({{"emailText", "Production checkout is failing for enterprise customers."}}));
  ExampleOptimizer optimizer;
  axllm::Value artifact = program.optimize_with(optimizer, axllm::array({axllm::object({{"emailText", "URGENT: checkout is down"}, {"priority", "high"}})}), axllm::object({{"apply", false}}));
  program.apply_optimization(artifact);
  axllm::Value after = program.forward(client, axllm::object({{"emailText", "Production checkout is failing for enterprise customers."}}));
  std::cout << axllm::stringify(axllm::object({{"baseline", baseline}, {"after", after}})) << "\n";
}
Docs