Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Agents in Kotlin - Building Smarter Apps with S...

Agents in Kotlin - Building Smarter Apps with Shared Codebases using KMP and Koog & Gemini and More

Kotlin Multiplatform (KMP) made it possible to share business logic across platforms. The next evolution is sharing intelligence. This session explores how AI agents can live inside shared Kotlin codebases - reasoning, planning, and acting across Android, iOS, and backend (ktor) targets.

We'll build a practical KMP app that integrates Koog, Gemini Nano, and Vertex AI, combining on-device inference with cloud-based reasoning to enable context-aware and adaptive behavior. You’ll learn how to design agent lifecycles, manage shared state and context across coroutines and Flows, and safely expose structured actions to platform layers.

We'll also cover production-ready concerns like concurrency control, observability, and debugging intelligent flows—giving you a hands-on blueprint for embedding intelligence directly into your shared Kotlin architecture.

Avatar for Rivu Chakraborty

Rivu Chakraborty PRO

November 15, 2025
Tweet

More Decks by Rivu Chakraborty

Other Decks in Technology

Transcript

  1. Agents in Kotlin Building Smarter Apps with Shared Codebases using

    KMP and Koog & Gemini and More Rivu Chakraborty
  2. WHO AM I? • GDE (Google Developer Expert) for Android

    • Previously India’s first GDE for Kotlin • More than 14 years in the Industry • Founder @ Mobrio Studio • Previously ◦ JioCinema/JioHotstar, Byju’s, Paytm, Gojek, Meesho • Author (wrote multiple Kotlin books) • Speaker • Mentor • Learning / Exploring ML/AI • Community Person (Started KotlinKolkata) • YouTuber (http://youtube.com/@RivuTalks)
  3. What All Changed in 7 years • Became a GDE

    • Changed 4 companies • Started Mobrio Studio
  4. • Led personally by me (Rivu), with my decades of

    experience of scaling 6+ unicorn startups, and many smaller ones • We do Mobile Dev tooling (products) as well as we consult with product based startups, helping them develop or scale their apps • We can help with anything to do with mobile, starting from code quality, migration, refactor to feature development • At Mobrio Studio, I have a team, who work under my direct super vision. • We don’t just develop for you, we train your team, so you’re independent in future https://mobrio.studio/
  5. Agents in Kotlin : Building Smarter Apps with Shared Codebases

    using KMP and Koog (and Gemini, and Gemma, and …)
  6. WHY THIS TALK? • GenAI & Agents are hot •

    Gemini API, Gemini Nano (Experimental) and Gemma models allow apps to use AI easily • KMP lets us build once for Android, iOS, Web & More • Koog let’s you build agents for multiple platforms • We'll walk through real code & gotchas
  7. 01 Intro to KMP 02 Intro to AI, Gemini, Gemma,

    Gemini Nano, VertexAI 03 Koog Sections of the Talk
  8. What’s KMP and Why? • A technology by JetBrains to

    share Kotlin code across platforms (Android, iOS, web, desktop, server). • Enables platform-specific UI while sharing core business logic (networking, database, state management). You control what you share and what you don’t • Write Once, Run Natively: Outputs native binaries (no VM or JS bridge).
  9. 01 True Multiplatform 02 Compiles to native (JVM Bytecode, ObjC

    bytecode or Minified JS) for platform-specific code 03 You decide how much code you want to share Want to build full app? Use Compose Multiplatform, or just share pieces of code with KMP Differences with Cross-platform 04 Interoperability Kotlin is fully interoperable with Java, it’s interoperable with JS and Objective C as well, and Swift interoperability improving with oicial Swift support
  10. A Brief on KMP Common JVM JS Native Android Server

    Apple Linux mingw iOS tvOS watchOS macOS linux_x64 linux_arm64 mingx64 iosX64 iosArm64 iosSimulatorArm64 tvosX64 tvosArm64 tvosSimulatorArm6 4 macosX64 macosArm64 watchosX64 watchosArm32 watchosArm64 watchosSimulatorArm64 watchosDeviceArm64
  11. A Brief on KMP expect fun getRandomUUID(): String actual fun

    getRandomUUID(): String = UUID.randomUUID().toString() actual fun getRandomUUID(): String = NSUUID().UUIDString() import uuid actual fun getRandomUUID(): String = uuid.v4().toString() commonMain jvmMain iosMain jsMain
  12. AI

  13. What’s AI? Algorithm Input Output Developers write explicit algorithms that

    take input and produce a desired output. 1. Train the model with large dataset of input and output 2. Model is deployed on cloud/on-device to process input data i.e. inference Traditional Programming Machine Learning ML Model Training Input ML Model Output Run ML Inference Input Output
  14. What’s GenAI? • Generative AI introduces the capability to understand

    inputs such as text, images, audio and video and generate human-like responses. • This enables applications like chatbots, language translation, text summarization, image captioning, image or code generation, creative writing assistance, and much more. • At its core, an LLM is a neural network model trained on massive amounts of text data. It learns paerns, grammar, and semantic relationships between words and phrases, enabling it to predict and generate text that mimics human language.
  15. What is GenAI in Mobile Development? • GenAI brings creative

    intelligence to mobile apps by enabling them to generate rather than just respond. • Enables hyper-personalized, intelligent, and context-aware user experiences. • Enhances accessibility, productivity, and entertainment within apps. • Can run on-device (for privacy/speed) or via cloud APIs. • In mobile apps, GenAI powers features like: a. Text generation (e.g., storytelling, smart replies, chatbots) b. Image generation/editing c. Voice synthesis (TTS)
  16. Why Gemini (by Google)? • Multimodal: Understands text, image, code,

    audio, and more. • Optimized for Android, iOS & Web • Enhances accessibility, productivity, and entertainment within apps. • Developer Friendly a. Easy-to-use libraries / APIs b. SDKs support prompting, streaming, and low-latency generation
  17. Different Ways To Integrate AI Directly in Mobile Apps 01

    Gemini API 02 Mediapipe / LLMInterference Library and Offline Model Can be used with any tflite / LiteRT Models, not Gemma Specific 03 Gemini Nano Currently Experimental, available only on Pixel 9 Devices Either Directly with GeminiAPI or By Using The Third Party Library by Shreyas 04 Firebase Vertex AI You can use Gemini APIs and models with Firebase Vertex API, reducing the need for handling intricate details yourself Koog You can use Koog, along with various LLM providers, and custom/inbuilt tools to build AI agents and use them directly in Mobile Apps 05
  18. Google Generative AI SDK for Kotlin Multiplatform by Shreyas Patil

    - hps://github.com/PatilShrey as/generative-ai-kmp API key stored in BuildKonfig Suspend function for story generation Works on Android & iOS GEMINI INTEGRATION (ONLINE)
  19. GENERATIVEMODEL IMPLEMENTATION (GEMINI) class GenerativeModelGemini(private val apiKey: String) : GenerativeModel

    { private val model by lazy { GeminiApiGenerativeModel( ... ) } override suspend fun generate(prompt: String, awaitReadiness: Boolean): Result<String> { return runCatching { val input = content { text(prompt) } val response = model.generateContent(input) response.text ?: throw UnsupportedOperationException("No text returned from model") } } } commonMain.dependencies { implementation("dev.shreyaspatil.generativeai:generativeai-google:<version>") } hps://github.com/PatilShreyas/generative-ai-kmp
  20. 01 USES MEDIAPIPE GENAI 02 TEXTGENERATOR EXPECT/ACTUAL for platform-specific code

    03 LOCALGENERATIVEMODEL wraps the logic OFFLINE MODE WITH GEMMA
  21. DOWNLOA D .TASK FILE FROM SERVER or Pack with App

    (not recommend ed) STORE IN INTERNAL APP DIRECTORY INIT MEDIAPIPE LLM AFTER DOWNLOAD COMPLETES MODEL DOWNLOAD & INITIALIZATION
  22. Init MediaPipe LLM Interference private val llmInference: LlmInference by lazy

    { val options = LlmInference.LlmInferenceOptions.builder() .setModelPath(modelFile.absolutePath) .setMaxTokens(1024) .setMaxTopK(40) .build() LlmInference.createFromOptions(context, options) }
  23. Generation Settings GeminiApiGenerativeModel( modelName = "gemini-2.0-flash", apiKey = apiKey, generationConfig

    = GenerationConfig.Builder().apply { topK = 40 } .build() ) private val llmInference: LlmInference by lazy { val options = LlmInference.LlmInferenceOptions.builder() .setModelPath(modelFile.absolutePath) .setMaxTokens(512) .setMaxTopK(40) .build() LlmInference.createFromOptions(context, options) }
  24. Generation Settings GeminiApiGenerativeModel( modelName = "gemini-2.0-flash", apiKey = apiKey, generationConfig

    = GenerationConfig.Builder().apply { topK = 40 } .build() ) private val llmInference: LlmInference by lazy { val options = LlmInference.LlmInferenceOptions.builder() .setModelPath(modelFile.absolutePath) .setMaxTokens(512) .setMaxTopK(40) .build() LlmInference.createFromOptions(context, options) }
  25. TopK • Top-K filters tokens for output. • For example

    a Top-K of 3 keeps the three most probable tokens. • Increasing the Top-K value will increase the randomness of the model response.
  26. maxTokens • Limits the maximum output length a model can

    generate • A token can be a whole word, part of a word (like "ing" or "est"), punctuation, or even a space. The exact way text is tokenized depends on the specific model’s tokenizer. • Whenever we call llmInference.generateResponse(prompt), the response generated by the local model will contain at most 512 tokens.
  27. Integrate Gemini Nano generativeModel = try { val generationConfig =

    generationConfig { context = getApplication<Application>().applicationContext temperature = 0.2f topK = 40 maxOutputTokens = 1024 } val downloadConfig = DownloadConfig( object : DownloadCallback { isReady.update { true } } ) GenerativeModel( generationConfig = generationConfig, downloadConfig = downloadConfig ) } catch (e: Exception) { Log.e("MainViewModel", "Failed to initialize AI Core: ${e.message}") null }
  28. Integrate Gemini Nano val generationConfig = generationConfig { context =

    getApplication<Application>().applicationContext temperature = 0.2f topK = 40 maxOutputTokens = 1024 }
  29. Vertex AI Google Recommends using Vertex AI in Firebase SDK

    for Android to access the Gemini API and the Gemini family of models directly from the app.
  30. Vertex AI implementation("com.google.firebase:firebase-vertexai:$version") class GenerativeModelVertex() : GenerativeModel { val generativeModel

    = Firebase.vertexAI.generativeModel("gemini-2.5-flash") override suspend fun generate(prompt: String, awaitReadiness: Boolean): Result<String> { return runCatching { model.generateContent(prompt) } } }
  31. Koog Koog is a Kotlin-based framework designed to build and

    run AI agents entirely in idiomatic Kotlin. It lets you create agents that can interact with tools, handle complex workflows, and communicate with users. https://docs.koog.ai/
  32. Koog implementation("ai.koog:koog-agents:0.5.2") suspend fun runAgent(prompt: String): String { return try

    { val agent = AIAgent( promptExecutor = simpleGoogleAIExecutor(apiKey), llmModel = GoogleModels.Gemini2_5Flash, systemPrompt = systemPrompt ) val result = agent.run(prompt) result } catch (e: Exception) { "Koog Agent Error: ${e.message}\n${e.stackTraceToString()}" } }
  33. Koog - tools • The AI Agent is the "Brain"

    • Tools are the "Hands" and "Eyes" • Example: The "Search" Tool • The AI is the "Smart Foreman" • Why It Maers: Without tools, an AI is just a fancy encyclopedia. With tools, an AI becomes a real personal assistant that can find current information and actually get things done for you in the real world.
  34. Koog - Tools Agents use tools to perform specific tasks

    or access external systems. expect class DatabaseOperationsToolSet( repository: YourRepository ) { suspend fun someDBOperation(): Result /** * Convert to Koog tools */ fun toTools(): List<Tool<*, *>> }
  35. Koog - Tools Android/JVM @LLMDescription("Meaningfull description of the class/toolset") expect

    class DatabaseOperationsToolSet( repository: YourRepository ) : ToolSet { { @Tool @LLMDescription("Meaningfull description of the function/operation") suspend fun someDBOperation(): Result {...} fun toTools(): List<Tool<*, *>> {...} }
  36. Koog - Tools Common private fun createAgent(): AIAgent<String, String> {

    return AIAgent( promptExecutor = MultiLLMPromptExecutor( GoogleLLMClient(apiKey) ), systemPrompt = """ ---Your System Prompt--- """.trimIndent(), llmModel = GoogleModels.Gemini2_5FlashLite, toolRegistry = dbToolRegistry ) }
  37. Koog - Memory • Your Brain vs. A Goldfish: By

    default, a simple AI is like a goldfish. • Memory is the "Notepad" • It Remembers "You" , it Remembers "What It Did" • Short-Term vs. Long-Term • Why It Maers: Without memory, an AI is just a tool. With memory, it becomes a personal assistant that gets smarter and more helpful the more you interact with it.
  38. Koog - Memory • Facts: This is the actual piece

    of information being saved. It’s the "note" itself. Koog has two types. ◦ SingleFact: For one piece of info (e.g., "User’s preferred theme is Dark"). ◦ MultipleFacts: For a list of info (e.g., "User knows Kotlin, Java, and Python"). • Concepts: This is the label or category for the fact. It’s like the heading on a page in the notepad. • Subjects: This is who or what the fact is about. It’s like the label on the "file drawer."
  39. Koog - Memory The AgentMemory Feature addresses the challenge of

    maintaining context in AI agent install(AgentMemory) { agentName = "query-agent" featureName = "natural-language-search" organizationName = "mobrio-studio" productName = "files-plus" memoryProvider = FilesPlusMemory.memoryProvider }
  40. Koog - Memory The AgentMemory Feature addresses the challenge of

    maintaining context in AI agent FilesPlusMemory.memoryProvider.save( fact = SingleFact( value = response, concept = responseConcept, timestamp = Clock.System.now().toEpochMilliseconds(), ), subject = User, scope = MemoryScope.Product("files-plus"), )
  41. Koog - Strategy • The "Strategy" is the AI’s "Recipe"

    or "Plan": If the AI is the "foreman" (brain), the tools are the "hands," and the memory is the "notepad," the strategy is the detailed, step-by-step "workflow" or "recipe" the foreman follows to get a job done.
  42. Koog - Strategy • Koog’s "Strategy Graph": In Koog, you

    don’t just write a simple list. You build a "Strategy Graph"—think of it as a flowchart for the AI’s "recipe." This lets you create very smart and complex plans. • Nodes (The Steps): The "Nodes" are the boxes in the flowchart. Each node is one action in the recipe. • Edges (The Arrows): The "Edges" are the arrows that connect the boxes. They show the agent which step to do next. • Subgraphs are "Recipe" Inside a "Recipe"
  43. Koog - Strategy val myStrategy = strategy<String, String>("my-strategy") { val

    nodeCallLLM by nodeLLMRequest() val executeToolCall by nodeExecuteTool() val sendToolResult by nodeLLMSendToolResult() edge(nodeStart forwardTo nodeCallLLM) edge(nodeCallLLM forwardTo nodeFinish onAssistantMessage { true }) edge(nodeCallLLM forwardTo executeToolCall onToolCall { true }) edge(executeToolCall forwardTo sendToolResult) edge(sendToolResult forwardTo nodeFinish onAssistantMessage { true }) edge(sendToolResult forwardTo executeToolCall onToolCall { true }) }
  44. Koog - Strategy val nodeProcessQuery by subgraph<String, String> { val

    processQuery by nodeLLMRequest() val executeToolCall by nodeExecuteTool() val sendToolResult by nodeLLMSendToolResult() val processToolResult by node<Message.Response, String> { input -> input.content } edge(nodeStart forwardTo processQuery) edge(processQuery forwardTo executeToolCall onToolCall { true }) edge(executeToolCall forwardTo sendToolResult) edge(sendToolResult forwardTo processToolResult) edge(processToolResult forwardTo processQuery) edge(processQuery forwardTo nodeFinish onAssistantMessage { true }) }
  45. COCOAPODS INTEGRATION FOR IOS Cocoapods integration for iOS is deprecated

    MEDIAPIPE GENAI MediaPipe GenAI supports Android, iOS and Web, however integrating it with KMP is challenging CHALLENGES FACED Koog Agents Using Koog makes building and using agents or even just calling any prominent LLM very easy in Mobile or any platform
  46. It’s easy to integrate GenAI with your KMP apps LLM

    Interference / MediaPipe works but its’ not for most of the usecases Code reusability across platforms with KMP KEY TAKEAWAYS Gemini Nano can be a game changer Koog makes it even easier