Slide 1

Slide 1 text

KoogではじめるAIエージェント開発 Getting Started with AI Agent Development in Koog 1 Nosho Hiroaki Kotlin Fest 2025 2025/11/1

Slide 2

Slide 2 text

● AIエージェントを「使う」ではなく「作る」話 ● 開発のハードルは下がってきている ○ AIエージェントを作るフレームワークが発展してきた ● AIエージェントを作る機会がない方...大丈夫です👍 ○ どうやって作るかを理解すると、 AIエージェントの中を想像できるようになる AIエージェントを作ってみよう 2

Slide 3

Slide 3 text

自己紹介 ● Nosho Hiroaki ● Android Engineer/Kotlin歴が長い ● 社内向けのAI/DXアプリの開発(フルスタック) ● 趣味: AIを使った個人アプリ 3 X: @hiroaki08181359 GitHub: hiroaki404 スライド資料

Slide 4

Slide 4 text

話すこと ● AIエージェントとは ● Koogの基本 ● 他のフレームワークとの比較 ● Koogの機能、ワークフロー ● 実践例(Koogを活用したAIエージェント事例) 4 スライド資料

Slide 5

Slide 5 text

AIエージェントとは? 5

Slide 6

Slide 6 text

AIエージェントとは?(1/3) "Agent" can be defined in several ways. Some customers define agents as fully autonomous systems that operate independently over extended periods, using various tools to accomplish complex tasks. Others use the term to describe more prescriptive implementations that follow predefined workflows. … by Anthropic Building effective agents https://www.anthropic.com/engineering/building-effective-agents 6 定義は様々 自律的に動く ツール 複雑なタスク ワークフロー

Slide 7

Slide 7 text

AIエージェントとは?(2/3) ● AIエージェントかどうかは二択でではなく、 どれくらいエージェンティックに動くか、というグラデーションで考える ● エージェントらしいエージェントは、人間の指示がなくても、 自律的に動き、ツールを使い、より複雑なタスクをこなす ● (このあたりはKoogのKotlinConfのセッションでも言及されています ) 7 Building AI Agents in Kotlin with Koog https://www.youtube.com/watch?v=O8WQCrdza8E

Slide 8

Slide 8 text

AIエージェントとは?(3/3) 8 以前のAI Coding Coding Agent 🔎 🧠 🔧 🧠 Read/Write/ Shell/Search.. Application Plan, Observe, Reasoning.. ClaudeCode等

Slide 9

Slide 9 text

● 業務の自動化(文書作成、 経理処理、社内情報検索...) ● カスタマーサービス ● Deep Research ○ 複数のエージェントが協調する リサーチ ● BtoCアプリ(旅行AI、料理レシピAI…) ● (※ChatGPTやGeminiもAIエージェント) AIエージェントでできること 9 旅行AIエージェント

Slide 10

Slide 10 text

AIエージェントを作るメリット ● すでにある汎用的なAIエージェントは使えないのか? ○ ChatGPT, Gemini, Claude Desktop, Gemini CLI, Claude Code… ● 不安定な出力を制御し、特定タスクでの精度/効率を高める ○ 汎用的なエージェントはときに不安定で効率が悪い ○ 特定タスクに特化したエージェントワークフローで、安定した結果を得る ○ 無駄な出力を抑えて費用の節約にもなる 10

Slide 11

Slide 11 text

Koogとは 11

Slide 12

Slide 12 text

Koogとは(1/2) ● 🚀 JetbrainsがKotlin Conf 2025(5月)で発表 ● KotlinでAIエージェントを構築・実行するライブラリ ○ シンプルなLLM呼出し・エージェント 〜複雑にカスタマイズしたワークフロー ○ Open Source 12 https://github.com/JetBrains/koog

Slide 13

Slide 13 text

Koogとは(2/2) ● Koogが作られた背景 ○ JetbrainsはAIに力を入れている ○ Muellum/Junieなどの開発で培ったノウハウをKoogの開発に活かしている ○ 既存のフレームワークの不便を解消している ○ 一部Jetbrains製品でKoogを採用 ● ⚠ ここから先はバージョン0.5.2の情報です 13

Slide 14

Slide 14 text

● ✅ Pure Kotlinであること ○ (AI関連のフレームワークはPythonが多い) ● ✅ 静的型付けでありシステム開発に有利 ○ プロトタイプ以上の、信頼性・保守性が求められるシステムに ● ✅ AIコードとアプリケーションのコードをすべてKotlinで作れる ○ AIがPythonだとアプリケーションのコードで言語が違う問題 ○ 接続の手間、開発者が複数の言語を読む負荷 ○ KotlinだとAI、Backend、UIすべてKotlinで作れる Pure Kotlin framework(1/2) 14

Slide 15

Slide 15 text

● ✅ Kotlin-DSLを使ったワークフロー(グラフ構造)の表現 ○ Nodeの関係や処理の流れが分かりやすい ○ 他のフレームワークにはない良さ edge(nodeStart forwardTo nodeCallLLM) edge(nodeCallLLM forwardTo nodeExecuteTool onToolCall { true }) edge(nodeCallLLM forwardTo nodeFinish onAssistantMessage { true }) edge(nodeExecuteTool forwardTo nodeSendToolResult) edge(nodeSendToolResult forwardTo nodeFinish onAssistantMessage { true }) edge(nodeSendToolResult forwardTo nodeExecuteTool onToolCall { true }) Pure Kotlin framework(2/2) 15

Slide 16

Slide 16 text

Koog Overview(1/2) ● ✅ 幅広いモデル ○ Google, OpenAI, Anthropic, OpenRouter, DeepSeek, Bedrock, AzureOpenAI, MistralAI, Ollamaに対応(ローカルLLMも可) ● ✅ シンプルな構築から複雑なカスタマイズまで ○ 事前定義されたワークフローで簡単にエージェントを構築 ● ✅ 本番環境での運用 ○ チェックポイント、副作用のあるツールのロールバックがあり 障害に強い 16

Slide 17

Slide 17 text

Koog Overview(2/2) ● ✅ Multiplatform support ○ Kotlin Multiplatformに対応(JVM, JS, WasmJS, iOS, 他も追加予定) ● ✅ Server Side Support ○ Ktor, Spring Boot plugin ● IDE support ○ Jetbrainsの製品でサポートが入る予定 17

Slide 18

Slide 18 text

他のフレームワークとの比較 18

Slide 19

Slide 19 text

他のフレームワーク LangChain LangGraph AutoGen Koog Genkit Firebase AI Logic 19 Agent Developer Kit Bedrock LangChain4j and more.. CopilotStudio Dify SpringAI Mastra Strands Agents Embabel AgentKit フレームワーク選定の観点を取り上げ、 Koogの立ち位置を捉える VoltAgent AgentCore Agent Service Agent Engine Vertex AI CrewAI

Slide 20

Slide 20 text

フレームワーク選定の観点 ● プログラミング言語 ● フレームワークの成熟(機能は十分か、リソースが多いか) ● クラウドベンダー提供のものか ● 開発者支援が充実しているか ● シンプルにLLMを使うものか、エージェント、マルチエージェント ● ノーコード/ローコード 20

Slide 21

Slide 21 text

LangChain/LangGraph 21 ● ☑ リソースや活用事例が多い ○ 機能が豊富、基準となるフレームワーク ● Python/JavaScript/TypeScript ● LangChain/LangGraph(OSS) + LangSmith(Commercial) ○ LangChain: シンプルなチェーン、LCEL記法(パイプで処理を繋ぐ)、エージェント ○ LangGraph: グラフ構造の複雑なワークフロー

Slide 22

Slide 22 text

Python以外のフレームワーク ● 現状Pythonフレームワークが主流 ○ しかし他の言語のフレームワークも作られてきている ● Koog以外の非Python系 ○ Mastra, VoltAgent(TypeScript) ○ Spring AI, LangChain4j(Java) ○ (※複数の言語に対応しているフレームワークもあります ) 22

Slide 23

Slide 23 text

● GoogleのAIアプリケーション構築 するOSSフレームワーク(Node等) ● ☑ 開発者UIがコマンド一つで ● 開発者支援ツールも選定の 観点の一つ Genkit 23 開発者UI https://genkit.dev/

Slide 24

Slide 24 text

Cloud Vendor Framework(Google, Amazon, Microsoft) ● エージェントフレームワーク : Agent Developer Kit, Autogen, Strands Agents ● モデルのAPI: Vertex AI, Azure OpenAI, Bedrock ● プラットフォーム(deploy,no-code):Agent Engine, Agent Service, AgentCore, Bedrock Agent ● 「モデルのAPI」は他のフレームワークとの 併用可能 ○ BedrockやAzure OpenAIはKoogでもすぐに使える ● ☑ クラウドと親和性が高い ○ 安全性、セキュリティ、デプロイ、ポータル機能(Playground、トレース)を気軽に利用可能 ● 特定のクラウドにある程度依存する可能性がある ○ モデルの制約、クラウドの知識もある程度必要 ● (※大雑把な分類なのでご注意ください。クラウドに依存することによる制約は限定的なこともあります ) 24

Slide 25

Slide 25 text

他のフレームワークと比較したKoogの特徴 ● ✅ プログラミング言語: Kotlin ● ✅ 開発しやすさ、スケーラビリティ ● ✅ 豊富な機能、実用面を重視した機能 ● ✅ 再利用可能なワークフロー、本番運用、Kotlin DSL、Multiplatform ● ➡ クラウドベンダーに依存しないフレームワーク ○ Koogはエージェントを構築するライブラリ ○ 🚧 クラウド連携も計画されいてる(Agent Engine, AgentCore) ● 🚧 開発環境: 現状単独の開発支援のツールは少ないので他と組み合わせる ○ ただしIDEのデバッグツールが近日公開される予定だそうです 25

Slide 26

Slide 26 text

🧪 開発環境 ● 開発環境は早めに整える ● Langfuseと簡単に統合し トレース可能 ○ ※OpenTelemetryに対応 ● KotlinNotebookはLLM応答をさっ と確認、出力を保存/共有 26 Langfuse https://langfuse.com/ KotlinNotebook

Slide 27

Slide 27 text

⚠ Risk ● APIの不正利用 ○ API Keyはハードコードせず安全に管理 ● Prompt Injection ○ 不正な命令でシステムを乗っ取る攻撃 ● Harmful Output ○ 倫理的に良くない等有害なコンテンツの生成 ● (※Koogに限らず他のフレームワークでも注意する) ● 対策: ガードレール、多層防御の考え方... 27

Slide 28

Slide 28 text

📒 Catch Up ● ✅ 公式リソースが充実していて始めやすい ● 公式ドキュメント(設計のベストプラクティスも ) ○ https://docs.koog.ai/ ○ https://www.jetbrains.com/koog/ ● 公式リポジトリ(数十のサンプル、テスト、 Androidなど) ○ https://github.com/JetBrains/koog ● 開発者の記事 ○ https://medium.com/@vadim.briliantov ● Youtube(Jetbrains/Kotlin Conf、最後の参考文献にリンクあり) ● Slack Channel ● Koogに限定せず、並行してLangChainやクラウド系に触れるのもあり 28

Slide 29

Slide 29 text

Koogの基本 29

Slide 30

Slide 30 text

LLMの実行手段 ● LLMClient, PromptExecutor, AIAgent ● LLMClientが最も基本的なLLMを 呼び出す主体 ● LLMClient, PromptExecutorは 直接使える 30

Slide 31

Slide 31 text

LLMClient, PromptExecutor ● シンプルにLLMを呼び出す ○ Prompt API(Kotlin DSL) ● PromptExecutorは複数の Providerを扱える ○ 処理によって別のプロバイダーの モデルを使い分けることが可能 ○ (※同一Provider内のモデル切り替えは LLMClientでも可能) ○ CachedPromptExecutorは プロンプトをキャッシュしておき 同じ入力が来たときに使う 31 複数のProvider val executor = simpleOpenAIExecutor(apiKey) val prompt = prompt { system("You are a helpful assistant. Answer user questions concisely.") user("Hello! How can you help me?") } executor.execute(prompt) // Hello! How can I assist you today? val multiExecutor = MultiLLMPromptExecutor( LLMProvider.OpenAI to openAIClient, LLMProvider.Ollama to ollamaClient ) PromptExecutor

Slide 32

Slide 32 text

🤖 Agent ● ワークフロー、ツールを使う ● 数行で簡単に使える ● strategyなしだとデフォルトの SingleRunStrategyになる ○ strategy: ワークフローを定義 するもの val agent = AIAgent( promptExecutor = simpleOpenAIExecutor(apiKey), llmModel = OpenAIModels.Chat.GPT4o ) val result = agent.run("Hello! How can you help me?") 32 エージェント val agent = AIAgent( promptExecutor = executor, strategy = customStrategy, llmModel = OpenAIModels.Chat.GPT4o toolRegistry = toolRegistry ) Custom Strategy Tool シンプルな例 CustomStrategy, Toolあり

Slide 33

Slide 33 text

🔧 Tool ● AIエージェントが使うツールを定義 ○ 定義済み(組込み)ツールもある ○ Annotation based/Class based ○ 後者のほうが高度な制御が可能 ● LLMは使うツールとパラメータを 決定するだけ ○ LLMから受けたパラメータをもとに アプリケーションがツールを実行する ● @LLMDescriptionでToolの情報を LLMに教える @LLMDescription("Tools for controlling a switch") class SwitchTools(val switch: Switch) : ToolSet { @Tool @LLMDescription("Switches the state of the switch") fun switch( @LLMDescription("The state to set(true for on, …)") state: Boolean ) { switch.switch(state) } } 33 Toolの説明 パラメータの説明

Slide 34

Slide 34 text

Koogの機能 34

Slide 35

Slide 35 text

Koogの主要機能 ● Structured Output(構造化出力) ● History Compression ● Streaming ● Parallel ● Embeddings ● MCP ● A2A protocol ● Features: Tracing, Memory, Persistence ● など 35

Slide 36

Slide 36 text

構造化出力 ● LLMのテキスト応答を 特定のクラスにパース ● 構造化しやすくするLLMへの説明 ● 成功率を上げるため ○ 例を渡す ○ デフォルト値 ○ パース用モデル ○ リトライ回数 36 @Serializable @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 ) LLMへの説明 val getWeatherForecast by nodeLLMRequestStructured( name = "forecast-node", examples = exampleForecasts, fixingParser = StructureFixingParser( fixingModel = OpenAIModels.Chat.GPT4o, retries = 3 ) ) 例を渡す パース用モデル、リトライ回数 構造の定義 構造化実行

Slide 37

Slide 37 text

History Compression ● Agent内部の会話履歴を圧縮する ● LLMの集中力⬆ トークンコスト⬇ ● 圧縮戦略 ○ TLDR, Concept/Fact, チャンク, 最後のN個 37 val compressHistory by nodeLLMCompressHistory() … edge(callLLM forwardTo executeTool onToolCall { true }) edge(executeTool forwardTo compressHistory onCondition { historyIsTooLong() }) edge(compressHistory forwardTo sendToolResult) edge(executeTool forwardTo sendToolResult onCondition { !historyIsTooLong() }) … 履歴圧縮用Node

Slide 38

Slide 38 text

● チェックポイント ○ エージェントの状態を保存/中断して再開 ○ 会話履歴、状態、ワークフローの進捗を 保存 ● 保存先 ○ InMemory, File, Custom(DB, CloudStorage) ● enableAutomaticPersistence ○ 自動保存 ○ 任意のタイミングでの保存も可 💾 Persistence(Check Point) 38 val agent = AIAgent( promptExecutor = executor, llmModel = OllamaModels.Meta.LLAMA_3_2, ) { install(Persistence) { storage =     InMemoryPersistenceStorageProvider() enableAutomaticPersistence = true } } 自動保存 保存先

Slide 39

Slide 39 text

ワークフロー 39

Slide 40

Slide 40 text

Strategy ● Strategy: エージェントが入力から結果を出力するまでのプロセスを表す概念 ○ GraphStrategy, FunctionalStrategy(v0.5.0~) ○ FunctionalStrategyはifやwhileなど普通の関数のようにロジックを記述 ■ Prototype用途 ■ チェックポイントやトレースが使えない ● GraphStrategy: グラフ構造でワークフローを定義 (※ここで言うワークフローは Anthropicの言うワークフローより、エージェントを含む広い範囲を含めます ) 40

Slide 41

Slide 41 text

Graph ● Node: 特定の操作 ○ Ask LLM, Call Tool, Update Prompt… ● Edge: Node間の関係 ● 会話履歴やコンテキストは 自動で管理される 41

Slide 42

Slide 42 text

ワークフローのDSL 42 Nodeの接続 edge(nodeStart forwardTo nodeAskLLM) edge(nodeAskLLM forwardTo nodeCallTool onToolCall { true }) edge(nodeAskLLM forwardTo nodeFinish onAssistantMessage { true }) edge(nodeCallTool forwardTo nodeSendToolResult) edge(nodeSendToolResult forwardTo nodeFinish onAssistantMessage { true }) edge(nodeSendToolResult forwardTo nodeCallTool onToolCall { true }) 条件分岐 条件分岐

Slide 43

Slide 43 text

edge(nodeStart forwardTo nodeAskLLM) edge(nodeAskLLM forwardTo nodeCallTool onToolCall { true }) edge(nodeAskLLM forwardTo nodeFinish onAssistantMessage { true }) edge(nodeCallTool forwardTo nodeSendToolResult) edge(nodeSendToolResult forwardTo nodeFinish onAssistantMessage { true }) edge(nodeSendToolResult forwardTo nodeCallTool onToolCall { true }) ワークフローのDSL 43 nodeStart then nodeAskLLM thenはedge/forwartToの シンタックスシュガー edge(someProcess forwardTo nodeFinish onCondition { it.isSuccess } transformed { it.getOrThrow().structure }) 出力変換 条件分岐

Slide 44

Slide 44 text

● LLMの処理、それ以外の様々な処理 ○ prompt更新、ツールの実行、ログ出力、 path-through… ● 定義済みのNode ○ nodeLLMRequest, nodeLLMRequestStructured, nodeLLMRequestStreaming, nodeLLMCompressHistory, nodeExecuteTool, nodeSendResult, nodeDoNothing… ● or CustomNode Nodeについて 44

Slide 45

Slide 45 text

入出力の型 45 strategy("single_run") { val nodeAskLLM by nodeLLMRequest() val nodeCallTool by nodeExecutorTool() edge(nodeStart forwardTo nodeAskLLM) edge(nodeAskLLM forwardTo nodeCallTool onToolCall { true }) … } 入力型 出力型 val nodeAskLLM by node { input -> llm.writeSession { updatePrompt { user(input) } requestLLM() } } 入力型 出力型 Strategyの型 Nodeの型

Slide 46

Slide 46 text

Custom Node ● LLM Session: LLMと構造化された方 法で対話する概念 ○ 排他制御で安全 ○ 処理は短く終わる必要がある ● Message型: LLMの会話の単位 ○ System, User, Assistant, Tool ○ LLMへのメッセージの抽象化 ● updatePrompt: メッセージの追加 ○ 全置き換えにはrewritePrompt 46 val nodeAskLLM by node { input -> llm.writeSession { updatePrompt { user(input) } requestLLM() } } LLMSession LLM呼び出し prompt更新

Slide 47

Slide 47 text

ワークフローの設計方針 47

Slide 48

Slide 48 text

なぜワークフロー設計は重要? 48 ● LLMは期待通りに動かない ● 期待通りいかないときデバッグが大変 ● 無限ループ ● 時間がかかる ● 制御しやすさ ● 効率性

Slide 49

Slide 49 text

ワークフロー設計指針(1/3) ● シンプルにする ○ 複雑なグラフは人間にとって分かりづらく、トレースも難しくなる ○ 複雑なワークフローに頼らずプロンプトの工夫を優先 ● 人間が理解しやすくする ○ ノードとエッジにわかりやすい名前 ○ ワークフローを可視化してドキュメント化 (Mermaid, Miro…) 49

Slide 50

Slide 50 text

● SubGraph ○ ワークフローの一部を カプセル化 ○ 再利用性 ○ 可読性 ワークフロー設計指針(2/3) 50

Slide 51

Slide 51 text

ワークフロー設計指針(3/3) ● Strategy, SubGraph, Nodeは定義済み(組込み)のものを優先 ○ Stretegy ■ SingleRunStrategy/ChatStrategy/ReActStrategy ○ SubGraph ■ SubGraphWithTask/SubGraphWithRetry/SubGraphWithVerification… ○ ワークフローやプロンプトが最適化されている ○ 多くのユースケースは定義済みのもので十分 ■ デフォルトのSingleRunStrategyにtoolを渡すだけでもOK ● 並列化: LLMの応答は時間がかかるので、並列化 51

Slide 52

Slide 52 text

SubGraph or マルチエージェント ● マルチエージェント: 複数エージェントで特定のタスクに専念させる ● 会話履歴を共有するか ○ SubGraph: 共有する、マルチエージェント: 共有しない ○ 以前の会話を踏まえたいか、コンテキストを限定したいか ● Koogのマルチエージェント ○ AIAgentService.createAgentToolで、Toolとして呼びだす ○ A2A (Agent-to-Agent) protocolにも対応 ■ (他のエージェントと通信するプロトコル ) 52

Slide 53

Slide 53 text

実践方法 (個人的に作った翻訳ツールと旅行AIエージェントの紹介) 53 ※次からの説明は一部簡略化している部分が含まれます

Slide 54

Slide 54 text

🌍 翻訳CLIツール ● 翻訳までの手数を減らす ● ☑ CLIツールなのでターミナルで完結、パイプ対応 ● ☑ ソース言語とターゲット言語を自動で特定 ● ☑ 言語コードを覚えなくて良い ● ☑ 要約機能 ● ☑ モデル選択可能 ● ☑ 長文対応: LLMには入力トークン長に限りがあるので対応が必要 54 https://github.com/hiroaki404/gentrans

Slide 55

Slide 55 text

55

Slide 56

Slide 56 text

どう作るか(1/2) ● 最もシンプルな実装: PromptExecutorでシンプルにLLM を呼び出す ● 他の機能のためワークフローを定 義した 56 val input = "Koogは素晴らしいフレームワークです。 " val res = executor.execute( prompt = prompt("prompt") { system ("You are a helpful translator.") user("Translate this to English: ${input}") }, // model… ) println(res.last().content) // Koog is a wonderful framework. 入力 Template

Slide 57

Slide 57 text

設計したグラフ 57 要約Option あり テキスト分割 翻訳前の言語の検出 翻訳後の言語の検出 長文用ループ

Slide 58

Slide 58 text

ワークフロー 58 nodeStart then detectSourceLanguage then decideTargetLanguage if (shouldSummary) { /* summaryByLLM nextChunk to TranslateByLLM to FinalizeSummary */ } else { decideTargetLanguage then translateByLLM } edge(translateByLLM forwardTo finalizeTranslation onCondition { it.inputTexts.isEmpty() }) edge(translateByLLM forwardTo translateByLLM onCondition { it.inputTexts.isNotEmpty() }) edge(finalizeTranslation forwardTo nodeFinish) 長文チャンクがなくなるまで

Slide 59

Slide 59 text

● ローカルLLM対応 ○ 簡単なタスクに分割 ● LLMの長文翻訳のパターン ○ Stuff, Map, Reduce, Refine ■ (要約を翻訳の前後どちらでやるかのパターンもある ) ○ LLMのタスクごとに研究されたパターン を探してみると良い ● 改善点 ○ 長文のパフォーマンスのための翻訳処理の並列化 ■ Koogには並列化のノードがある ○ エージェント機能(例: Androidの文字リソースの翻訳ファイル作成 ) 工夫した所/改善すべきポイント 59

Slide 60

Slide 60 text

旅行AIエージェント 60

Slide 61

Slide 61 text

旅行AIエージェント ● 旅行プランを立てるエージェント ● ComposeのUI(Multiplatform) ● 旅行の位置情報を地図上に視覚的に表示 ● 処理の流れ ○ 1⃣ユーザーの要望を聞き出す ○ 2⃣旅行計画を立てる ○ 3⃣ユーザーの承諾を取ってカレンダーに登録する ● 外部ツール連携(Web検索、カレンダー登録、Mapbox API) 61 https://github.com/hiroaki404/trip-ai

Slide 62

Slide 62 text

62

Slide 63

Slide 63 text

63 Google Calendarに登録

Slide 64

Slide 64 text

どう作るか/設計したグラフ 64 🔧 WebSearch   MapTool 2⃣旅行プラン作成 TripPlanクラス にパース 1⃣要望明確化 🔧 AskTool Human in the Loop 3⃣評価 🔧 Feedback Calendar Human in the Loop subGraphにはビルドインの subGraphWithTaskを利用

Slide 65

Slide 65 text

サブグラフ 65 val planTrip by subgraphWithTask( tools = webSearchTools.asTools() + directionsTool, ) { requestInfo -> planTripPrompt(requestInfo) } 事前定義されたSubGraph clarifyUserRequest then planTrip then nodeStructuredOutput Nodeと同様に ワークフローに組み込める Tool

Slide 66

Slide 66 text

● ツール利用を最適化するプロンプト ○ LLMはツールを使わずに応答しがち ○ ワークフローの中のプロンプトは、 細かく指示を出すと成功する ○ ツール利用の義務付け、使用回数の目安 を指示 ● サブグラフに与えるツールを限定 ○ ツールを与えすぎるとLLMが混乱する ● 改善点 ○ 他のツールを使う ■ 天気予報、フライト予約、自社 API(ホテル予約、記事のブックマーク ...) 工夫した所/改善すべきポイント 66

Slide 67

Slide 67 text

● 社内システム、エンタープライズアプリケーション ○ 出張精算AI、料理レシピAI… ● サーバーサイド(Ktor, Spring Boot) ○ SSE(Server-Sent Events)でツール呼び出しなど途中の状態を返す ○ Streaming(LLMの応答を少しずつ返す) 応用のアイデア 67

Slide 68

Slide 68 text

エージェントのデザインパターン ● ゼロから思いつくのは難しいので先人のパターンを借りる ● よく使われるパターンを使う ○ Re-Act Human In the Loop, 検証, Orchestrator(マルチエージェント) ● Agent Design Pattern Catalogue: A Collection of Architectural Patterns for Foundation Model based Agents ○ https://arxiv.org/abs/2405.10467 ● 12-Factor Agents - Principles for building reliable LLM applications ○ https://github.com/humanlayer/12-factor-agents ● サンプルを見る ○ Koog, LangChain, Android Developer Kit.. 68

Slide 69

Slide 69 text

テスト/運用/評価 69

Slide 70

Slide 70 text

ユニットテスト/結合テスト ● ユニットテスト ○ モック: LLMの応答をモック(getMockExecutor) ○ グラフ構造のテスト: ノード動作、エッジの接続、ルーティング (testGraph) ● 結合テスト ○ OllamaのローカルLLMを使ったテストがコスト観点で良い ○ テストコンテナを使う(特にCI) 70

Slide 71

Slide 71 text

● LLMOps ○ Langfuse, W&B Weave… ○ 開発運用を効率化する ○ Tracing、Playground、 プロンプト管理、Evaluation、 Observability… ● Langfuse ○ Open Sourceでおすすめ ○ Self Hosted(for security) 運用 71 https://langfuse.com/ プロンプト管理

Slide 72

Slide 72 text

● エンタープライズアプリで評価は重要 ● 改善したことを評価・計測する ○ 定量的評価 ○ 人による評価、LLM as a Judge ○ LLMタスクごとの評価ベンチマーク ○ オフライン評価/オンライン評価 ○ エージェントの行動軌跡の評価 ● 正しく評価するのは難しい ○ ベンチマークが良くても、 ユーザー体験と結びつかないかも ○ コストもかかる 評価 72 Claudeのオンライン評価の例 https://claude.ai/

Slide 73

Slide 73 text

まとめ ● KotlinでAIエージェントを構築できる第一候補 ● とても使いやすく良いライブラリなのでおすすめです ● 開発も活発なので今後の発展にも期待 73

Slide 74

Slide 74 text

主な参考文献/謝辞 ● Koog公式(Catch Upのページも参照) https://docs.koog.ai/ https://github.com/JetBrains/koog https://www.jetbrains.com/koog/ ○ スライドのコードは Githubを引用しています ● Youtube(Jetbrains/Kotlin Conf) https://www.youtube.com/watch?v=O8WQCrdza8E https://www.youtube.com/watch?v=2l1GBp80CbY&t=1527s https://www.youtube.com/watch?v=AGHONAx8gjQ (他にもYoutubeで検索するとヒットします ) ● LangChain/LangGraph https://www.langchain.com/ ● Langfuse https://langfuse.com/ ● Genkit https://genkit.dev/ ● 書籍 ○ LangChainとLangGraphによるRAG・AIエージェント(エンジニア選書) ○ AIエージェント開発 / 運用入門 [生成AI深掘りガイド](SBクリエイティブ) Thanks ● Jetbrainsの皆さん(特にKoog開発者のVadim Briliantovさん)、Kotlin Slackのさん ● 「いらすとや」さんのイラスト 74