Skip to main content

Getting Started

Aigentic is a Kotlin Multiplatform library for building AI agents with a typed DSL. You'll have a working agent in three steps. The rest of this page covers the other modules, Maven, and adding tools.

Your first agent in 3 steps​

1. Add the dependencies​

build.gradle.kts
plugins {
kotlin("jvm") version "2.3.0"
kotlin("plugin.serialization") version "2.3.0"
application
}

dependencies {
implementation("community.flock.aigentic:core:0.11.0")
implementation("community.flock.aigentic:gemini:0.11.0")
implementation("io.ktor:ktor-client-cio:3.4.3")
}

application {
mainClass.set("MainKt")
}

The plugin.serialization line is required: Aigentic uses it to turn your @AigenticParameter classes into schemas the model fills in. Using Maven or another provider? See Installation below.

2. Write the agent​

src/main/kotlin/Main.kt
import community.flock.aigentic.core.agent.start
import community.flock.aigentic.core.agent.tool.Outcome
import community.flock.aigentic.core.annotations.AigenticParameter
import community.flock.aigentic.core.dsl.agent
import community.flock.aigentic.gemini.dsl.geminiModel
import community.flock.aigentic.gemini.model.GeminiModelIdentifier

@AigenticParameter
data class Answer(val answer: String)

val kotlinExpert = agent<String, Answer> {
geminiModel {
apiKey(System.getenv("GEMINI_API_KEY"))
modelIdentifier(GeminiModelIdentifier.Gemini3_5Flash)
}
task("Answer questions about Kotlin") {
addInstruction("Keep answers to two sentences")
}
}

suspend fun main() {
val run = kotlinExpert.start("How are coroutines different from threads?")
when (val outcome = run.outcome) {
is Outcome.Finished -> println(outcome.response?.answer)
is Outcome.Stuck -> println("Stuck: ${outcome.reason}")
is Outcome.Fatal -> println("Error: ${outcome.message}")
}
}

agent<String, Answer> means the agent takes a String and gives you back an Answer. The model fills in the data class for you, so there's no JSON to parse.

3. Run it​

Get a free API key from Google AI Studio, then run:

export GEMINI_API_KEY=your-api-key
./gradlew run
Output
🚀 Agent started!
Coroutines suspend instead of blocking, so thousands of them can share a handful of threads. Threads are managed by the operating system and cost far more to create and switch between.

The answer comes from the model, so yours will be worded differently. Next, see how the pieces fit together, give the agent a tool or switch to another provider.


Installation​

Aigentic can be added to your project using either Gradle or Maven build tools.

Kotlin (JVM)​

Add the following to your build.gradle.kts file:

plugins {
kotlin("jvm") version "2.3.0"

// Kotlinx serialization enables @AigenticParameter to convert Kotlin classes
// to LLM-compatible formats in order to provide a type safe DSL
kotlin("plugin.serialization") version "2.3.0"
}

dependencies {
// Core module
implementation("community.flock.aigentic:core:0.11.0")

// Provider modules (choose the ones you need)
implementation("community.flock.aigentic:openai:0.11.0")
implementation("community.flock.aigentic:gemini:0.11.0")
implementation("community.flock.aigentic:ollama:0.11.0")
implementation("community.flock.aigentic:vertexai:0.11.0")

// Tools modules (optional)
implementation("community.flock.aigentic:http:0.11.0")
implementation("community.flock.aigentic:openapi:0.11.0")

// Platform module (optional): send runs to the Aigentic platform and run regression tests
implementation("community.flock.aigentic:platform:0.11.0")

// Choose one of the following Ktor client engines depending on your platform
implementation("io.ktor:ktor-client-cio:3.4.3") // Ktor's CIO engine
//implementation("io.ktor:ktor-client-okhttp:3.4.3") // JVM (Android compatible)
// implementation("io.ktor:ktor-client-apache:3.4.3") // Apache HttpClient
// implementation("io.ktor:ktor-client-java:3.4.3") // Java 11+ HttpClient
// implementation("io.ktor:ktor-client-jetty:3.4.3") // Jetty HttpClient
// implementation("io.ktor:ktor-client-js:3.4.3") // Javascript/Node
}

Ktor Client Engine Selection​

Aigentic uses Ktor for HTTP communication, which requires a platform-specific client engine:

For detailed information about engine features, which one to choose and alternatives, see the Ktor Client Engines documentation.


Add a tool​

Tools let an agent call your code. Here the agent gets a getWeather tool and decides on its own when to call it. It uses the imports from step 2, plus community.flock.aigentic.core.annotations.Description:

// Describe the agents response type
@AigenticParameter
data class WeatherResponse(
@Description("Current temperature in degrees Celsius")
val temperature: Double,
@Description("Current weather conditions description")
val conditions: String,
@Description("Name of the location for the weather data")
val location: String
)

// Describe the agents task input type
@AigenticParameter
data class WeatherQuestion(
val city: String,
val country: String
)

suspend fun main() {

val agent = agent<WeatherQuestion, WeatherResponse> {

// Configure the Gemini model for the agent
geminiModel {
apiKey("YOUR_API_KEY")
modelIdentifier(GeminiModelIdentifier.Gemini3_5Flash)
}

// Configure the task for the agent
task("Provide weather information") {
addInstruction("Respond to user queries about weather")
}

// Add a weather tool
addTool("getWeather", "Get the current weather for a location") { req: WeatherQuestion ->
// Replace with a call to a real weather API
WeatherResponse(temperature = 14.0, conditions = "Light rain", location = req.city)
}
}

val run = agent.start(WeatherQuestion("Amsterdam", "Netherlands"))

// Print the result
when (val outcome = run.outcome) {
is Outcome.Finished -> println("Weather in ${outcome.response?.location}: ${outcome.response?.temperature}°C, ${outcome.response?.conditions}")
is Outcome.Stuck -> println("Agent is stuck: ${outcome.reason}")
is Outcome.Fatal -> println("Error: ${outcome.message}")
}
}

The run prints each step, so you can follow what the agent does:

Output (shortened)
🚀 Agent started!
🏗 Executing tool: getWeather arguments: {"city":"Amsterdam","country":"Netherlands"}
🦾 Tool result getWeather: …
🏁 Agent finished! …
Weather in Amsterdam: 14.0°C, Light rain
Don't forget the Kotlinx serialization plugin

To use the @AigenticParameter annotation, you must include the Kotlinx serialization plugin in your build configuration. This plugin generates the metadata Aigentic needs to process your custom types when communicating with LLMs.

More Examples​

The Aigentic Initializr repository contains many ready-to-use example projects, including agents for various use cases, tools implementations, and provider configurations. You can find these examples at Aigentic Initializr repository. We encourage you to explore these examples to better understand how to structure your own AI agents and integrate different tools and providers.