Quick Start
Ax gives C++ one typed contract for LLM programs: signatures for data shape, ai() for model access, ax() for structured generation, agent() for tool-using runtime loops, and AxGEPA for improving programs with examples.
Install
cmake_minimum_required(VERSION 3.20)
project(ax_quick_start LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
include(FetchContent)
FetchContent_Declare(axllm GIT_REPOSITORY https://github.com/ax-llm/ax GIT_TAG main SOURCE_SUBDIR packages/cpp)
FetchContent_MakeAvailable(axllm)
add_executable(quick_start quick_start.cpp)
target_link_libraries(quick_start PRIVATE axllm::axllm)Set Your API Key
The first program uses OpenAI. Export the key in the same terminal where you will run it.
export OPENAI_API_KEY="sk-..."First Program
Start with a small typed task. The signature declares the fields the model receives and the fields Ax must parse back out. Save this as quick_start.cpp.
#include <axllm/axllm.hpp>
#include <cstdlib>
#include <iostream>
int main() {
auto llm = axllm::ai("openai", axllm::object({{"apiKey", std::getenv("OPENAI_API_KEY")}}));
auto classify = axllm::ax("review:string -> sentiment:class \"positive, negative, neutral\"");
auto result = classify.forward(*llm, axllm::object({
{"review", "Useful and boring in the best way."}
}));
auto sentiment = axllm::Core::get(result, "sentiment");
std::cout << "sentiment: " << std::get<std::string>(sentiment.data) << "\n";
}That is the core loop:
- create a provider client
- declare the input and output contract
- run the program with typed inputs
- read typed outputs instead of scraping prose
flowchart LR A["ai() client"] --> C["forward() with typed inputs"] B["Signature"] --> C C --> D["Validate + retry"] D --> E["Typed output"]
Run It
cmake -S . -B build && cmake --build build
./build/quick_startYou should see:
sentiment: positiveThe model’s wording can vary, but the declared class shape is guaranteed.
The rest of the site keeps the same concepts but swaps install commands, imports, examples, and API names for C++.
Where To Go Next
Use Examples when you want runnable files. Use Concepts when you want the mental model. Use Subsystems when you know which surface you are trying to use and want the practical call shape.