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.
- Level:
beginner - Run:
npm run example -- cpp src/examples/cpp/generation/basic_generation.cpp - Source: src/examples/cpp/generation/basic_generation.cpp
- More in this group: Generation examples
#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.
- Level:
beginner - Run:
npm run example -- cpp src/examples/cpp/short-agents/basic_agent.cpp - Source: src/examples/cpp/short-agents/basic_agent.cpp
- More in this group: Agents examples
#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.
- Level:
beginner - Run:
npm run example -- cpp src/examples/cpp/flows/sequential_flow.cpp - Source: src/examples/cpp/flows/sequential_flow.cpp
- More in this group: Flows examples
#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.
- Level:
beginner - Run:
npm run example -- cpp src/examples/cpp/audio/speech_audio.cpp - Source: src/examples/cpp/audio/speech_audio.cpp
- More in this group: Audio examples
#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.
- Level:
beginner - Run:
npm run example -- cpp src/examples/cpp/optimization/axgen_optimization.cpp - Source: src/examples/cpp/optimization/axgen_optimization.cpp
- More in this group: Optimization examples
#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";
}