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

Ktorで簡単AIアプリケーション

 Ktorで簡単AIアプリケーション

Avatar for Keita Tsukamoto

Keita Tsukamoto

October 13, 2025
Tweet

More Decks by Keita Tsukamoto

Other Decks in Programming

Transcript

  1. 自己紹介 名前・所属 塚本 啓太( @tsukakei1012 ) 株式会社スマートラウンド 執行役員VPoE サーバーサイドKotlin歴 ここ5年くらいずっとKotlinでやっています!

    2019-04~2023-10 株式会社イエソド テックリード 2023-10~ 株式会社スマートラウンド 2024-01~2025-06 テックリード:サービス開発、イネーブルメント担当 2025-07~ 執行役員VPoE:開発部全体のマネジメント 2
  2. AIエージェント エージェントとは、LLM が自律的に自らのプロセスやツールの使用方法を動的に制御 し、どのようにタスクを達成するかを自分で管理するシステムのことを指す。 Agents, on the other hand, are

    systems where LLMs dynamically direct their own processes and tool usage, maintaining control over how they accomplish tasks. from Building effective agents by Anthropic https://www.anthropic.com/engineering/building-effective-agents 7
  3. Koogで簡単なエージェント まずはやってみよう! val agent = AIAgent( promptExecutor = simpleOpenAIExecutor(System.getenv("YOUR_API_KEY")), systemPrompt

    = "You are a helpful assistant. Answer user questions concisely.", llmModel = OpenAIModels.Chat.GPT4o ) fun main() = runBlocking { val result = agent.run("Hello! How can you help me?") } ね、お手軽でしょ? 11
  4. マルチモーダル対応 画像・音声・映像・ファイルに対応 val prompt = prompt("multimodal_input") { system("You are a

    helpful assistant.") user { +"Describe these images" attachments { image("https://example.com/test.png") image(Path("/User/koog/image.png")) } } } 13
  5. 構造化出力 データクラスを定義するだけ(Webアプリと同様ですね) @Serializable @SerialName("WeatherForecast") @LLMDescription("Weather forecast for a given location")

    data class WeatherForecast( @property:LLMDescription("Temperature in Celsius") val temperature: Int, @property:LLMDescription("Weather conditions (e.g., sunny, cloudy, rainy)") val conditions: String, @property:LLMDescription("Chance of precipitation in percentage") val precipitation: Int ) 14
  6. ワークフロー ワークフロー定義用のDSLが整備されている // Basic edge edge(sourceNode forwardTo targetNode) // Edge

    with condition edge(sourceNode forwardTo targetNode onCondition { output -> // Return true to follow this edge, false to skip it output.contains("specific text") }) // Edge with transformation edge(sourceNode forwardTo targetNode transformed { output -> // Transform the output before passing it to the target node "Modified: $output" }) // Combined condition and transformation edge(sourceNode forwardTo targetNode onCondition { it.isNotEmpty() } transformed { it.uppercase() }) 15
  7. Tracing① これだけで各イベントごとにログを吐いてくれる val agent = AIAgent( promptExecutor = simpleOllamaAIExecutor(), llmModel

    = OllamaModels.Meta.LLAMA_3_2, ) { install(Tracing) { addMessageProcessor(TraceFeatureMessageLogWriter(logger)) } } 16
  8. Tracing② OpenTelemetryやLangFuse対応も簡単 val agent = AIAgent( promptExecutor = simpleOpenAIExecutor(apiKey), llmModel

    = OpenAIModels.Chat.GPT4o, systemPrompt = "You are a helpful assistant.", installFeatures = { install(OpenTelemetry) { // Configuration options go here // LangFuseにも対応 // addLangfuseExporter() } } ) 17
  9. Ktorとのインテグレーション② ルーティングファイル routing { route("/ai") { post("/chat") { val userInput

    = call.receive<String>() val output = aiAgent( strategy = reActStrategy(), model = OpenAIModels.Chat.GPT4_1, input = userInput ) call.respond(HttpStatusCode.OK, output) } } } 20