{"id":91997,"date":"2026-08-08T22:17:06","date_gmt":"2026-08-08T14:17:06","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/91997.html"},"modified":"2026-08-08T22:17:06","modified_gmt":"2026-08-08T14:17:06","slug":"kmp-%e5%85%a8%e6%a0%88%e5%bc%80%e5%8f%91%ef%bc%9a%e7%94%a8-koog-%e6%a1%86%e6%9e%b6%e6%9e%84%e5%bb%ba%e5%8e%9f%e7%94%9f-ai-agent","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/91997.html","title":{"rendered":"KMP \u5168\u6808\u5f00\u53d1\uff1a\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent"},"content":{"rendered":"<hr \/>\n<p><img decoding=\"async\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/08\/20260808141700-6a773a5c637e9.jpg\" alt=\"\u5728\u8fd9\u91cc\u63d2\u5165\u56fe\u7247\u63cf\u8ff0\" \/><\/p>\n<hr \/>\n<h2>KMP \u5168\u6808\u5f00\u53d1&#xff1a;\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent<\/h2>\n<hr \/>\n<h3>\u6458\u8981<\/h3>\n<p>2026 \u5e74&#xff0c;Kotlin Multiplatform&#xff08;KMP&#xff09;\u5df2\u4ece\u5b9e\u9a8c\u6027\u6280\u672f\u8dc3\u8fc1\u4e3a\u4f01\u4e1a\u7ea7\u751f\u4ea7\u65b9\u6848&#xff0c;\u800c JetBrains \u63a8\u51fa\u7684 Koog \u6846\u67b6\u5219\u586b\u8865\u4e86 JVM\/Kotlin \u751f\u6001\u5728 AI Agent \u9886\u57df\u7684\u7a7a\u767d\u3002\u672c\u6587\u662f\u4e00\u7bc7\u9762\u5411\u65b0\u624b\u7684\u5b8c\u6574\u5b9e\u6218\u6559\u7a0b&#xff0c;\u4ece\u96f6\u5f00\u59cb\u624b\u628a\u624b\u5e26\u4f60\u4f7f\u7528 Koog \u6846\u67b6\u5728 KMP \u9879\u76ee\u4e2d\u6784\u5efa\u539f\u751f AI Agent\u3002\u5185\u5bb9\u6db5\u76d6&#xff1a;KMP \u751f\u6001\u6700\u65b0\u6f14\u8fdb\u4e0e Koog \u6846\u67b6\u6982\u89c8\u3001\u591a\u5e73\u53f0\u5f00\u53d1\u73af\u5883\u642d\u5efa\u4e0e Gradle \u914d\u7f6e\u3001Koog \u6838\u5fc3\u6982\u5ff5&#xff08;Prompt\u3001Tool\u3001Strategy\u3001Graph&#xff09;\u6df1\u5ea6\u89e3\u6790\u3001Android \u7aef\u9996\u4e2a Agent \u5b9e\u4f8b\u521b\u5efa\u3001\u81ea\u5b9a\u4e49\u5de5\u5177\u51fd\u6570\u5f00\u53d1\u3001\u591a\u8f6e\u5bf9\u8bdd\u72b6\u6001\u673a\u8bbe\u8ba1\u3001iOS \u4e0e Desktop \u7aef\u8de8\u5e73\u53f0\u8fc1\u79fb\u9a8c\u8bc1\u3001\u7f16\u8bd1\u62a5\u9519\u6392\u67e5\u4e0e\u4f9d\u8d56\u51b2\u7a81\u89e3\u51b3\u3001\u6d41\u5f0f\u54cd\u5e94\u4e0e\u7ebf\u7a0b\u8c03\u5ea6\u6027\u80fd\u4f18\u5316&#xff0c;\u4ee5\u53ca\u8131\u79bb Python \u670d\u52a1\u5b9e\u73b0\u7eaf Kotlin \u7aef\u4fa7\u667a\u80fd\u4f53\u7684\u8fdb\u9636\u65b9\u6848\u3002\u5168\u6587\u914d\u6709\u5b8c\u6574\u53ef\u8fd0\u884c\u4ee3\u7801\u3001\u8be6\u7ec6\u6ce8\u91ca\u3001\u5e38\u89c1\u9677\u9631\u8b66\u793a\u4e0e\u6392\u67e5\u65b9\u6848&#xff0c;\u5e2e\u52a9\u4f60\u5728\u6700\u77ed\u65f6\u95f4\u5185\u5c06 AI Agent \u80fd\u529b\u843d\u5730\u5230 Android\u3001iOS\u3001Desktop \u5168\u5e73\u53f0\u3002<\/p>\n<p>\u9002\u7528\u8bfb\u8005&#xff1a;\u5177\u5907 Kotlin \u57fa\u7840\u8bed\u6cd5\u3001\u4e86\u89e3 Android \u5f00\u53d1\u57fa\u672c\u6d41\u7a0b\u3001\u5bf9 AI\/LLM \u6709\u521d\u6b65\u8ba4\u77e5\u7684\u5f00\u53d1\u8005\u3002<\/p>\n<p>\u6280\u672f\u7248\u672c\u57fa\u51c6&#xff1a;Kotlin 2.2&#043; \/ Koog 0.7.x \/ AGP 9.0 \/ Gradle 8.10&#043; \/ Compose Multiplatform 1.11&#043;<\/p>\n<hr \/>\n<h3>\u76ee\u5f55<\/h3>\n<ul>\n<li>\n<p>\u4e00\u3001KotlinConf 2026 \u540e KMP \u751f\u6001\u8fdb\u5316\u4e0e Koog \u6846\u67b6\u6982\u89c8<\/p>\n<ul>\n<li>1.1 KMP 2026 \u751f\u6001\u5168\u666f&#xff1a;\u4ece\u903b\u8f91\u5171\u4eab\u5230\u5168\u5e73\u53f0\u8986\u76d6<\/li>\n<li>1.2 Koog \u6846\u67b6\u8bde\u751f\u80cc\u666f\u4e0e\u8bbe\u8ba1\u54f2\u5b66\n<ul>\n<li>1.2.1 \u4e3a\u4ec0\u4e48 JVM \u751f\u6001\u9700\u8981\u539f\u751f Agent \u6846\u67b6<\/li>\n<li>1.2.2 Koog \u7684\u4e94\u5c42\u67b6\u6784\u8bbe\u8ba1<\/li>\n<\/ul>\n<\/li>\n<li>1.3 Koog \u6838\u5fc3\u80fd\u529b\u4e00\u89c8<\/li>\n<li>1.4 Koog \u4e0e\u540c\u7c7b\u6846\u67b6\u5bf9\u6bd4&#xff08;Spring AI \/ LangChain4j&#xff09;<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u4e8c\u3001\u591a\u5e73\u53f0\u5f00\u53d1\u73af\u5883\u642d\u5efa\u4e0e Gradle \u4f9d\u8d56\u914d\u7f6e<\/p>\n<ul>\n<li>2.1 \u5f00\u53d1\u73af\u5883\u51c6\u5907\u6e05\u5355<\/li>\n<li>2.2 \u4f7f\u7528 KMP \u5411\u5bfc\u521b\u5efa\u9879\u76ee<\/li>\n<li>2.3 Gradle \u4f9d\u8d56\u914d\u7f6e\u8be6\u89e3\n<ul>\n<li>2.3.1 \u6839\u9879\u76ee settings.gradle.kts<\/li>\n<li>2.3.2 \u5171\u4eab\u6a21\u5757 build.gradle.kts<\/li>\n<li>2.3.3 \u5e73\u53f0\u7279\u5b9a\u6a21\u5757\u914d\u7f6e<\/li>\n<\/ul>\n<\/li>\n<li>2.4 API Key \u7ba1\u7406\u4e0e\u5b89\u5168\u914d\u7f6e<\/li>\n<li>2.5 \u9a8c\u8bc1\u73af\u5883&#xff1a;\u8fd0\u884c\u7b2c\u4e00\u4e2a Gradle Task<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u4e09\u3001Koog \u6838\u5fc3\u6982\u5ff5\u89e3\u6790&#xff1a;\u4ece Prompt \u5230\u5de5\u5177\u8c03\u7528\u7684\u6620\u5c04<\/p>\n<ul>\n<li>3.1 Agent \u751f\u547d\u5468\u671f\u603b\u89c8<\/li>\n<li>3.2 Prompt \u7cfb\u7edf&#xff1a;\u7ed3\u6784\u5316\u63d0\u793a\u8bcd\u5de5\u7a0b\n<ul>\n<li>3.2.1 System Prompt \u4e0e User Prompt<\/li>\n<li>3.2.2 PromptTemplate \u4e0e\u52a8\u6001\u53d8\u91cf\u6ce8\u5165<\/li>\n<\/ul>\n<\/li>\n<li>3.3 LLM \u62bd\u8c61\u5c42&#xff1a;\u6a21\u578b\u65e0\u5173\u8bbe\u8ba1<\/li>\n<li>3.4 Tool&#xff08;\u5de5\u5177&#xff09;\u7cfb\u7edf&#xff1a;\u7c7b\u578b\u5b89\u5168\u7684\u51fd\u6570\u8c03\u7528\n<ul>\n<li>3.4.1 \u5de5\u5177\u5b9a\u4e49\u4e0e\u53c2\u6570 Schema<\/li>\n<li>3.4.2 \u5de5\u5177\u6267\u884c\u4e0e\u7ed3\u679c\u56de\u4f20<\/li>\n<\/ul>\n<\/li>\n<li>3.5 Strategy&#xff08;\u7b56\u7565&#xff09;&#xff1a;Agent \u7684\u51b3\u7b56\u5f15\u64ce<\/li>\n<li>3.6 Graph Workflow&#xff1a;\u56fe\u5de5\u4f5c\u6d41\u5f15\u64ce<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u56db\u3001\u5b9e\u6218\u7b2c\u4e00\u6b65&#xff1a;\u5728 Android \u7aef\u521d\u59cb\u5316\u9996\u4e2a AI Agent \u5b9e\u4f8b<\/p>\n<ul>\n<li>4.1 \u521b\u5efa Agent \u914d\u7f6e\u7c7b<\/li>\n<li>4.2 \u521d\u59cb\u5316 PromptExecutor<\/li>\n<li>4.3 \u6784\u5efa AIAgent \u5b9e\u4f8b<\/li>\n<li>4.4 \u5728 Activity\/ViewModel \u4e2d\u96c6\u6210<\/li>\n<li>4.5 \u8fd0\u884c\u4e0e\u9a8c\u8bc1<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u4e94\u3001\u5b9a\u4e49\u81ea\u5b9a\u4e49\u5de5\u5177\u51fd\u6570\u5e76\u5b9e\u73b0\u672c\u5730\u4e1a\u52a1\u903b\u8f91\u8c03\u7528<\/p>\n<ul>\n<li>5.1 \u5de5\u5177\u51fd\u6570\u7684\u8bbe\u8ba1\u89c4\u8303<\/li>\n<li>5.2 \u5b9e\u73b0\u5929\u6c14\u67e5\u8be2\u5de5\u5177<\/li>\n<li>5.3 \u5b9e\u73b0\u672c\u5730\u6570\u636e\u5e93\u67e5\u8be2\u5de5\u5177<\/li>\n<li>5.4 \u5de5\u5177\u6ce8\u518c\u4e0e Agent \u7ed1\u5b9a<\/li>\n<li>5.5 \u5de5\u5177\u8c03\u7528\u94fe\u8def\u8c03\u8bd5<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u516d\u3001\u6784\u5efa\u591a\u8f6e\u5bf9\u8bdd\u72b6\u6001\u673a\u4e0e\u7ba1\u7406\u4e0a\u4e0b\u6587\u8bb0\u5fc6<\/p>\n<ul>\n<li>6.1 \u5bf9\u8bdd\u5386\u53f2\u7684\u6570\u636e\u6a21\u578b<\/li>\n<li>6.2 \u4e0a\u4e0b\u6587\u7a97\u53e3\u7ba1\u7406\u7b56\u7565<\/li>\n<li>6.3 \u6301\u4e45\u5316\u8bb0\u5fc6&#xff1a;AIAgentStorage<\/li>\n<li>6.4 \u5386\u53f2\u538b\u7f29&#xff1a;\u964d\u4f4e Token \u6210\u672c<\/li>\n<li>6.5 \u591a\u8f6e\u5bf9\u8bdd UI \u96c6\u6210<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u4e03\u3001\u8de8\u5e73\u53f0\u8fd0\u884c\u9a8c\u8bc1&#xff1a;iOS \u4e0e Desktop \u7aef\u7684\u65e0\u7f1d\u8fc1\u79fb<\/p>\n<ul>\n<li>7.1 iOS \u7aef\u96c6\u6210&#xff1a;Framework \u5bfc\u51fa\u4e0e SwiftUI \u6865\u63a5<\/li>\n<li>7.2 Desktop \u7aef\u96c6\u6210&#xff1a;Compose Desktop \u5e94\u7528<\/li>\n<li>7.3 \u5e73\u53f0\u5dee\u5f02\u5904\u7406&#xff1a;expect\/actual \u6a21\u5f0f<\/li>\n<li>7.4 \u4e09\u7aef\u7edf\u4e00\u6d4b\u8bd5\u9a8c\u8bc1<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u516b\u3001\u5e38\u89c1\u7f16\u8bd1\u62a5\u9519\u6392\u67e5\u4e0e\u4f9d\u8d56\u51b2\u7a81\u89e3\u51b3\u65b9\u6848<\/p>\n<ul>\n<li>8.1 Kotlin\/Native \u7f16\u8bd1\u9519\u8bef<\/li>\n<li>8.2 \u4f9d\u8d56\u7248\u672c\u51b2\u7a81<\/li>\n<li>8.3 Ktor \u5f15\u64ce\u51b2\u7a81<\/li>\n<li>8.4 \u5e8f\u5217\u5316\u4e0e\u53cd\u5c04\u95ee\u9898<\/li>\n<li>8.5 \u5185\u5b58\u4e0e GC \u76f8\u5173\u95ee\u9898<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u4e5d\u3001\u6027\u80fd\u4f18\u5316\u6280\u5de7&#xff1a;\u6d41\u5f0f\u54cd\u5e94\u5904\u7406\u4e0e\u540e\u53f0\u7ebf\u7a0b\u8c03\u5ea6<\/p>\n<ul>\n<li>9.1 \u6d41\u5f0f\u54cd\u5e94&#xff08;Streaming&#xff09;\u5b9e\u73b0<\/li>\n<li>9.2 \u534f\u7a0b\u8c03\u5ea6\u5668\u9009\u62e9<\/li>\n<li>9.3 \u5e76\u884c\u5de5\u5177\u8c03\u7528<\/li>\n<li>9.4 \u7f51\u7edc\u5c42\u4f18\u5316<\/li>\n<li>9.5 \u5185\u5b58\u4e0e Token \u9884\u7b97\u63a7\u5236<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u5341\u3001\u8fdb\u9636\u573a\u666f&#xff1a;\u8131\u79bb Python \u670d\u52a1\u5b9e\u73b0\u7eaf Kotlin \u7aef\u4fa7\u667a\u80fd\u4f53<\/p>\n<ul>\n<li>10.1 \u7aef\u4fa7\u63a8\u7406\u6a21\u578b\u96c6\u6210&#xff08;Ollama \/ llama.cpp&#xff09;<\/li>\n<li>10.2 MCP \u534f\u8bae\u5bf9\u63a5\u5916\u90e8\u7cfb\u7edf<\/li>\n<li>10.3 \u591a Agent \u534f\u4f5c\u67b6\u6784<\/li>\n<li>10.4 \u751f\u4ea7\u73af\u5883\u90e8\u7f72\u6e05\u5355<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u5341\u4e00\u3001\u5e38\u89c1\u9677\u9631\u4e0e\u95ee\u9898\u6392\u9664\u901f\u67e5\u8868<\/p>\n<\/li>\n<li>\n<p>\u5341\u4e8c\u3001\u603b\u7ed3\u4e0e\u5c55\u671b<\/p>\n<\/li>\n<li>\n<p>\u5341\u4e09\u3001\u8be6\u7ec6\u53c2\u8003\u8d44\u6599<\/p>\n<\/li>\n<li>\n<p>\u9644\u5f55<\/p>\n<ul>\n<li>\u9644\u5f55 A&#xff1a;\u5b8c\u6574\u9879\u76ee\u7ed3\u6784\u6811<\/li>\n<li>\u9644\u5f55 B&#xff1a;Gradle \u7248\u672c\u517c\u5bb9\u77e9\u9635<\/li>\n<li>\u9644\u5f55 C&#xff1a;Koog API \u901f\u67e5\u8868<\/li>\n<li>\u9644\u5f55 D&#xff1a;\u672f\u8bed\u8868<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<hr \/>\n<h3>\u4e00\u3001KotlinConf 2026 \u540e KMP \u751f\u6001\u8fdb\u5316\u4e0e Koog \u6846\u67b6\u6982\u89c8<\/h3>\n<h4>1.1 KMP 2026 \u751f\u6001\u5168\u666f&#xff1a;\u4ece\u903b\u8f91\u5171\u4eab\u5230\u5168\u5e73\u53f0\u8986\u76d6<\/h4>\n<p>Kotlin Multiplatform&#xff08;KMP&#xff09;\u662f JetBrains \u4e3b\u5bfc\u7814\u53d1\u7684\u8de8\u5e73\u53f0\u6280\u672f\u4f53\u7cfb&#xff0c;\u5176\u6838\u5fc3\u8bbe\u8ba1\u54f2\u5b66\u662f \u201c\u5171\u4eab\u4e1a\u52a1\u903b\u8f91&#xff0c;\u4fdd\u7559\u539f\u751f UI \u4f53\u9a8c\u201d\u3002\u4e0e Flutter \u7684&#034;\u81ea\u7ed8 UI \u8de8\u5e73\u53f0&#034;\u4e0d\u540c&#xff0c;KMP \u805a\u7126\u4e8e\u903b\u8f91\u5c42\u7684\u9ad8\u5ea6\u590d\u7528&#xff0c;\u8ba9\u5f00\u53d1\u8005\u5728 Android\u3001iOS\u3001Desktop\u3001Web \u7b49\u591a\u5e73\u53f0\u95f4\u5171\u4eab\u7f51\u7edc\u3001\u6570\u636e\u5b58\u50a8\u3001\u4e1a\u52a1\u8ba1\u7b97\u7b49\u6838\u5fc3\u4ee3\u7801&#xff0c;\u540c\u65f6\u4fdd\u7559\u5404\u5e73\u53f0\u539f\u751f UI \u5f00\u53d1\u4f53\u9a8c\u3002<\/p>\n<p>2026 \u5e74 KMP \u751f\u6001\u7684\u5173\u952e\u91cc\u7a0b\u7891&#xff1a;<\/p>\n<table>\n<tr>\u65f6\u95f4\u4e8b\u4ef6\u610f\u4e49<\/tr>\n<tbody>\n<tr>\n<td>2025.05<\/td>\n<td>KotlinConf 2025 \u53d1\u5e03 Kotlin 2.2 &#043; Koog \u5f00\u6e90<\/td>\n<td>AI Agent \u6b63\u5f0f\u8fdb\u5165 Kotlin \u751f\u6001<\/td>\n<\/tr>\n<tr>\n<td>2025.11<\/td>\n<td>KMP \u8fdb\u5165\u7a33\u5b9a\u7248&#xff08;GA&#xff09;<\/td>\n<td>\u751f\u4ea7\u73af\u5883\u53ef\u7528<\/td>\n<\/tr>\n<tr>\n<td>2026.03<\/td>\n<td>Koog for Java \u6b63\u5f0f\u53d1\u5e03<\/td>\n<td>\u4f01\u4e1a\u7ea7 JVM Agent \u6846\u67b6\u5b8c\u5584<\/td>\n<\/tr>\n<tr>\n<td>2026.04<\/td>\n<td>Compose Multiplatform 1.11 \u7a33\u5b9a<\/td>\n<td>iOS \u7aef UI \u5171\u4eab\u6210\u719f<\/td>\n<\/tr>\n<tr>\n<td>2026.05<\/td>\n<td>KotlinConf 2026&#xff1a;AI \u00d7 Multiplatform \u6210\u4e3a\u6838\u5fc3\u8bae\u9898<\/td>\n<td>Agent \u4e0e\u8de8\u7aef\u6df1\u5ea6\u878d\u5408<\/td>\n<\/tr>\n<tr>\n<td>2026.06<\/td>\n<td>KMP \u65b0\u9879\u76ee\u7ed3\u6784\u53d1\u5e03&#xff08;\u914d\u5408 AGP 9.0&#xff09;<\/td>\n<td>\u5de5\u7a0b\u89c4\u8303\u7edf\u4e00<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>KMP \u7684\u4ee3\u7801\u5206\u5c42\u67b6\u6784\u5982\u4e0b&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502                  Platform UI Layer               \u2502<br \/>\n\u2502  (Android Compose \/ SwiftUI \/ Compose Desktop)  \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502              Shared Business Logic               \u2502<br \/>\n\u2502        (commonMain &#8211; Kotlin \u4ee3\u7801)               \u2502<br \/>\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510    \u2502<br \/>\n\u2502  \u2502   AI Agent Logic (Koog Framework)       \u2502    \u2502<br \/>\n\u2502  \u2502   &#8211; Prompt Management                   \u2502    \u2502<br \/>\n\u2502  \u2502   &#8211; Tool Calling                        \u2502    \u2502<br \/>\n\u2502  \u2502   &#8211; Strategy \/ Workflow                 \u2502    \u2502<br \/>\n\u2502  \u2502   &#8211; Memory \/ Context                    \u2502    \u2502<br \/>\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518    \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502           Platform-specific Implementations      \u2502<br \/>\n\u2502  (androidMain \/ iosMain \/ desktopMain)          \u2502<br \/>\n\u2502  &#8211; Network Engine \/ Storage \/ Permissions       \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<h4>1.2 Koog \u6846\u67b6\u8bde\u751f\u80cc\u666f\u4e0e\u8bbe\u8ba1\u54f2\u5b66<\/h4>\n<h5>1.2.1 \u4e3a\u4ec0\u4e48 JVM \u751f\u6001\u9700\u8981\u539f\u751f Agent \u6846\u67b6<\/h5>\n<p>2026 \u5e74\u7684 AI Agent \u9886\u57df&#xff0c;Python \u751f\u6001\u5df2\u76f8\u5f53\u6210\u719f\u2014\u2014LangChain\u3001LlamaIndex\u3001AutoGPT \u7b49\u6846\u67b6\u8ba9\u5f00\u53d1\u8005\u80fd\u591f\u5feb\u901f\u6784\u5efa\u5404\u79cd\u667a\u80fd\u4f53\u5e94\u7528\u3002\u7136\u800c&#xff0c;\u5bf9\u4e8e JVM \u751f\u6001\u7684\u5f00\u53d1\u8005\u6765\u8bf4&#xff0c;\u4f7f\u7528 Python \u6846\u67b6\u6784\u5efa AI Agent \u5b58\u5728\u4e09\u5927\u75db\u70b9&#xff1a;<\/p>\n<li>\u7c7b\u578b\u5b89\u5168\u7f3a\u5931&#xff1a;Python \u7684\u52a8\u6001\u7c7b\u578b\u7cfb\u7edf\u4e0e Kotlin\/Java \u7684\u5f3a\u7c7b\u578b\u4f53\u7cfb\u683c\u683c\u4e0d\u5165&#xff0c;\u8de8\u8bed\u8a00\u8c03\u7528\u65f6\u7c7b\u578b\u9519\u8bef\u53ea\u80fd\u5728\u8fd0\u884c\u65f6\u66b4\u9732\u3002<\/li>\n<li>\u534f\u7a0b\u6a21\u578b\u4e0d\u5339\u914d&#xff1a;Kotlin \u534f\u7a0b\u7684\u7ed3\u6784\u5316\u5e76\u53d1\u3001\u53d6\u6d88\u4f20\u64ad\u3001\u5f02\u5e38\u5904\u7406\u673a\u5236\u65e0\u6cd5\u4e0e Python \u7684 asyncio \u81ea\u7136\u5bf9\u63a5\u3002<\/li>\n<li>\u8de8\u8bed\u8a00\u90e8\u7f72\u590d\u6742&#xff1a;\u5f15\u5165 Python \u5fae\u670d\u52a1\u610f\u5473\u7740\u989d\u5916\u7684\u5e8f\u5217\u5316\u5f00\u9500\u3001\u8fd0\u7ef4\u6210\u672c\u3001\u8c03\u8bd5\u96be\u5ea6\u3002<\/li>\n<p>Koog \u7684\u51fa\u73b0\u6b63\u662f\u4e3a\u4e86\u586b\u8865\u8fd9\u4e2a\u7a7a\u767d\u3002JetBrains \u5b98\u65b9\u5b9a\u4e49&#xff1a;<\/p>\n<p>\u201cA JVM (Java and Kotlin) framework for building predictable, fault-tolerant and enterprise-ready AI agents.\u201d<\/p>\n<p>\u4e09\u4e2a\u5173\u952e\u8bcd&#xff1a;\u53ef\u9884\u6d4b\u3001\u5bb9\u9519\u3001\u4f01\u4e1a\u5c31\u7eea\u3002<\/p>\n<h5>1.2.2 Koog \u7684\u4e94\u5c42\u67b6\u6784\u8bbe\u8ba1<\/h5>\n<p>Koog \u7684\u67b6\u6784\u5206\u4e3a\u4e94\u5c42&#xff0c;\u4ece\u4e0a\u5230\u4e0b\u4f9d\u6b21\u4e3a&#xff1a;<\/p>\n<p>\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510<br \/>\n\u2502  Layer 5: \u5e94\u7528\u5c42                                      \u2502<br \/>\n\u2502  Basic Agent \/ Functional Agent \/ Graph Agent \/       \u2502<br \/>\n\u2502  Planner Agent                                       \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502  Layer 4: \u6838\u5fc3\u7ec4\u4ef6                                    \u2502<br \/>\n\u2502  Prompt \/ Strategy \/ Tools \/ Features \/ Storage       \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502  Layer 3: LLM \u62bd\u8c61\u5c42                                 \u2502<br \/>\n\u2502  OpenAI \/ Anthropic \/ Ollama \/ MCP Protocol          \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502  Layer 2: \u6a21\u578b\u63d0\u4f9b\u5546                                  \u2502<br \/>\n\u2502  GPT-4o \/ Claude \/ Llama \/ DeepSeek \/ \u901a\u4e49\u5343\u95ee       \u2502<br \/>\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524<br \/>\n\u2502  Layer 1: Runtime                                    \u2502<br \/>\n\u2502  JVM \/ Android \/ iOS (Kotlin\/Native) \/ JS \/ WasmJS   \u2502<br \/>\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/p>\n<p>\u6838\u5fc3\u8bbe\u8ba1\u539f\u5219&#xff1a;<\/p>\n<ul>\n<li>\u7eaf Kotlin \u5b9e\u73b0&#xff1a;\u5b8c\u5168\u5728 Kotlin \u4e2d\u6784\u5efa\u548c\u8fd0\u884c AI \u667a\u80fd\u4f53&#xff0c;\u65e0\u9700\u5916\u90e8\u670d\u52a1\u4f9d\u8d56<\/li>\n<li>\u6a21\u5757\u5316\u529f\u80fd\u7cfb\u7edf&#xff1a;\u901a\u8fc7\u53ef\u7ec4\u5408\u7684\u529f\u80fd\u7cfb\u7edf\u6269\u5c55 Agent \u80fd\u529b<\/li>\n<li>\u534f\u7a0b\u4e3a\u6838\u5fc3&#xff1a;Agent \u6267\u884c\u3001\u5de5\u5177\u8c03\u7528\u3001\u6d41\u5f0f\u54cd\u5e94\u5747\u4e3a suspend \u51fd\u6570\u6216 Flow<\/li>\n<li>\u7c7b\u578b\u5b89\u5168&#xff1a;\u6bcf\u4e2a\u64cd\u4f5c\u7684\u8f93\u5165\u8f93\u51fa\u7c7b\u578b\u4e25\u683c\u9650\u5b9a&#xff0c;\u7f16\u8bd1\u671f\u5373\u53ef\u53d1\u73b0\u9519\u8bef<\/li>\n<\/ul>\n<h4>1.3 Koog \u6838\u5fc3\u80fd\u529b\u4e00\u89c8<\/h4>\n<table>\n<tr>\u80fd\u529b\u8bf4\u660e<\/tr>\n<tbody>\n<tr>\n<td>Kotlin DSL \u6784\u5efa Agent<\/td>\n<td>\u4f7f\u7528\u58f0\u660e\u5f0f DSL \u5b9a\u4e49 Agent \u884c\u4e3a<\/td>\n<\/tr>\n<tr>\n<td>\u81ea\u52a8\u6267\u884c\u89c4\u5212<\/td>\n<td>GOAP \u89c4\u5212\u5668\u6216 LLM \u89c4\u5212\u5668&#xff0c;\u8fed\u4ee3\u5f0f\u591a\u6b65\u65b9\u6848<\/td>\n<\/tr>\n<tr>\n<td>\u7c7b\u578b\u5b89\u5168\u6a21\u578b<\/td>\n<td>\u6570\u636e\u9a71\u52a8\u6784\u5efa Agent \u6d41&#xff0c;\u7c7b\u578b\u4e25\u683c\u9650\u5b9a<\/td>\n<\/tr>\n<tr>\n<td>MCP \u96c6\u6210<\/td>\n<td>\u76f4\u63a5\u5bf9\u63a5\u5916\u90e8\u7cfb\u7edf\u4e0e\u5de5\u5177<\/td>\n<\/tr>\n<tr>\n<td>\u5d4c\u5165\u4e0e\u5411\u91cf\u68c0\u7d22<\/td>\n<td>\u5185\u7f6e RAG \u652f\u6301<\/td>\n<\/tr>\n<tr>\n<td>\u6d41\u5f0f\u4e0e\u5e76\u884c\u5de5\u5177\u8c03\u7528<\/td>\n<td>\u63d0\u5347\u5b9e\u65f6\u6027<\/td>\n<\/tr>\n<tr>\n<td>\u6301\u4e45\u5316\u8bb0\u5fc6\u4e0e\u5386\u53f2\u538b\u7f29<\/td>\n<td>\u964d\u4f4e\u4e0a\u4e0b\u6587\u6210\u672c<\/td>\n<\/tr>\n<tr>\n<td>\u53ef\u89c2\u6d4b\u6027\u4e0e\u8ffd\u8e2a<\/td>\n<td>OpenTelemetry \u96c6\u6210&#xff0c;\u4fbf\u4e8e\u8c03\u8bd5\u56de\u653e<\/td>\n<\/tr>\n<tr>\n<td>\u56fe\u5de5\u4f5c\u6d41<\/td>\n<td>\u8868\u8fbe\u590d\u6742\u884c\u4e3a\u4e0e\u591a\u6b65\u4efb\u52a1<\/td>\n<\/tr>\n<tr>\n<td>\u591a\u5e73\u53f0\u90e8\u7f72<\/td>\n<td>JVM \/ Android \/ iOS \/ JS \/ WasmJS<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>1.4 Koog \u4e0e\u540c\u7c7b\u6846\u67b6\u5bf9\u6bd4<\/h4>\n<table>\n<tr>\u7ef4\u5ea6KoogSpring AILangChain4j<\/tr>\n<tbody>\n<tr>\n<td>\u5b9a\u4f4d<\/td>\n<td>Agent-first&#xff0c;\u5168\u5e73\u53f0<\/td>\n<td>Spring \u751f\u6001\u96c6\u6210<\/td>\n<td>\u901a\u7528 LLM \u96c6\u6210<\/td>\n<\/tr>\n<tr>\n<td>\u8bed\u8a00<\/td>\n<td>Kotlin (Java API)<\/td>\n<td>Java<\/td>\n<td>Java<\/td>\n<\/tr>\n<tr>\n<td>\u8de8\u5e73\u53f0<\/td>\n<td>\u2705 KMP \u539f\u751f<\/td>\n<td>\u274c JVM only<\/td>\n<td>\u274c JVM only<\/td>\n<\/tr>\n<tr>\n<td>\u5de5\u5177\u8c03\u7528<\/td>\n<td>\u7c7b\u578b\u5b89\u5168 DSL<\/td>\n<td>\u6ce8\u89e3\u9a71\u52a8<\/td>\n<td>\u6ce8\u89e3\u9a71\u52a8<\/td>\n<\/tr>\n<tr>\n<td>\u5de5\u4f5c\u6d41<\/td>\n<td>\u56fe\u5f15\u64ce &#043; GOAP<\/td>\n<td>\u6709\u9650<\/td>\n<td>Chain \u6a21\u5f0f<\/td>\n<\/tr>\n<tr>\n<td>\u53ef\u89c2\u6d4b\u6027<\/td>\n<td>OpenTelemetry \u5185\u7f6e<\/td>\n<td>Micrometer<\/td>\n<td>\u6709\u9650<\/td>\n<\/tr>\n<tr>\n<td>\u79fb\u52a8\u7aef<\/td>\n<td>\u2705 Android\/iOS<\/td>\n<td>\u274c<\/td>\n<td>\u274c<\/td>\n<\/tr>\n<tr>\n<td>\u5bb9\u9519\u673a\u5236<\/td>\n<td>Checkpoint &#043; \u6062\u590d<\/td>\n<td>\u65e0<\/td>\n<td>\u6709\u9650<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h3>\u4e8c\u3001\u591a\u5e73\u53f0\u5f00\u53d1\u73af\u5883\u642d\u5efa\u4e0e Gradle \u4f9d\u8d56\u914d\u7f6e<\/h3>\n<h4>2.1 \u5f00\u53d1\u73af\u5883\u51c6\u5907\u6e05\u5355<\/h4>\n<p>\u5728\u5f00\u59cb\u4e4b\u524d&#xff0c;\u8bf7\u786e\u4fdd\u4f60\u7684\u5f00\u53d1\u73af\u5883\u6ee1\u8db3\u4ee5\u4e0b\u57fa\u672c\u8981\u6c42&#xff1a;<\/p>\n<table>\n<tr>\u5de5\u5177\u6700\u4f4e\u7248\u672c\u63a8\u8350\u7248\u672c\u8bf4\u660e<\/tr>\n<tbody>\n<tr>\n<td>JDK<\/td>\n<td>17<\/td>\n<td>21<\/td>\n<td>Koog \u8981\u6c42 Java 17&#043;<\/td>\n<\/tr>\n<tr>\n<td>Kotlin<\/td>\n<td>2.2.0<\/td>\n<td>2.2.20<\/td>\n<td>K2 \u7f16\u8bd1\u5668<\/td>\n<\/tr>\n<tr>\n<td>Gradle<\/td>\n<td>8.8<\/td>\n<td>8.10&#043;<\/td>\n<td>\u6784\u5efa\u5de5\u5177<\/td>\n<\/tr>\n<tr>\n<td>Android Studio<\/td>\n<td>Ladybug&#043;<\/td>\n<td>\u6700\u65b0\u7a33\u5b9a\u7248<\/td>\n<td>Android \u5f00\u53d1<\/td>\n<\/tr>\n<tr>\n<td>Xcode<\/td>\n<td>15.4&#043;<\/td>\n<td>16.x<\/td>\n<td>iOS \u5f00\u53d1&#xff08;macOS&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>IntelliJ IDEA<\/td>\n<td>2025.1&#043;<\/td>\n<td>2026.1<\/td>\n<td>Desktop\/JVM \u5f00\u53d1<\/td>\n<\/tr>\n<tr>\n<td>KMP \u63d2\u4ef6<\/td>\n<td>\u6700\u65b0<\/td>\n<td>\u6700\u65b0<\/td>\n<td>IDE \u591a\u5e73\u53f0\u652f\u6301<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u5b89\u88c5\u6b65\u9aa4&#xff1a;<\/p>\n<p><span class=\"token comment\"># 1. \u9a8c\u8bc1 JDK \u7248\u672c<\/span><br \/>\n<span class=\"token function\">java<\/span> <span class=\"token parameter variable\">-version<\/span><br \/>\n<span class=\"token comment\"># \u671f\u671b\u8f93\u51fa: openjdk version &#034;21.x.x&#034; \u6216\u66f4\u9ad8<\/span><\/p>\n<p><span class=\"token comment\"># 2. \u9a8c\u8bc1 Gradle&#xff08;\u5982\u4f7f\u7528 wrapper \u5219\u8df3\u8fc7&#xff09;<\/span><br \/>\ngradle <span class=\"token parameter variable\">&#8211;version<\/span><\/p>\n<p><span class=\"token comment\"># 3. macOS \u7528\u6237\u9a8c\u8bc1 Xcode Command Line Tools<\/span><br \/>\nxcode-select &#8211;print-path<br \/>\n<span class=\"token comment\"># \u671f\u671b\u8f93\u51fa: \/Applications\/Xcode.app\/Contents\/Developer<\/span><\/p>\n<p><span class=\"token comment\"># 4. \u9a8c\u8bc1 Kotlin \u7f16\u8bd1\u5668&#xff08;\u53ef\u9009&#xff09;<\/span><br \/>\nkotlinc <span class=\"token parameter variable\">-version<\/span><\/p>\n<h4>2.2 \u4f7f\u7528 KMP \u5411\u5bfc\u521b\u5efa\u9879\u76ee<\/h4>\n<p>JetBrains \u63d0\u4f9b\u4e86\u5728\u7ebf KMP \u9879\u76ee\u5411\u5bfc&#xff0c;\u8bbf\u95ee https:\/\/kmp.jetbrains.com&#xff1a;<\/p>\n<li>\u9009\u62e9\u9879\u76ee\u540d\u79f0&#xff1a;KoogAgentDemo<\/li>\n<li>\u9009\u62e9\u76ee\u6807\u5e73\u53f0&#xff1a;Android &#043; iOS &#043; Desktop<\/li>\n<li>\u9009\u62e9 UI \u6846\u67b6&#xff1a;Compose Multiplatform&#xff08;\u53ef\u9009&#xff0c;\u672c\u6559\u7a0b\u91cd\u70b9\u5728\u903b\u8f91\u5c42&#xff09;<\/li>\n<li>\u70b9\u51fb \u201cDownload\u201d \u4e0b\u8f7d\u9879\u76ee\u538b\u7f29\u5305<\/li>\n<li>\u89e3\u538b\u540e\u7528 Android Studio \u6216 IntelliJ IDEA \u6253\u5f00<\/li>\n<p>\u26a0\ufe0f \u5e38\u89c1\u9677\u9631&#xff1a;\u4e0b\u8f7d\u7684\u9879\u76ee\u53ef\u80fd\u4f7f\u7528\u65e7\u7248\u76ee\u5f55\u7ed3\u6784\u30022026 \u5e74 6 \u6708\u540e KMP \u63a8\u51fa\u4e86\u65b0\u7684\u9ed8\u8ba4\u9879\u76ee\u7ed3\u6784&#xff08;\u914d\u5408 AGP 9.0&#xff09;&#xff0c;\u5982\u679c\u4f60\u4f7f\u7528\u65e7\u7248 IDE \u6253\u5f00\u65b0\u9879\u76ee&#xff0c;\u53ef\u80fd\u9700\u8981\u624b\u52a8\u8c03\u6574\u3002<\/p>\n<h4>2.3 Gradle \u4f9d\u8d56\u914d\u7f6e\u8be6\u89e3<\/h4>\n<h5>2.3.1 \u6839\u9879\u76ee settings.gradle.kts<\/h5>\n<p><span class=\"token comment\">\/\/ settings.gradle.kts<\/span><br \/>\n<span class=\"token comment\">\/\/ \u9879\u76ee\u6839\u914d\u7f6e&#xff1a;\u58f0\u660e\u63d2\u4ef6\u4ed3\u5e93\u4e0e\u6a21\u5757\u7ed3\u6784<\/span><\/p>\n<p>pluginManagement <span class=\"token punctuation\">{<\/span><br \/>\n    repositories <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token function\">google<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span>          <span class=\"token comment\">\/\/ Android Gradle Plugin<\/span><br \/>\n        <span class=\"token function\">mavenCentral<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span>    <span class=\"token comment\">\/\/ Kotlin \u63d2\u4ef6<\/span><br \/>\n        <span class=\"token function\">gradlePluginPortal<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token comment\">\/\/ Gradle \u63d2\u4ef6\u95e8\u6237<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>dependencyResolutionManagement <span class=\"token punctuation\">{<\/span><br \/>\n    repositories <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token function\">google<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token function\">mavenCentral<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token comment\">\/\/ Koog \u76ee\u524d\u53d1\u5e03\u5728 Maven Central<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5982\u679c\u4f7f\u7528\u5feb\u7167\u7248\u672c&#xff0c;\u9700\u8981\u6dfb\u52a0&#xff1a;<\/span><br \/>\n        <span class=\"token comment\">\/\/ maven(&#034;https:\/\/packages.jetbrains.team\/maven\/p\/koog\/koog&#034;)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>rootProject<span class=\"token punctuation\">.<\/span>name <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;KoogAgentDemo&#034;<\/span><\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u58f0\u660e\u5b50\u6a21\u5757<\/span><br \/>\n<span class=\"token function\">include<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;:shared&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span>           <span class=\"token comment\">\/\/ \u5171\u4eab\u4e1a\u52a1\u903b\u8f91&#xff08;\u542b Koog Agent&#xff09;<\/span><br \/>\n<span class=\"token function\">include<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;:androidApp&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span>       <span class=\"token comment\">\/\/ Android \u5e94\u7528\u58f3<\/span><br \/>\n<span class=\"token function\">include<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;:desktopApp&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span>       <span class=\"token comment\">\/\/ Desktop \u5e94\u7528\u58f3<\/span><br \/>\n<span class=\"token function\">include<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;:iosApp&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span>           <span class=\"token comment\">\/\/ iOS \u5e94\u7528\u58f3&#xff08;Xcode \u9879\u76ee\u5f15\u7528&#xff09;<\/span><\/p>\n<h5>2.3.2 \u5171\u4eab\u6a21\u5757 build.gradle.kts<\/h5>\n<p><span class=\"token comment\">\/\/ shared\/build.gradle.kts<\/span><br \/>\n<span class=\"token comment\">\/\/ \u6838\u5fc3\u5171\u4eab\u6a21\u5757&#xff1a;\u5305\u542b\u6240\u6709 Koog Agent \u903b\u8f91<\/span><\/p>\n<p>plugins <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function\">alias<\/span><span class=\"token punctuation\">(<\/span>libs<span class=\"token punctuation\">.<\/span>plugins<span class=\"token punctuation\">.<\/span>kotlinMultiplatform<span class=\"token punctuation\">)<\/span>    <span class=\"token comment\">\/\/ KMP \u63d2\u4ef6<\/span><br \/>\n    <span class=\"token function\">alias<\/span><span class=\"token punctuation\">(<\/span>libs<span class=\"token punctuation\">.<\/span>plugins<span class=\"token punctuation\">.<\/span>kotlinSerialization<span class=\"token punctuation\">)<\/span>     <span class=\"token comment\">\/\/ Kotlin \u5e8f\u5217\u5316&#xff08;Koog \u4f9d\u8d56&#xff09;<\/span><br \/>\n    <span class=\"token function\">alias<\/span><span class=\"token punctuation\">(<\/span>libs<span class=\"token punctuation\">.<\/span>plugins<span class=\"token punctuation\">.<\/span>androidLibrary<span class=\"token punctuation\">)<\/span>          <span class=\"token comment\">\/\/ Android Library<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>kotlin <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ &#061;&#061;&#061;&#061;&#061; \u76ee\u6807\u5e73\u53f0\u58f0\u660e &#061;&#061;&#061;&#061;&#061;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ Android \u76ee\u6807<\/span><br \/>\n    androidTarget <span class=\"token punctuation\">{<\/span><br \/>\n        compilations<span class=\"token punctuation\">.<\/span><span class=\"token function\">all<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            kotlinOptions <span class=\"token punctuation\">{<\/span><br \/>\n                jvmTarget <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;17&#034;<\/span><\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ iOS \u76ee\u6807&#xff08;\u6839\u636e Mac \u67b6\u6784\u9009\u62e9&#xff09;<\/span><br \/>\n    <span class=\"token function\">iosX64<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">iosArm64<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">iosSimulatorArm64<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ Desktop (JVM) \u76ee\u6807<\/span><br \/>\n    <span class=\"token function\">jvm<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;desktop&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ &#061;&#061;&#061;&#061;&#061; \u6e90\u7801\u96c6\u914d\u7f6e &#061;&#061;&#061;&#061;&#061;<\/span><br \/>\n    sourceSets <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u516c\u5171\u6e90\u7801\u96c6&#xff1a;\u6240\u6709\u5e73\u53f0\u5171\u4eab\u7684 Agent \u903b\u8f91<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> commonMain <span class=\"token keyword\">by<\/span> getting <span class=\"token punctuation\">{<\/span><br \/>\n            dependencies <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ &#061;&#061;&#061; Koog \u6838\u5fc3\u4f9d\u8d56 &#061;&#061;&#061;<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;ai.koog:koog-agents-core:0.7.2&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;ai.koog:koog-agents-tools:0.7.2&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;ai.koog:koog-prompt-executor:0.7.2&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>                <span class=\"token comment\">\/\/ &#061;&#061;&#061; LLM \u5ba2\u6237\u7aef&#xff08;\u6309\u9700\u9009\u62e9&#xff09;&#061;&#061;&#061;<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;ai.koog:koog-llm-client-openai:0.7.2&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token comment\">\/\/ implementation(&#034;ai.koog:koog-llm-client-anthropic:0.7.2&#034;)<\/span><br \/>\n                <span class=\"token comment\">\/\/ implementation(&#034;ai.koog:koog-llm-client-ollama:0.7.2&#034;)<\/span><\/p>\n<p>                <span class=\"token comment\">\/\/ &#061;&#061;&#061; Kotlin \u57fa\u7840\u5e93 &#061;&#061;&#061;<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;org.jetbrains.kotlinx:kotlinx-datetime:0.6.1&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>                <span class=\"token comment\">\/\/ &#061;&#061;&#061; \u7f51\u7edc\u5c42&#xff08;Ktor&#xff09;&#061;&#061;&#061;<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;io.ktor:ktor-client-core:3.1.0&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;io.ktor:ktor-client-content-negotiation:3.1.0&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;io.ktor:ktor-serialization-kotlinx-json:3.1.0&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ Android \u7279\u5b9a\u5b9e\u73b0<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> androidMain <span class=\"token keyword\">by<\/span> getting <span class=\"token punctuation\">{<\/span><br \/>\n            dependencies <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;io.ktor:ktor-client-okhttp:3.1.0&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ iOS \u7279\u5b9a\u5b9e\u73b0<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> iosX64Main <span class=\"token keyword\">by<\/span> getting<br \/>\n        <span class=\"token keyword\">val<\/span> iosArm64Main <span class=\"token keyword\">by<\/span> getting<br \/>\n        <span class=\"token keyword\">val<\/span> iosSimulatorArm64Main <span class=\"token keyword\">by<\/span> getting<br \/>\n        <span class=\"token keyword\">val<\/span> iosMain <span class=\"token keyword\">by<\/span> creating <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token function\">dependsOn<\/span><span class=\"token punctuation\">(<\/span>commonMain<span class=\"token punctuation\">)<\/span><br \/>\n            iosX64Main<span class=\"token punctuation\">.<\/span><span class=\"token function\">dependsOn<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            iosArm64Main<span class=\"token punctuation\">.<\/span><span class=\"token function\">dependsOn<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            iosSimulatorArm64Main<span class=\"token punctuation\">.<\/span><span class=\"token function\">dependsOn<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">this<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            dependencies <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;io.ktor:ktor-client-darwin:3.1.0&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ Desktop (JVM) \u7279\u5b9a\u5b9e\u73b0<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> desktopMain <span class=\"token keyword\">by<\/span> getting <span class=\"token punctuation\">{<\/span><br \/>\n            dependencies <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;io.ktor:ktor-client-cio:3.1.0&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>android <span class=\"token punctuation\">{<\/span><br \/>\n    namespace <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;com.example.koogagent.shared&#034;<\/span><\/span><br \/>\n    compileSdk <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">35<\/span><br \/>\n    defaultConfig <span class=\"token punctuation\">{<\/span><br \/>\n        minSdk <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">26<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n    compileOptions <span class=\"token punctuation\">{<\/span><br \/>\n        sourceCompatibility <span class=\"token operator\">&#061;<\/span> JavaVersion<span class=\"token punctuation\">.<\/span>VERSION_17<br \/>\n        targetCompatibility <span class=\"token operator\">&#061;<\/span> JavaVersion<span class=\"token punctuation\">.<\/span>VERSION_17<br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h5>2.3.3 \u5e73\u53f0\u7279\u5b9a\u6a21\u5757\u914d\u7f6e<\/h5>\n<p>Android \u5e94\u7528\u6a21\u5757 (androidApp\/build.gradle.kts)&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ androidApp\/build.gradle.kts<\/span><br \/>\nplugins <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function\">alias<\/span><span class=\"token punctuation\">(<\/span>libs<span class=\"token punctuation\">.<\/span>plugins<span class=\"token punctuation\">.<\/span>androidApplication<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">alias<\/span><span class=\"token punctuation\">(<\/span>libs<span class=\"token punctuation\">.<\/span>plugins<span class=\"token punctuation\">.<\/span>kotlinAndroid<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">alias<\/span><span class=\"token punctuation\">(<\/span>libs<span class=\"token punctuation\">.<\/span>plugins<span class=\"token punctuation\">.<\/span>composeCompiler<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>android <span class=\"token punctuation\">{<\/span><br \/>\n    namespace <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;com.example.koogagent.android&#034;<\/span><\/span><br \/>\n    compileSdk <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">35<\/span><\/p>\n<p>    defaultConfig <span class=\"token punctuation\">{<\/span><br \/>\n        applicationId <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;com.example.koogagent.android&#034;<\/span><\/span><br \/>\n        minSdk <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">26<\/span><br \/>\n        targetSdk <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">35<\/span><br \/>\n        versionCode <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">1<\/span><br \/>\n        versionName <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;1.0&#034;<\/span><\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    buildFeatures <span class=\"token punctuation\">{<\/span><br \/>\n        compose <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    compileOptions <span class=\"token punctuation\">{<\/span><br \/>\n        sourceCompatibility <span class=\"token operator\">&#061;<\/span> JavaVersion<span class=\"token punctuation\">.<\/span>VERSION_17<br \/>\n        targetCompatibility <span class=\"token operator\">&#061;<\/span> JavaVersion<span class=\"token punctuation\">.<\/span>VERSION_17<br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    kotlinOptions <span class=\"token punctuation\">{<\/span><br \/>\n        jvmTarget <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;17&#034;<\/span><\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>dependencies <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">project<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;:shared&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ Compose UI<\/span><br \/>\n    <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">platform<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;androidx.compose:compose-bom:2025.06.00&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;androidx.compose.ui:ui&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;androidx.compose.material3:material3&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;androidx.activity:activity-compose:1.9.3&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u534f\u7a0b<\/span><br \/>\n    <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2.4 API Key \u7ba1\u7406\u4e0e\u5b89\u5168\u914d\u7f6e<\/h4>\n<p>\u26a0\ufe0f \u91cd\u8981\u5b89\u5168\u63d0\u793a&#xff1a;\u6c38\u8fdc\u4e0d\u8981\u5c06 API Key \u786c\u7f16\u7801\u5728\u6e90\u4ee3\u7801\u4e2d\u6216\u63d0\u4ea4\u5230\u7248\u672c\u63a7\u5236\u7cfb\u7edf\u3002<\/p>\n<p>\u65b9\u6848\u4e00&#xff1a;local.properties&#xff08;\u63a8\u8350\u5f00\u53d1\u9636\u6bb5&#xff09;<\/p>\n<p># local.properties&#xff08;\u6b64\u6587\u4ef6\u5df2\u5728 .gitignore \u4e2d&#xff09;<br \/>\nOPENAI_API_KEY&#061;sk-your-api-key-here<br \/>\n# \u5982\u679c\u4f7f\u7528\u56fd\u5185\u517c\u5bb9 OpenAI \u534f\u8bae\u7684\u670d\u52a1&#xff1a;<br \/>\n# LLM_BASE_URL&#061;https:\/\/dashscope.aliyuncs.com\/compatible-mode\/v1<br \/>\n# LLM_API_KEY&#061;sk-your-dashscope-key<\/p>\n<p>\u5728 Gradle \u4e2d\u8bfb\u53d6&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ shared\/build.gradle.kts \u4e2d\u6dfb\u52a0<\/span><br \/>\nandroid <span class=\"token punctuation\">{<\/span><br \/>\n    defaultConfig <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u4ece local.properties \u8bfb\u53d6 API Key<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> localProps <span class=\"token operator\">&#061;<\/span> java<span class=\"token punctuation\">.<\/span>util<span class=\"token punctuation\">.<\/span><span class=\"token function\">Properties<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">apply<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token function\">load<\/span><span class=\"token punctuation\">(<\/span>rootProject<span class=\"token punctuation\">.<\/span><span class=\"token function\">file<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;local.properties&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">inputStream<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token function\">buildConfigField<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;String&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;OPENAI_API_KEY&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\\\\&#034;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">localProps<span class=\"token punctuation\">.<\/span><span class=\"token function\">getProperty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;OPENAI_API_KEY&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">\\\\&#034;&#034;<\/span><\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u65b9\u6848\u4e8c&#xff1a;\u73af\u5883\u53d8\u91cf&#xff08;\u63a8\u8350 CI\/CD&#xff09;<\/p>\n<p><span class=\"token comment\">\/\/ \u5728 commonMain \u4e2d\u901a\u8fc7 expect\/actual \u83b7\u53d6<\/span><br \/>\n<span class=\"token comment\">\/\/ commonMain<\/span><br \/>\n<span class=\"token keyword\">expect<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">getApiKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String<\/p>\n<p><span class=\"token comment\">\/\/ androidMain<\/span><br \/>\n<span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">getApiKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String <span class=\"token operator\">&#061;<\/span> BuildConfig<span class=\"token punctuation\">.<\/span>OPENAI_API_KEY<\/p>\n<p><span class=\"token comment\">\/\/ iosMain<\/span><br \/>\n<span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">getApiKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> NSBundle<span class=\"token punctuation\">.<\/span>mainBundle<span class=\"token punctuation\">.<\/span>infoDictionary<br \/>\n        <span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;OPENAI_API_KEY&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span><span class=\"token operator\">?<\/span> String <span class=\"token operator\">?:<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;&#034;<\/span><\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ desktopMain<\/span><br \/>\n<span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">getApiKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> System<span class=\"token punctuation\">.<\/span><span class=\"token function\">getenv<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;OPENAI_API_KEY&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">?:<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;&#034;<\/span><\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>2.5 \u9a8c\u8bc1\u73af\u5883&#xff1a;\u8fd0\u884c\u7b2c\u4e00\u4e2a Gradle Task<\/h4>\n<p><span class=\"token comment\"># \u9a8c\u8bc1\u9879\u76ee\u53ef\u4ee5\u6b63\u5e38\u7f16\u8bd1\u6240\u6709\u5e73\u53f0<\/span><br \/>\n.\/gradlew :shared:compileKotlinDesktop    <span class=\"token comment\"># Desktop\/JVM<\/span><br \/>\n.\/gradlew :shared:compileDebugKotlinAndroid  <span class=\"token comment\"># Android<\/span><br \/>\n.\/gradlew :shared:compileKotlinIosArm64   <span class=\"token comment\"># iOS&#xff08;\u9700\u8981 macOS&#xff09;<\/span><\/p>\n<p><span class=\"token comment\"># \u5982\u679c\u4ee5\u4e0a\u547d\u4ee4\u5168\u90e8\u6210\u529f&#xff08;BUILD SUCCESSFUL&#xff09;&#xff0c;\u73af\u5883\u914d\u7f6e\u5b8c\u6210<\/span><\/p>\n<hr \/>\n<h3>\u4e09\u3001Koog \u6838\u5fc3\u6982\u5ff5\u89e3\u6790&#xff1a;\u4ece Prompt \u5230\u5de5\u5177\u8c03\u7528\u7684\u6620\u5c04<\/h3>\n<h4>3.1 Agent \u751f\u547d\u5468\u671f\u603b\u89c8<\/h4>\n<p>\u4e00\u4e2a Koog Agent \u7684\u5b8c\u6574\u751f\u547d\u5468\u671f\u5982\u4e0b&#xff1a;<\/p>\n<p>\u7528\u6237\u8f93\u5165 \u2192 Prompt \u7ec4\u88c5 \u2192 LLM \u8bf7\u6c42 \u2192 \u54cd\u5e94\u89e3\u6790<br \/>\n                                         \u2193<br \/>\n                              [\u662f\u5426\u5305\u542b Tool Call?]<br \/>\n                              \/                    \\\\<br \/>\n                           \u662f                      \u5426<br \/>\n                           \u2193                       \u2193<br \/>\n                    \u6267\u884c\u5de5\u5177\u51fd\u6570              \u8fd4\u56de\u6700\u7ec8\u56de\u7b54<br \/>\n                           \u2193<br \/>\n                    \u5de5\u5177\u7ed3\u679c\u56de\u4f20 LLM<br \/>\n                           \u2193<br \/>\n                    [\u7ee7\u7eed\u5faa\u73af\u6216\u7ed3\u675f]<\/p>\n<p>\u6838\u5fc3\u7ec4\u4ef6\u5173\u7cfb\u56fe&#xff1a;<\/p>\n<p>AIAgent<br \/>\n \u251c\u2500\u2500 PromptExecutor      \/\/ \u8d1f\u8d23\u4e0e LLM \u901a\u4fe1<br \/>\n \u2502    \u2514\u2500\u2500 LLMClient      \/\/ \u5177\u4f53\u7684\u6a21\u578b\u5ba2\u6237\u7aef<br \/>\n \u251c\u2500\u2500 Prompt              \/\/ \u7cfb\u7edf\u63d0\u793a\u8bcd &#043; \u5bf9\u8bdd\u5386\u53f2<br \/>\n \u251c\u2500\u2500 Tools[]             \/\/ \u53ef\u7528\u5de5\u5177\u5217\u8868<br \/>\n \u251c\u2500\u2500 Strategy            \/\/ \u51b3\u7b56\u7b56\u7565&#xff08;\u5355\u8f6e\/\u591a\u8f6e\/\u56fe&#xff09;<br \/>\n \u2514\u2500\u2500 Storage             \/\/ \u6301\u4e45\u5316\u5b58\u50a8<\/p>\n<h4>3.2 Prompt \u7cfb\u7edf&#xff1a;\u7ed3\u6784\u5316\u63d0\u793a\u8bcd\u5de5\u7a0b<\/h4>\n<h5>3.2.1 System Prompt \u4e0e User Prompt<\/h5>\n<p>\u5728 Koog \u4e2d&#xff0c;Prompt \u662f Agent \u4e0e LLM \u4ea4\u4e92\u7684\u57fa\u7840\u3002\u5b83\u5206\u4e3a\u4e24\u90e8\u5206&#xff1a;<\/p>\n<ul>\n<li>System Prompt&#xff1a;\u5b9a\u4e49 Agent \u7684\u89d2\u8272\u3001\u80fd\u529b\u8fb9\u754c\u3001\u884c\u4e3a\u89c4\u8303<\/li>\n<li>User Prompt&#xff1a;\u7528\u6237\u7684\u5b9e\u9645\u8f93\u5165<\/li>\n<\/ul>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>llm<span class=\"token punctuation\">.<\/span>LLMProvider<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>structural<span class=\"token punctuation\">.<\/span>StructuralPrompt<\/p>\n<p><span class=\"token comment\">\/\/ \u5b9a\u4e49\u7cfb\u7edf\u63d0\u793a\u8bcd<\/span><br \/>\n<span class=\"token keyword\">val<\/span> systemPrompt <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal multiline\"><span class=\"token string\">&#034;&#034;&#034;<br \/>\n    \u4f60\u662f\u4e00\u4e2a\u4e13\u4e1a\u7684\u4e2a\u4eba\u52a9\u7406 Agent&#xff0c;\u5177\u5907\u4ee5\u4e0b\u80fd\u529b&#xff1a;<br \/>\n    1. \u67e5\u8be2\u5929\u6c14\u4fe1\u606f<br \/>\n    2. \u7ba1\u7406\u7528\u6237\u65e5\u7a0b<br \/>\n    3. \u641c\u7d22\u672c\u5730\u6587\u4ef6<\/p>\n<p>    \u89c4\u5219&#xff1a;<br \/>\n    &#8211; \u56de\u7b54\u5fc5\u987b\u7b80\u6d01\u660e\u4e86&#xff0c;\u4e0d\u8d85\u8fc7 200 \u5b57<br \/>\n    &#8211; \u5982\u679c\u9700\u8981\u8c03\u7528\u5de5\u5177&#xff0c;\u5148\u8bf4\u660e\u4f60\u8981\u505a\u4ec0\u4e48<br \/>\n    &#8211; \u4e0d\u786e\u5b9a\u7684\u4fe1\u606f\u4e0d\u8981\u7f16\u9020&#xff0c;\u76f4\u63a5\u544a\u77e5\u7528\u6237<br \/>\n&#034;&#034;&#034;<\/span><\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">trimIndent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<h5>3.2.2 PromptTemplate \u4e0e\u52a8\u6001\u53d8\u91cf\u6ce8\u5165<\/h5>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>template<span class=\"token punctuation\">.<\/span>PromptTemplate<\/p>\n<p><span class=\"token comment\">\/\/ \u521b\u5efa\u5e26\u53d8\u91cf\u7684\u63d0\u793a\u8bcd\u6a21\u677f<\/span><br \/>\n<span class=\"token keyword\">val<\/span> assistantTemplate <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">PromptTemplate<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    system <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal multiline\"><span class=\"token string\">&#034;&#034;&#034;<br \/>\n        \u4f60\u662f {{role}}&#xff0c;\u670d\u52a1\u4e8e {{company}} \u7684 AI \u52a9\u624b\u3002<br \/>\n        \u5f53\u524d\u7528\u6237&#xff1a;{{userName}}<br \/>\n        \u5f53\u524d\u65f6\u95f4&#xff1a;{{currentTime}}<\/p>\n<p>        \u4f60\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u5de5\u5177\u6765\u5e2e\u52a9\u7528\u6237&#xff1a;<br \/>\n        {{availableTools}}<br \/>\n    &#034;&#034;&#034;<\/span><\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">trimIndent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u8fd0\u884c\u65f6\u52a8\u6001\u586b\u5145\u53d8\u91cf<\/span><br \/>\n    variables <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mapOf<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;role&#034;<\/span><\/span> <span class=\"token keyword\">to<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u667a\u80fd\u5ba2\u670d\u4e13\u5458&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;company&#034;<\/span><\/span> <span class=\"token keyword\">to<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u793a\u4f8b\u79d1\u6280\u6709\u9650\u516c\u53f8&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;userName&#034;<\/span><\/span> <span class=\"token keyword\">to<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u5f20\u4e09&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;currentTime&#034;<\/span><\/span> <span class=\"token keyword\">to<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;2026-08-06 11:53&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;availableTools&#034;<\/span><\/span> <span class=\"token keyword\">to<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u5929\u6c14\u67e5\u8be2\u3001\u65e5\u7a0b\u7ba1\u7406\u3001\u6587\u4ef6\u641c\u7d22&#034;<\/span><\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u6e32\u67d3\u6700\u7ec8 Prompt<\/span><br \/>\n<span class=\"token keyword\">val<\/span> renderedPrompt <span class=\"token operator\">&#061;<\/span> assistantTemplate<span class=\"token punctuation\">.<\/span><span class=\"token function\">render<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token function\">println<\/span><span class=\"token punctuation\">(<\/span>renderedPrompt<span class=\"token punctuation\">)<\/span><\/p>\n<h4>3.3 LLM \u62bd\u8c61\u5c42&#xff1a;\u6a21\u578b\u65e0\u5173\u8bbe\u8ba1<\/h4>\n<p>Koog \u7684 LLM \u62bd\u8c61\u5c42\u8ba9\u4f60\u53ef\u4ee5\u65e0\u7f1d\u5207\u6362\u4e0d\u540c\u7684\u6a21\u578b\u63d0\u4f9b\u5546&#xff1a;<\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>llm<span class=\"token punctuation\">.<\/span>LLModel<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>llm<span class=\"token punctuation\">.<\/span>LLMCapability<\/p>\n<p><span class=\"token comment\">\/\/ \u5b9a\u4e49\u6a21\u578b\u914d\u7f6e<\/span><br \/>\n<span class=\"token keyword\">val<\/span> gpt4oModel <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">LLModel<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    provider <span class=\"token operator\">&#061;<\/span> LLMProvider<span class=\"token punctuation\">.<\/span>OpenAI<span class=\"token punctuation\">,<\/span><br \/>\n    id <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;gpt-4o&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n    capabilities <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">setOf<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        LLMCapability<span class=\"token punctuation\">.<\/span>Completion<span class=\"token punctuation\">,<\/span>       <span class=\"token comment\">\/\/ \u6587\u672c\u8865\u5168<\/span><br \/>\n        LLMCapability<span class=\"token punctuation\">.<\/span>Tools<span class=\"token punctuation\">,<\/span>            <span class=\"token comment\">\/\/ \u5de5\u5177\u8c03\u7528<\/span><br \/>\n        LLMCapability<span class=\"token punctuation\">.<\/span>Streaming<span class=\"token punctuation\">,<\/span>        <span class=\"token comment\">\/\/ \u6d41\u5f0f\u8f93\u51fa<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    contextLength <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">128_000<\/span><span class=\"token punctuation\">,<\/span>            <span class=\"token comment\">\/\/ \u4e0a\u4e0b\u6587\u7a97\u53e3<\/span><br \/>\n    maxOutputTokens <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4_096<\/span>             <span class=\"token comment\">\/\/ \u6700\u5927\u8f93\u51fa token<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u4f7f\u7528 Ollama \u672c\u5730\u6a21\u578b&#xff08;\u7aef\u4fa7\u63a8\u7406&#xff09;<\/span><br \/>\n<span class=\"token keyword\">val<\/span> localModel <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">LLModel<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    provider <span class=\"token operator\">&#061;<\/span> LLMProvider<span class=\"token punctuation\">.<\/span>Ollama<span class=\"token punctuation\">,<\/span><br \/>\n    id <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;llama3.1:8b&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n    capabilities <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">setOf<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        LLMCapability<span class=\"token punctuation\">.<\/span>Completion<span class=\"token punctuation\">,<\/span><br \/>\n        LLMCapability<span class=\"token punctuation\">.<\/span>Tools<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    contextLength <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">8_192<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    maxOutputTokens <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">2_048<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<h4>3.4 Tool&#xff08;\u5de5\u5177&#xff09;\u7cfb\u7edf&#xff1a;\u7c7b\u578b\u5b89\u5168\u7684\u51fd\u6570\u8c03\u7528<\/h4>\n<h5>3.4.1 \u5de5\u5177\u5b9a\u4e49\u4e0e\u53c2\u6570 Schema<\/h5>\n<p>Koog \u7684\u5de5\u5177\u7cfb\u7edf\u662f\u5176\u6700\u6838\u5fc3\u7684\u5dee\u5f02\u5316\u80fd\u529b\u4e4b\u4e00\u3002\u5de5\u5177\u5b9a\u4e49\u5b8c\u5168\u7c7b\u578b\u5b89\u5168&#xff1a;<\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span>annotation<span class=\"token punctuation\">.<\/span>Tool<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span>annotation<span class=\"token punctuation\">.<\/span>ToolParam<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>serialization<span class=\"token punctuation\">.<\/span>Serializable<\/p>\n<p><span class=\"token comment\">\/\/ \u5b9a\u4e49\u5de5\u5177\u53c2\u6570&#xff08;\u5fc5\u987b\u662f\u53ef\u5e8f\u5217\u5316\u7684\u6570\u636e\u7c7b&#xff09;<\/span><br \/>\n<span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n<span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">WeatherRequest<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token annotation builtin\">&#064;ToolParam<\/span><span class=\"token punctuation\">(<\/span>description <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u57ce\u5e02\u540d\u79f0&#xff0c;\u5982&#xff1a;\u5317\u4eac\u3001\u4e0a\u6d77&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> city<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;ToolParam<\/span><span class=\"token punctuation\">(<\/span>description <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u65e5\u671f&#xff0c;\u683c\u5f0f YYYY-MM-DD&#xff0c;\u9ed8\u8ba4\u4eca\u5929&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> date<span class=\"token operator\">:<\/span> String <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;&#034;<\/span><\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5b9a\u4e49\u5de5\u5177\u8fd4\u56de\u503c<\/span><br \/>\n<span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n<span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">WeatherResponse<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> temperature<span class=\"token operator\">:<\/span> Double<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> condition<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> humidity<span class=\"token operator\">:<\/span> Int<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> windSpeed<span class=\"token operator\">:<\/span> Double<br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5b9a\u4e49\u5de5\u5177\u51fd\u6570<\/span><br \/>\n<span class=\"token keyword\">class<\/span> WeatherTools <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Tool<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        name <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;get_weather&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n        description <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u67e5\u8be2\u6307\u5b9a\u57ce\u5e02\u7684\u5929\u6c14\u4fe1\u606f\u3002\u5f53\u7528\u6237\u8be2\u95ee\u5929\u6c14\u76f8\u5173\u95ee\u9898\u65f6\u8c03\u7528\u6b64\u5de5\u5177\u3002&#034;<\/span><\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">getWeather<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token operator\">:<\/span> WeatherRequest<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> WeatherResponse <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5b9e\u9645\u5b9e\u73b0&#xff1a;\u8c03\u7528\u5929\u6c14 API<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> apiUrl <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;https:\/\/api.weather.example.com\/v1\/current&#034;<\/span><\/span><br \/>\n        <span class=\"token comment\">\/\/ &#8230; \u7f51\u7edc\u8bf7\u6c42\u903b\u8f91<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token function\">WeatherResponse<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            temperature <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">28.5<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            condition <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u6674&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n            humidity <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">45<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            windSpeed <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">3.2<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h5>3.4.2 \u5de5\u5177\u6267\u884c\u4e0e\u7ed3\u679c\u56de\u4f20<\/h5>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span>ToolExecutor<\/p>\n<p><span class=\"token comment\">\/\/ \u5de5\u5177\u6267\u884c\u5668\u8d1f\u8d23&#xff1a;<\/span><br \/>\n<span class=\"token comment\">\/\/ 1. \u63a5\u6536 LLM \u8fd4\u56de\u7684 tool_call \u6307\u4ee4<\/span><br \/>\n<span class=\"token comment\">\/\/ 2. \u53cd\u5e8f\u5217\u5316\u53c2\u6570<\/span><br \/>\n<span class=\"token comment\">\/\/ 3. \u8c03\u7528\u5bf9\u5e94\u7684\u5de5\u5177\u51fd\u6570<\/span><br \/>\n<span class=\"token comment\">\/\/ 4. \u5e8f\u5217\u5316\u7ed3\u679c\u5e76\u56de\u4f20\u7ed9 LLM<\/span><\/p>\n<p><span class=\"token keyword\">val<\/span> toolExecutor <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ToolExecutor<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    tools <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">listOf<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token function\">WeatherTools<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token function\">CalendarTools<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token function\">FileSearchTools<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5f53 LLM \u8fd4\u56de tool_call \u65f6&#xff0c;\u6846\u67b6\u81ea\u52a8\u6267\u884c&#xff1a;<\/span><br \/>\n<span class=\"token comment\">\/\/ LLM Response: {&#034;tool_calls&#034;: [{&#034;function&#034;: {&#034;name&#034;: &#034;get_weather&#034;, &#034;arguments&#034;: &#034;{\\\\&#034;city\\\\&#034;: \\\\&#034;\u5317\u4eac\\\\&#034;}&#034;}}]}<\/span><br \/>\n<span class=\"token comment\">\/\/ \u2192 ToolExecutor \u89e3\u6790 \u2192 \u8c03\u7528 WeatherTools.getWeather(WeatherRequest(city&#061;&#034;\u5317\u4eac&#034;))<\/span><br \/>\n<span class=\"token comment\">\/\/ \u2192 \u5e8f\u5217\u5316 WeatherResponse \u2192 \u4f5c\u4e3a tool_result \u56de\u4f20 LLM<\/span><\/p>\n<h4>3.5 Strategy&#xff08;\u7b56\u7565&#xff09;&#xff1a;Agent \u7684\u51b3\u7b56\u5f15\u64ce<\/h4>\n<p>Strategy \u51b3\u5b9a\u4e86 Agent \u5982\u4f55\u5904\u7406\u7528\u6237\u8bf7\u6c42&#xff1a;<\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>strategy<span class=\"token punctuation\">.<\/span>BasicAgentStrategy<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>strategy<span class=\"token punctuation\">.<\/span>FunctionalAgentStrategy<\/p>\n<p><span class=\"token comment\">\/\/ \u7b56\u7565\u4e00&#xff1a;\u57fa\u7840\u5355\u8f6e\u7b56\u7565&#xff08;\u7b80\u5355\u95ee\u7b54&#xff09;<\/span><br \/>\n<span class=\"token keyword\">val<\/span> basicStrategy <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">BasicAgentStrategy<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    maxIterations <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">5<\/span>  <span class=\"token comment\">\/\/ \u6700\u5927\u5de5\u5177\u8c03\u7528\u8f6e\u6b21<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u7b56\u7565\u4e8c&#xff1a;\u51fd\u6570\u5f0f\u7b56\u7565&#xff08;\u81ea\u5b9a\u4e49\u6d41\u7a0b&#xff09;<\/span><br \/>\n<span class=\"token keyword\">val<\/span> customStrategy <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">FunctionalAgentStrategy<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;weather-check&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> ctx<span class=\"token punctuation\">,<\/span> input <span class=\"token operator\">-&gt;<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u7b2c\u4e00\u6b65&#xff1a;\u89e3\u6790\u7528\u6237\u610f\u56fe<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> intent <span class=\"token operator\">&#061;<\/span> ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">analyzeIntent<\/span><span class=\"token punctuation\">(<\/span>input<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u7b2c\u4e8c\u6b65&#xff1a;\u6839\u636e\u610f\u56fe\u9009\u62e9\u6267\u884c\u8def\u5f84<\/span><br \/>\n    <span class=\"token keyword\">when<\/span> <span class=\"token punctuation\">(<\/span>intent<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;weather_query&#034;<\/span><\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">val<\/span> city <span class=\"token operator\">&#061;<\/span> ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">extractCity<\/span><span class=\"token punctuation\">(<\/span>input<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token keyword\">val<\/span> weather <span class=\"token operator\">&#061;<\/span> ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">callTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;get_weather&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function\">mapOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;city&#034;<\/span><\/span> <span class=\"token keyword\">to<\/span> city<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">respond<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u4eca\u5929<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">city<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">\u7684\u5929\u6c14\u662f&#xff1a;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">weather<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;schedule_query&#034;<\/span><\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">val<\/span> events <span class=\"token operator\">&#061;<\/span> ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">callTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;get_schedule&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function\">mapOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;date&#034;<\/span><\/span> <span class=\"token keyword\">to<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;today&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">respond<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u4f60\u4eca\u5929\u7684\u65e5\u7a0b&#xff1a;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$<\/span><span class=\"token expression\">events<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token keyword\">else<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">respond<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u62b1\u6b49&#xff0c;\u6211\u6682\u65f6\u65e0\u6cd5\u5904\u7406\u8fd9\u4e2a\u8bf7\u6c42\u3002&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>3.6 Graph Workflow&#xff1a;\u56fe\u5de5\u4f5c\u6d41\u5f15\u64ce<\/h4>\n<p>\u5bf9\u4e8e\u590d\u6742\u7684\u591a\u6b65\u9aa4\u4efb\u52a1&#xff0c;Koog \u63d0\u4f9b\u4e86\u56fe\u5de5\u4f5c\u6d41\u5f15\u64ce&#xff1a;<\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>graph<span class=\"token punctuation\">.<\/span>GraphAgentStrategy<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>graph<span class=\"token punctuation\">.<\/span>node<\/p>\n<p><span class=\"token keyword\">val<\/span> workflowStrategy <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">GraphAgentStrategy<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;order-processing&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u5b9a\u4e49\u8282\u70b9<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> validateNode <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">node<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;validate&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> ctx <span class=\"token operator\">-&gt;<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u9a8c\u8bc1\u8ba2\u5355\u4fe1\u606f<\/span><br \/>\n        ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">set<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;isValid&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">next<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;process&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">val<\/span> processNode <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">node<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;process&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> ctx <span class=\"token operator\">-&gt;<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5904\u7406\u8ba2\u5355<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> orderId <span class=\"token operator\">&#061;<\/span> ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">callTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;create_order&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;orderData&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">set<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;orderId&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> orderId<span class=\"token punctuation\">)<\/span><br \/>\n        ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">next<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;notify&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">val<\/span> notifyNode <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">node<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;notify&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> ctx <span class=\"token operator\">-&gt;<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u53d1\u9001\u901a\u77e5<\/span><br \/>\n        ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">callTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;send_notification&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function\">mapOf<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;userId&#034;<\/span><\/span> <span class=\"token keyword\">to<\/span> ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;userId&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;message&#034;<\/span><\/span> <span class=\"token keyword\">to<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u8ba2\u5355 <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;orderId&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\"> \u5df2\u521b\u5efa&#034;<\/span><\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        ctx<span class=\"token punctuation\">.<\/span><span class=\"token function\">finish<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u8ba2\u5355\u5904\u7406\u5b8c\u6210&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u5b9a\u4e49\u8fb9&#xff08;\u6d41\u8f6c\u5173\u7cfb&#xff09;<\/span><br \/>\n    <span class=\"token function\">edge<\/span><span class=\"token punctuation\">(<\/span>validateNode<span class=\"token punctuation\">,<\/span> processNode<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token function\">edge<\/span><span class=\"token punctuation\">(<\/span>processNode<span class=\"token punctuation\">,<\/span> notifyNode<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u8bbe\u7f6e\u5165\u53e3<\/span><br \/>\n    <span class=\"token function\">entry<\/span><span class=\"token punctuation\">(<\/span>validateNode<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<hr \/>\n<h3>\u56db\u3001\u5b9e\u6218\u7b2c\u4e00\u6b65&#xff1a;\u5728 Android \u7aef\u521d\u59cb\u5316\u9996\u4e2a AI Agent \u5b9e\u4f8b<\/h3>\n<h4>4.1 \u521b\u5efa Agent \u914d\u7f6e\u7c7b<\/h4>\n<p><span class=\"token comment\">\/\/ shared\/src\/commonMain\/kotlin\/com\/example\/koogagent\/AgentConfig.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>llm<span class=\"token punctuation\">.<\/span>LLModel<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>llm<span class=\"token punctuation\">.<\/span>LLMProvider<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>llm<span class=\"token punctuation\">.<\/span>LLMCapability<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * Agent \u5168\u5c40\u914d\u7f6e<br \/>\n * \u96c6\u4e2d\u7ba1\u7406\u6a21\u578b\u9009\u62e9\u3001API \u914d\u7f6e\u7b49<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">object<\/span> AgentConfig <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u4f7f\u7528\u7684 LLM \u6a21\u578b<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> model <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">LLModel<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        provider <span class=\"token operator\">&#061;<\/span> LLMProvider<span class=\"token punctuation\">.<\/span>OpenAI<span class=\"token punctuation\">,<\/span><br \/>\n        id <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;gpt-4o-mini&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u5f00\u53d1\u9636\u6bb5\u7528 mini \u8282\u7701\u6210\u672c<\/span><br \/>\n        capabilities <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">setOf<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            LLMCapability<span class=\"token punctuation\">.<\/span>Completion<span class=\"token punctuation\">,<\/span><br \/>\n            LLMCapability<span class=\"token punctuation\">.<\/span>Tools<span class=\"token punctuation\">,<\/span><br \/>\n            LLMCapability<span class=\"token punctuation\">.<\/span>Streaming<br \/>\n        <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        contextLength <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">128_000<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        maxOutputTokens <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4_096<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ Agent \u7cfb\u7edf\u63d0\u793a\u8bcd<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> systemPrompt <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal multiline\"><span class=\"token string\">&#034;&#034;&#034;<br \/>\n        \u4f60\u662f\u4e00\u4e2a\u667a\u80fd\u4e2a\u4eba\u52a9\u624b&#xff0c;\u8fd0\u884c\u5728\u7528\u6237\u7684\u79fb\u52a8\u8bbe\u5907\u4e0a\u3002<\/p>\n<p>        \u4f60\u7684\u80fd\u529b&#xff1a;<br \/>\n        1. \u67e5\u8be2\u5b9e\u65f6\u5929\u6c14<br \/>\n        2. \u7ba1\u7406\u7528\u6237\u5f85\u529e\u4e8b\u9879<br \/>\n        3. \u8fdb\u884c\u7b80\u5355\u7684\u6570\u5b66\u8ba1\u7b97<\/p>\n<p>        \u884c\u4e3a\u51c6\u5219&#xff1a;<br \/>\n        &#8211; \u56de\u7b54\u7b80\u6d01&#xff0c;\u4e0d\u8d85\u8fc7 150 \u5b57<br \/>\n        &#8211; \u9700\u8981\u5de5\u5177\u65f6\u4e3b\u52a8\u8c03\u7528<br \/>\n        &#8211; \u9047\u5230\u4e0d\u786e\u5b9a\u7684\u95ee\u9898\u8bda\u5b9e\u544a\u77e5<br \/>\n        &#8211; \u4f7f\u7528\u4e2d\u6587\u56de\u7b54<br \/>\n    &#034;&#034;&#034;<\/span><\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">trimIndent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u6700\u5927\u5de5\u5177\u8c03\u7528\u8fed\u4ee3\u6b21\u6570&#xff08;\u9632\u6b62\u65e0\u9650\u5faa\u73af&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> <span class=\"token keyword\">val<\/span> MAX_TOOL_ITERATIONS <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">10<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u8bf7\u6c42\u8d85\u65f6\u65f6\u95f4&#xff08;\u6beb\u79d2&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> <span class=\"token keyword\">val<\/span> REQUEST_TIMEOUT_MS <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">30_000L<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>4.2 \u521d\u59cb\u5316 PromptExecutor<\/h4>\n<p><span class=\"token comment\">\/\/ shared\/src\/commonMain\/kotlin\/com\/example\/koogagent\/AgentFactory.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>core<span class=\"token punctuation\">.<\/span>agent<span class=\"token punctuation\">.<\/span>AIAgent<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>executor<span class=\"token punctuation\">.<\/span>SingleLLMPromptExecutor<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>executor<span class=\"token punctuation\">.<\/span>clients<span class=\"token punctuation\">.<\/span>openai<span class=\"token punctuation\">.<\/span>OpenAILLMClient<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>executor<span class=\"token punctuation\">.<\/span>clients<span class=\"token punctuation\">.<\/span>LLMClientConfiguration<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * Agent \u5de5\u5382&#xff1a;\u8d1f\u8d23\u521b\u5efa\u548c\u914d\u7f6e Agent \u5b9e\u4f8b<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">object<\/span> AgentFactory <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u521b\u5efa\u57fa\u7840 Agent \u5b9e\u4f8b<br \/>\n     * &#064;param apiKey LLM API \u5bc6\u94a5<br \/>\n     * &#064;return \u914d\u7f6e\u5b8c\u6210\u7684 AIAgent<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">createBasicAgent<\/span><span class=\"token punctuation\">(<\/span>apiKey<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> AIAgent <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 1. \u914d\u7f6e LLM \u5ba2\u6237\u7aef<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> clientConfig <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">LLMClientConfiguration<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            apiKey <span class=\"token operator\">&#061;<\/span> apiKey<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u5982\u679c\u4f7f\u7528\u56fd\u5185\u517c\u5bb9\u670d\u52a1&#xff0c;\u8bbe\u7f6e baseUrl&#xff1a;<\/span><br \/>\n            <span class=\"token comment\">\/\/ baseUrl &#061; &#034;https:\/\/dashscope.aliyuncs.com\/compatible-mode\/v1&#034;<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 2. \u521b\u5efa OpenAI \u5ba2\u6237\u7aef<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> llmClient <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">OpenAILLMClient<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            configuration <span class=\"token operator\">&#061;<\/span> clientConfig<br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 3. \u521b\u5efa Prompt \u6267\u884c\u5668<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> promptExecutor <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">SingleLLMPromptExecutor<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            llmClient <span class=\"token operator\">&#061;<\/span> llmClient<br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 4. \u6784\u5efa Agent<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> agent <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">AIAgent<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            promptExecutor <span class=\"token operator\">&#061;<\/span> promptExecutor<span class=\"token punctuation\">,<\/span><br \/>\n            model <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>model<span class=\"token punctuation\">,<\/span><br \/>\n            systemPrompt <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>systemPrompt<span class=\"token punctuation\">,<\/span><br \/>\n            maxIterations <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>MAX_TOOL_ITERATIONS<br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> agent<br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>4.3 \u6784\u5efa AIAgent \u5b9e\u4f8b&#xff08;\u5e26\u5de5\u5177&#xff09;<\/h4>\n<p><span class=\"token comment\">\/\/ shared\/src\/commonMain\/kotlin\/com\/example\/koogagent\/AgentFactory.kt&#xff08;\u7eed&#xff09;<\/span><\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span>ToolSet<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u521b\u5efa\u5e26\u5de5\u5177\u7684\u5b8c\u6574 Agent<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">fun<\/span> <span class=\"token function\">createFullAgent<\/span><span class=\"token punctuation\">(<\/span>apiKey<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> AIAgent <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">val<\/span> clientConfig <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">LLMClientConfiguration<\/span><span class=\"token punctuation\">(<\/span>apiKey <span class=\"token operator\">&#061;<\/span> apiKey<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> llmClient <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">OpenAILLMClient<\/span><span class=\"token punctuation\">(<\/span>configuration <span class=\"token operator\">&#061;<\/span> clientConfig<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> promptExecutor <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">SingleLLMPromptExecutor<\/span><span class=\"token punctuation\">(<\/span>llmClient <span class=\"token operator\">&#061;<\/span> llmClient<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u6ce8\u518c\u5de5\u5177\u96c6<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> toolSet <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ToolSet<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        tools <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">listOf<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token function\">WeatherTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u5929\u6c14\u67e5\u8be2<\/span><br \/>\n            <span class=\"token function\">TodoTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span>         <span class=\"token comment\">\/\/ \u5f85\u529e\u7ba1\u7406<\/span><br \/>\n            <span class=\"token function\">CalculatorTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span>    <span class=\"token comment\">\/\/ \u8ba1\u7b97\u5668<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">val<\/span> agent <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">AIAgent<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        promptExecutor <span class=\"token operator\">&#061;<\/span> promptExecutor<span class=\"token punctuation\">,<\/span><br \/>\n        model <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>model<span class=\"token punctuation\">,<\/span><br \/>\n        systemPrompt <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>systemPrompt<span class=\"token punctuation\">,<\/span><br \/>\n        tools <span class=\"token operator\">&#061;<\/span> toolSet<span class=\"token punctuation\">,<\/span><br \/>\n        maxIterations <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>MAX_TOOL_ITERATIONS<br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">return<\/span> agent<br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>4.4 \u5728 Activity\/ViewModel \u4e2d\u96c6\u6210<\/h4>\n<p><span class=\"token comment\">\/\/ androidApp\/src\/main\/java\/com\/example\/koogagent\/android\/ChatViewModel.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>android<\/p>\n<p><span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>lifecycle<span class=\"token punctuation\">.<\/span>ViewModel<br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>lifecycle<span class=\"token punctuation\">.<\/span>viewModelScope<br \/>\n<span class=\"token keyword\">import<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>AgentFactory<br \/>\n<span class=\"token keyword\">import<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>getApiKey<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span>flow<span class=\"token punctuation\">.<\/span>MutableStateFlow<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span>flow<span class=\"token punctuation\">.<\/span>StateFlow<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span>flow<span class=\"token punctuation\">.<\/span>asStateFlow<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span>launch<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u804a\u5929\u754c\u9762 ViewModel<br \/>\n * \u7ba1\u7406 Agent \u4ea4\u4e92\u4e0e UI \u72b6\u6001<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> ChatViewModel <span class=\"token operator\">:<\/span> <span class=\"token function\">ViewModel<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ UI \u72b6\u6001<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> _messages <span class=\"token operator\">&#061;<\/span> MutableStateFlow<span class=\"token operator\">&lt;<\/span>List<span class=\"token operator\">&lt;<\/span>ChatMessage<span class=\"token operator\">&gt;<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">emptyList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> messages<span class=\"token operator\">:<\/span> StateFlow<span class=\"token operator\">&lt;<\/span>List<span class=\"token operator\">&lt;<\/span>ChatMessage<span class=\"token operator\">&gt;<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> _messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">asStateFlow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> _isLoading <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">MutableStateFlow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> isLoading<span class=\"token operator\">:<\/span> StateFlow<span class=\"token operator\">&lt;<\/span>Boolean<span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> _isLoading<span class=\"token punctuation\">.<\/span><span class=\"token function\">asStateFlow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> _error <span class=\"token operator\">&#061;<\/span> MutableStateFlow<span class=\"token operator\">&lt;<\/span>String<span class=\"token operator\">?<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">null<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> error<span class=\"token operator\">:<\/span> StateFlow<span class=\"token operator\">&lt;<\/span>String<span class=\"token operator\">?<\/span><span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> _error<span class=\"token punctuation\">.<\/span><span class=\"token function\">asStateFlow<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ Agent \u5b9e\u4f8b&#xff08;\u61d2\u52a0\u8f7d&#xff09;<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> agent <span class=\"token keyword\">by<\/span> lazy <span class=\"token punctuation\">{<\/span><br \/>\n        AgentFactory<span class=\"token punctuation\">.<\/span><span class=\"token function\">createFullAgent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">getApiKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u53d1\u9001\u7528\u6237\u6d88\u606f\u5e76\u83b7\u53d6 Agent \u56de\u590d<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">sendMessage<\/span><span class=\"token punctuation\">(<\/span>userInput<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>userInput<span class=\"token punctuation\">.<\/span><span class=\"token function\">isBlank<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">return<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6dfb\u52a0\u7528\u6237\u6d88\u606f\u5230\u5217\u8868<\/span><br \/>\n        _messages<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> _messages<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#043;<\/span> <span class=\"token function\">ChatMessage<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            role <span class=\"token operator\">&#061;<\/span> MessageRole<span class=\"token punctuation\">.<\/span>USER<span class=\"token punctuation\">,<\/span><br \/>\n            content <span class=\"token operator\">&#061;<\/span> userInput<br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        _isLoading<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><br \/>\n        _error<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">null<\/span><\/p>\n<p>        viewModelScope<span class=\"token punctuation\">.<\/span><span class=\"token function\">launch<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u8c03\u7528 Agent \u5904\u7406\u7528\u6237\u8f93\u5165<\/span><br \/>\n                <span class=\"token keyword\">val<\/span> response <span class=\"token operator\">&#061;<\/span> agent<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span>userInput<span class=\"token punctuation\">)<\/span><\/p>\n<p>                <span class=\"token comment\">\/\/ \u6dfb\u52a0 Agent \u56de\u590d<\/span><br \/>\n                _messages<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> _messages<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#043;<\/span> <span class=\"token function\">ChatMessage<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    role <span class=\"token operator\">&#061;<\/span> MessageRole<span class=\"token punctuation\">.<\/span>ASSISTANT<span class=\"token punctuation\">,<\/span><br \/>\n                    content <span class=\"token operator\">&#061;<\/span> response<span class=\"token punctuation\">.<\/span>content<br \/>\n                <span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span>e<span class=\"token operator\">:<\/span> Exception<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                _error<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u8bf7\u6c42\u5931\u8d25&#xff1a;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">e<span class=\"token punctuation\">.<\/span>message<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">finally<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                _isLoading<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u6e05\u7a7a\u5bf9\u8bdd\u5386\u53f2<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">clearHistory<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        _messages<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">emptyList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        agent<span class=\"token punctuation\">.<\/span><span class=\"token function\">resetConversation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u6d88\u606f\u6570\u636e\u6a21\u578b<\/span><br \/>\n<span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">ChatMessage<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> role<span class=\"token operator\">:<\/span> MessageRole<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> content<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> timestamp<span class=\"token operator\">:<\/span> Long <span class=\"token operator\">&#061;<\/span> System<span class=\"token punctuation\">.<\/span><span class=\"token function\">currentTimeMillis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token keyword\">enum<\/span> <span class=\"token keyword\">class<\/span> MessageRole <span class=\"token punctuation\">{<\/span><br \/>\n    USER<span class=\"token punctuation\">,<\/span> ASSISTANT<span class=\"token punctuation\">,<\/span> SYSTEM<span class=\"token punctuation\">,<\/span> TOOL<br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>4.5 \u8fd0\u884c\u4e0e\u9a8c\u8bc1<\/h4>\n<p><span class=\"token comment\">\/\/ androidApp\/src\/main\/java\/com\/example\/koogagent\/android\/ChatScreen.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>android<\/p>\n<p><span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>foundation<span class=\"token punctuation\">.<\/span>layout<span class=\"token punctuation\">.<\/span><span class=\"token operator\">*<\/span><br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>foundation<span class=\"token punctuation\">.<\/span>lazy<span class=\"token punctuation\">.<\/span>LazyColumn<br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>foundation<span class=\"token punctuation\">.<\/span>lazy<span class=\"token punctuation\">.<\/span>items<br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>material3<span class=\"token punctuation\">.<\/span><span class=\"token operator\">*<\/span><br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>runtime<span class=\"token punctuation\">.<\/span><span class=\"token operator\">*<\/span><br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>ui<span class=\"token punctuation\">.<\/span>Alignment<br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>ui<span class=\"token punctuation\">.<\/span>Modifier<br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>ui<span class=\"token punctuation\">.<\/span>unit<span class=\"token punctuation\">.<\/span>dp<br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>lifecycle<span class=\"token punctuation\">.<\/span>viewmodel<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>viewModel<\/p>\n<p><span class=\"token annotation builtin\">&#064;OptIn<\/span><span class=\"token punctuation\">(<\/span>ExperimentalMaterial3Api<span class=\"token operator\">::<\/span><span class=\"token keyword\">class<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token annotation builtin\">&#064;Composable<\/span><br \/>\n<span class=\"token keyword\">fun<\/span> <span class=\"token function\">ChatScreen<\/span><span class=\"token punctuation\">(<\/span>viewModel<span class=\"token operator\">:<\/span> ChatViewModel <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">viewModel<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> messages <span class=\"token keyword\">by<\/span> viewModel<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">collectAsState<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> isLoading <span class=\"token keyword\">by<\/span> viewModel<span class=\"token punctuation\">.<\/span>isLoading<span class=\"token punctuation\">.<\/span><span class=\"token function\">collectAsState<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">var<\/span> inputText <span class=\"token keyword\">by<\/span> remember <span class=\"token punctuation\">{<\/span> <span class=\"token function\">mutableStateOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token function\">Scaffold<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        topBar <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token function\">TopAppBar<\/span><span class=\"token punctuation\">(<\/span>title <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token function\">Text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;Koog AI \u52a9\u624b&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> padding <span class=\"token operator\">-&gt;<\/span><br \/>\n        <span class=\"token function\">Column<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            modifier <span class=\"token operator\">&#061;<\/span> Modifier<br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">fillMaxSize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">padding<\/span><span class=\"token punctuation\">(<\/span>padding<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u6d88\u606f\u5217\u8868<\/span><br \/>\n            <span class=\"token function\">LazyColumn<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                modifier <span class=\"token operator\">&#061;<\/span> Modifier<span class=\"token punctuation\">.<\/span><span class=\"token function\">weight<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1f<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                contentPadding <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">PaddingValues<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">16<\/span><span class=\"token punctuation\">.<\/span>dp<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                verticalArrangement <span class=\"token operator\">&#061;<\/span> Arrangement<span class=\"token punctuation\">.<\/span><span class=\"token function\">spacedBy<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">8<\/span><span class=\"token punctuation\">.<\/span>dp<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token function\">items<\/span><span class=\"token punctuation\">(<\/span>messages<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> message <span class=\"token operator\">-&gt;<\/span><br \/>\n                    <span class=\"token function\">MessageBubble<\/span><span class=\"token punctuation\">(<\/span>message <span class=\"token operator\">&#061;<\/span> message<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><\/p>\n<p>                <span class=\"token comment\">\/\/ \u52a0\u8f7d\u6307\u793a\u5668<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>isLoading<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    item <span class=\"token punctuation\">{<\/span><br \/>\n                        <span class=\"token function\">Row<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                            modifier <span class=\"token operator\">&#061;<\/span> Modifier<span class=\"token punctuation\">.<\/span><span class=\"token function\">fillMaxWidth<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                            horizontalArrangement <span class=\"token operator\">&#061;<\/span> Arrangement<span class=\"token punctuation\">.<\/span>Center<br \/>\n                        <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                            <span class=\"token function\">CircularProgressIndicator<\/span><span class=\"token punctuation\">(<\/span>modifier <span class=\"token operator\">&#061;<\/span> Modifier<span class=\"token punctuation\">.<\/span><span class=\"token function\">size<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">24<\/span><span class=\"token punctuation\">.<\/span>dp<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">}<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u8f93\u5165\u533a\u57df<\/span><br \/>\n            <span class=\"token function\">Row<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                modifier <span class=\"token operator\">&#061;<\/span> Modifier<br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">fillMaxWidth<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">padding<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">16<\/span><span class=\"token punctuation\">.<\/span>dp<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                verticalAlignment <span class=\"token operator\">&#061;<\/span> Alignment<span class=\"token punctuation\">.<\/span>CenterVertically<br \/>\n            <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token function\">OutlinedTextField<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    value <span class=\"token operator\">&#061;<\/span> inputText<span class=\"token punctuation\">,<\/span><br \/>\n                    onValueChange <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span> inputText <span class=\"token operator\">&#061;<\/span> it <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    modifier <span class=\"token operator\">&#061;<\/span> Modifier<span class=\"token punctuation\">.<\/span><span class=\"token function\">weight<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">1f<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    placeholder <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token function\">Text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u8f93\u5165\u6d88\u606f&#8230;&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    maxLines <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">3<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><\/p>\n<p>                <span class=\"token function\">Spacer<\/span><span class=\"token punctuation\">(<\/span>modifier <span class=\"token operator\">&#061;<\/span> Modifier<span class=\"token punctuation\">.<\/span><span class=\"token function\">width<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">8<\/span><span class=\"token punctuation\">.<\/span>dp<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>                <span class=\"token function\">Button<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    onClick <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                        viewModel<span class=\"token punctuation\">.<\/span><span class=\"token function\">sendMessage<\/span><span class=\"token punctuation\">(<\/span>inputText<span class=\"token punctuation\">)<\/span><br \/>\n                        inputText <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;&#034;<\/span><\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    enabled <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">!<\/span>isLoading <span class=\"token operator\">&amp;&amp;<\/span> inputText<span class=\"token punctuation\">.<\/span><span class=\"token function\">isNotBlank<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token function\">Text<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u53d1\u9001&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation builtin\">&#064;Composable<\/span><br \/>\n<span class=\"token keyword\">fun<\/span> <span class=\"token function\">MessageBubble<\/span><span class=\"token punctuation\">(<\/span>message<span class=\"token operator\">:<\/span> ChatMessage<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> isUser <span class=\"token operator\">&#061;<\/span> message<span class=\"token punctuation\">.<\/span>role <span class=\"token operator\">&#061;&#061;<\/span> MessageRole<span class=\"token punctuation\">.<\/span>USER<\/p>\n<p>    <span class=\"token function\">Surface<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        modifier <span class=\"token operator\">&#061;<\/span> Modifier<br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">fillMaxWidth<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">wrapContentWidth<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>isUser<span class=\"token punctuation\">)<\/span> Alignment<span class=\"token punctuation\">.<\/span>End <span class=\"token keyword\">else<\/span> Alignment<span class=\"token punctuation\">.<\/span>Start<br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        shape <span class=\"token operator\">&#061;<\/span> MaterialTheme<span class=\"token punctuation\">.<\/span>shapes<span class=\"token punctuation\">.<\/span>medium<span class=\"token punctuation\">,<\/span><br \/>\n        color <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>isUser<span class=\"token punctuation\">)<\/span><br \/>\n            MaterialTheme<span class=\"token punctuation\">.<\/span>colorScheme<span class=\"token punctuation\">.<\/span>primaryContainer<br \/>\n        <span class=\"token keyword\">else<\/span><br \/>\n            MaterialTheme<span class=\"token punctuation\">.<\/span>colorScheme<span class=\"token punctuation\">.<\/span>surfaceVariant<br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token function\">Text<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            text <span class=\"token operator\">&#061;<\/span> message<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">,<\/span><br \/>\n            modifier <span class=\"token operator\">&#061;<\/span> Modifier<span class=\"token punctuation\">.<\/span><span class=\"token function\">padding<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">12<\/span><span class=\"token punctuation\">.<\/span>dp<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            style <span class=\"token operator\">&#061;<\/span> MaterialTheme<span class=\"token punctuation\">.<\/span>typography<span class=\"token punctuation\">.<\/span>bodyLarge<br \/>\n        <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u8fd0\u884c\u9a8c\u8bc1\u6b65\u9aa4&#xff1a;<\/p>\n<li>\u5728 Android Studio \u4e2d\u9009\u62e9\u6a21\u62df\u5668\u6216\u771f\u673a<\/li>\n<li>\u70b9\u51fb Run \u6309\u94ae&#xff08;\u6216 .\/gradlew :androidApp:installDebug&#xff09;<\/li>\n<li>\u5e94\u7528\u542f\u52a8\u540e&#xff0c;\u5728\u8f93\u5165\u6846\u8f93\u5165&#034;\u4f60\u597d&#xff0c;\u4ecb\u7ecd\u4e00\u4e0b\u4f60\u81ea\u5df1&#034;<\/li>\n<li>\u89c2\u5bdf Agent \u662f\u5426\u6b63\u786e\u8fd4\u56de\u57fa\u4e8e System Prompt \u7684\u81ea\u6211\u4ecb\u7ecd<\/li>\n<hr \/>\n<h3>\u4e94\u3001\u5b9a\u4e49\u81ea\u5b9a\u4e49\u5de5\u5177\u51fd\u6570\u5e76\u5b9e\u73b0\u672c\u5730\u4e1a\u52a1\u903b\u8f91\u8c03\u7528<\/h3>\n<h4>5.1 \u5de5\u5177\u51fd\u6570\u7684\u8bbe\u8ba1\u89c4\u8303<\/h4>\n<p>\u5728 Koog \u4e2d&#xff0c;\u4e00\u4e2a\u597d\u7684\u5de5\u5177\u51fd\u6570\u5e94\u9075\u5faa\u4ee5\u4e0b\u89c4\u8303&#xff1a;<\/p>\n<table>\n<tr>\u89c4\u8303\u8bf4\u660e\u793a\u4f8b<\/tr>\n<tbody>\n<tr>\n<td>\u5355\u4e00\u804c\u8d23<\/td>\n<td>\u6bcf\u4e2a\u5de5\u5177\u53ea\u505a\u4e00\u4ef6\u4e8b<\/td>\n<td>get_weather \u53ea\u67e5\u5929\u6c14<\/td>\n<\/tr>\n<tr>\n<td>\u63cf\u8ff0\u6e05\u6670<\/td>\n<td>description \u8ba9 LLM \u77e5\u9053\u4f55\u65f6\u8c03\u7528<\/td>\n<td>\u201c\u5f53\u7528\u6237\u8be2\u95ee\u5929\u6c14\u65f6\u8c03\u7528\u201d<\/td>\n<\/tr>\n<tr>\n<td>\u53c2\u6570\u7c7b\u578b\u5b89\u5168<\/td>\n<td>\u4f7f\u7528 &#064;Serializable \u6570\u636e\u7c7b<\/td>\n<td>WeatherRequest<\/td>\n<\/tr>\n<tr>\n<td>\u9519\u8bef\u5904\u7406<\/td>\n<td>\u8fd4\u56de\u6709\u610f\u4e49\u7684\u9519\u8bef\u4fe1\u606f<\/td>\n<td>\u800c\u975e\u629b\u5f02\u5e38<\/td>\n<\/tr>\n<tr>\n<td>\u5e42\u7b49\u6027<\/td>\n<td>\u76f8\u540c\u8f93\u5165\u4ea7\u751f\u76f8\u540c\u7ed3\u679c<\/td>\n<td>\u67e5\u8be2\u7c7b\u5de5\u5177\u5929\u7136\u5e42\u7b49<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>5.2 \u5b9e\u73b0\u5929\u6c14\u67e5\u8be2\u5de5\u5177<\/h4>\n<p><span class=\"token comment\">\/\/ shared\/src\/commonMain\/kotlin\/com\/example\/koogagent\/tools\/WeatherTool.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>tools<\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span>annotation<span class=\"token punctuation\">.<\/span>Tool<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span>annotation<span class=\"token punctuation\">.<\/span>ToolParam<br \/>\n<span class=\"token keyword\">import<\/span> io<span class=\"token punctuation\">.<\/span>ktor<span class=\"token punctuation\">.<\/span>client<span class=\"token punctuation\">.<\/span><span class=\"token operator\">*<\/span><br \/>\n<span class=\"token keyword\">import<\/span> io<span class=\"token punctuation\">.<\/span>ktor<span class=\"token punctuation\">.<\/span>client<span class=\"token punctuation\">.<\/span>request<span class=\"token punctuation\">.<\/span><span class=\"token operator\">*<\/span><br \/>\n<span class=\"token keyword\">import<\/span> io<span class=\"token punctuation\">.<\/span>ktor<span class=\"token punctuation\">.<\/span>client<span class=\"token punctuation\">.<\/span>statement<span class=\"token punctuation\">.<\/span><span class=\"token operator\">*<\/span><br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>serialization<span class=\"token punctuation\">.<\/span>Serializable<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>serialization<span class=\"token punctuation\">.<\/span>json<span class=\"token punctuation\">.<\/span>Json<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u5929\u6c14\u67e5\u8be2\u5de5\u5177<br \/>\n * \u8c03\u7528\u516c\u5f00\u5929\u6c14 API \u83b7\u53d6\u5b9e\u65f6\u5929\u6c14\u6570\u636e<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> <span class=\"token function\">WeatherTool<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> httpClient<span class=\"token operator\">:<\/span> HttpClient <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">HttpClient<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> json <span class=\"token operator\">&#061;<\/span> Json <span class=\"token punctuation\">{<\/span> ignoreUnknownKeys <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ &#061;&#061;&#061; \u8bf7\u6c42\/\u54cd\u5e94\u6570\u636e\u6a21\u578b &#061;&#061;&#061;<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n    <span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">WeatherQuery<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token annotation builtin\">&#064;ToolParam<\/span><span class=\"token punctuation\">(<\/span>description <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u8981\u67e5\u8be2\u5929\u6c14\u7684\u57ce\u5e02\u540d\u79f0&#xff0c;\u4f8b\u5982&#xff1a;\u5317\u4eac\u3001\u4e0a\u6d77\u3001\u5e7f\u5dde&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> city<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><\/p>\n<p>        <span class=\"token annotation builtin\">&#064;ToolParam<\/span><span class=\"token punctuation\">(<\/span>description <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u6e29\u5ea6\u5355\u4f4d&#xff1a;celsius&#xff08;\u6444\u6c0f&#xff09;\u6216 fahrenheit&#xff08;\u534e\u6c0f&#xff09;&#xff0c;\u9ed8\u8ba4\u6444\u6c0f&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> unit<span class=\"token operator\">:<\/span> String <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;celsius&#034;<\/span><\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n    <span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">WeatherResult<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> city<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> temperature<span class=\"token operator\">:<\/span> Double<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> unit<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> condition<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> humidity<span class=\"token operator\">:<\/span> Int<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> windSpeed<span class=\"token operator\">:<\/span> Double<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> forecast<span class=\"token operator\">:<\/span> String  <span class=\"token comment\">\/\/ \u7b80\u77ed\u9884\u62a5<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n    <span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">ApiWeatherResponse<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> temp<span class=\"token operator\">:<\/span> Double<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> condition<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> humidity<span class=\"token operator\">:<\/span> Int<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> wind_speed<span class=\"token operator\">:<\/span> Double<br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ &#061;&#061;&#061; \u5de5\u5177\u51fd\u6570 &#061;&#061;&#061;<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Tool<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        name <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;query_weather&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n        description <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal multiline\"><span class=\"token string\">&#034;&#034;&#034;<br \/>\n            \u67e5\u8be2\u6307\u5b9a\u57ce\u5e02\u7684\u5f53\u524d\u5929\u6c14\u4fe1\u606f\u3002<br \/>\n            \u9002\u7528\u573a\u666f&#xff1a;\u7528\u6237\u8be2\u95ee\u67d0\u4e2a\u57ce\u5e02\u7684\u5929\u6c14\u3001\u6e29\u5ea6\u3001\u662f\u5426\u9700\u8981\u5e26\u4f1e\u7b49\u3002<br \/>\n            \u8fd4\u56de\u6e29\u5ea6\u3001\u5929\u6c14\u72b6\u51b5\u3001\u6e7f\u5ea6\u3001\u98ce\u901f\u7b49\u4fe1\u606f\u3002<br \/>\n        &#034;&#034;&#034;<\/span><\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">trimIndent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">queryWeather<\/span><span class=\"token punctuation\">(<\/span>query<span class=\"token operator\">:<\/span> WeatherQuery<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> WeatherResult <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u8c03\u7528\u5929\u6c14 API&#xff08;\u8fd9\u91cc\u7528\u6a21\u62df\u6570\u636e\u6f14\u793a&#xff09;<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u5b9e\u9645\u9879\u76ee\u4e2d\u66ff\u6362\u4e3a\u771f\u5b9e API \u8c03\u7528<\/span><br \/>\n            <span class=\"token keyword\">val<\/span> response <span class=\"token operator\">&#061;<\/span> httpClient<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;https:\/\/api.openweathermap.org\/data\/2.5\/weather&#034;<\/span><\/span><br \/>\n            <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token function\">parameter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;q&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> query<span class=\"token punctuation\">.<\/span>city<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token function\">parameter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;appid&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;YOUR_WEATHER_API_KEY&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token function\">parameter<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;units&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>query<span class=\"token punctuation\">.<\/span>unit <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;celsius&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;metric&#034;<\/span><\/span> <span class=\"token keyword\">else<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;imperial&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token keyword\">val<\/span> apiResponse <span class=\"token operator\">&#061;<\/span> json<span class=\"token punctuation\">.<\/span>decodeFromString<span class=\"token operator\">&lt;<\/span>ApiWeatherResponse<span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                response<span class=\"token punctuation\">.<\/span><span class=\"token function\">bodyAsText<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><\/p>\n<p>            <span class=\"token function\">WeatherResult<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                city <span class=\"token operator\">&#061;<\/span> query<span class=\"token punctuation\">.<\/span>city<span class=\"token punctuation\">,<\/span><br \/>\n                temperature <span class=\"token operator\">&#061;<\/span> apiResponse<span class=\"token punctuation\">.<\/span>temp<span class=\"token punctuation\">,<\/span><br \/>\n                unit <span class=\"token operator\">&#061;<\/span> query<span class=\"token punctuation\">.<\/span>unit<span class=\"token punctuation\">,<\/span><br \/>\n                condition <span class=\"token operator\">&#061;<\/span> apiResponse<span class=\"token punctuation\">.<\/span>condition<span class=\"token punctuation\">,<\/span><br \/>\n                humidity <span class=\"token operator\">&#061;<\/span> apiResponse<span class=\"token punctuation\">.<\/span>humidity<span class=\"token punctuation\">,<\/span><br \/>\n                windSpeed <span class=\"token operator\">&#061;<\/span> apiResponse<span class=\"token punctuation\">.<\/span>wind_speed<span class=\"token punctuation\">,<\/span><br \/>\n                forecast <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">generateForecast<\/span><span class=\"token punctuation\">(<\/span>apiResponse<span class=\"token punctuation\">.<\/span>condition<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span>e<span class=\"token operator\">:<\/span> Exception<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u8fd4\u56de\u53cb\u597d\u7684\u9519\u8bef\u4fe1\u606f\u800c\u975e\u629b\u5f02\u5e38<\/span><br \/>\n            <span class=\"token function\">WeatherResult<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                city <span class=\"token operator\">&#061;<\/span> query<span class=\"token punctuation\">.<\/span>city<span class=\"token punctuation\">,<\/span><br \/>\n                temperature <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">999.0<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                unit <span class=\"token operator\">&#061;<\/span> query<span class=\"token punctuation\">.<\/span>unit<span class=\"token punctuation\">,<\/span><br \/>\n                condition <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u67e5\u8be2\u5931\u8d25&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n                humidity <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                windSpeed <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0.0<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                forecast <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u62b1\u6b49&#xff0c;\u6682\u65f6\u65e0\u6cd5\u83b7\u53d6<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">query<span class=\"token punctuation\">.<\/span>city<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">\u7684\u5929\u6c14\u6570\u636e&#xff1a;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">e<span class=\"token punctuation\">.<\/span>message<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">generateForecast<\/span><span class=\"token punctuation\">(<\/span>condition<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">when<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            condition<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;rain&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u6709\u96e8&#xff0c;\u5efa\u8bae\u5e26\u4f1e&#034;<\/span><\/span><br \/>\n            condition<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;sun&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u6674\u5929&#xff0c;\u9002\u5408\u5916\u51fa&#034;<\/span><\/span><br \/>\n            condition<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;cloud&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u591a\u4e91&#xff0c;\u6c14\u6e29\u9002\u5b9c&#034;<\/span><\/span><br \/>\n            condition<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;snow&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u6709\u96ea&#xff0c;\u6ce8\u610f\u4fdd\u6696&#034;<\/span><\/span><br \/>\n            <span class=\"token keyword\">else<\/span> <span class=\"token operator\">-&gt;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u5929\u6c14\u72b6\u51b5\u4e00\u822c&#034;<\/span><\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>5.3 \u5b9e\u73b0\u672c\u5730\u6570\u636e\u5e93\u67e5\u8be2\u5de5\u5177<\/h4>\n<p><span class=\"token comment\">\/\/ shared\/src\/commonMain\/kotlin\/com\/example\/koogagent\/tools\/TodoTool.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>tools<\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span>annotation<span class=\"token punctuation\">.<\/span>Tool<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>tools<span class=\"token punctuation\">.<\/span>annotation<span class=\"token punctuation\">.<\/span>ToolParam<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>serialization<span class=\"token punctuation\">.<\/span>Serializable<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span>sync<span class=\"token punctuation\">.<\/span>Mutex<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span>sync<span class=\"token punctuation\">.<\/span>withLock<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u5f85\u529e\u4e8b\u9879\u7ba1\u7406\u5de5\u5177<br \/>\n * \u4f7f\u7528\u5185\u5b58\u5b58\u50a8&#xff08;\u5b9e\u9645\u9879\u76ee\u53ef\u66ff\u6362\u4e3a Room\/SQLDelight&#xff09;<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> TodoTool <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u7ebf\u7a0b\u5b89\u5168\u7684\u5f85\u529e\u5217\u8868<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> todos <span class=\"token operator\">&#061;<\/span> mutableListOf<span class=\"token operator\">&lt;<\/span>TodoItem<span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> mutex <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">Mutex<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">var<\/span> nextId <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">1<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n    <span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">TodoItem<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> id<span class=\"token operator\">:<\/span> Int<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> title<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> isCompleted<span class=\"token operator\">:<\/span> Boolean <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> createdAt<span class=\"token operator\">:<\/span> Long <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0L<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n    <span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">AddTodoRequest<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token annotation builtin\">&#064;ToolParam<\/span><span class=\"token punctuation\">(<\/span>description <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u5f85\u529e\u4e8b\u9879\u7684\u6807\u9898\/\u5185\u5bb9&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> title<span class=\"token operator\">:<\/span> String<br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n    <span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">ListTodoRequest<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token annotation builtin\">&#064;ToolParam<\/span><span class=\"token punctuation\">(<\/span>description <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u8fc7\u6ee4\u6761\u4ef6&#xff1a;all&#xff08;\u5168\u90e8&#xff09;\u3001pending&#xff08;\u672a\u5b8c\u6210&#xff09;\u3001completed&#xff08;\u5df2\u5b8c\u6210&#xff09;&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> filter<span class=\"token operator\">:<\/span> String <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;all&#034;<\/span><\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n    <span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">CompleteTodoRequest<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token annotation builtin\">&#064;ToolParam<\/span><span class=\"token punctuation\">(<\/span>description <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u8981\u6807\u8bb0\u5b8c\u6210\u7684\u5f85\u529e\u4e8b\u9879 ID&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> id<span class=\"token operator\">:<\/span> Int<br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n    <span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">TodoResponse<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> success<span class=\"token operator\">:<\/span> Boolean<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> message<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> items<span class=\"token operator\">:<\/span> List<span class=\"token operator\">&lt;<\/span>TodoItem<span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">emptyList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Tool<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        name <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;add_todo&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n        description <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u6dfb\u52a0\u4e00\u6761\u65b0\u7684\u5f85\u529e\u4e8b\u9879\u3002\u5f53\u7528\u6237\u8bf4\u8981\u8bb0\u4f4f\u67d0\u4e8b\u3001\u6dfb\u52a0\u4efb\u52a1\u3001\u521b\u5efa\u63d0\u9192\u65f6\u4f7f\u7528\u3002&#034;<\/span><\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">addTodo<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token operator\">:<\/span> AddTodoRequest<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> TodoResponse <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> mutex<span class=\"token punctuation\">.<\/span><span class=\"token function\">withLock<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">val<\/span> item <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">TodoItem<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                id <span class=\"token operator\">&#061;<\/span> nextId<span class=\"token operator\">&#043;&#043;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                title <span class=\"token operator\">&#061;<\/span> request<span class=\"token punctuation\">.<\/span>title<span class=\"token punctuation\">,<\/span><br \/>\n                createdAt <span class=\"token operator\">&#061;<\/span> kotlinx<span class=\"token punctuation\">.<\/span>datetime<span class=\"token punctuation\">.<\/span>Clock<span class=\"token punctuation\">.<\/span>System<span class=\"token punctuation\">.<\/span><span class=\"token function\">now<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">toEpochMilliseconds<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><br \/>\n            todos<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>item<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token function\">TodoResponse<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                success <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                message <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u5df2\u6dfb\u52a0\u5f85\u529e&#xff1a;\u300c<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">request<span class=\"token punctuation\">.<\/span>title<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">\u300d&#xff08;ID: <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">item<span class=\"token punctuation\">.<\/span>id<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#xff09;&#034;<\/span><\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Tool<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        name <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;list_todos&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n        description <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u67e5\u770b\u5f85\u529e\u4e8b\u9879\u5217\u8868\u3002\u5f53\u7528\u6237\u8be2\u95ee\u5f85\u529e\u3001\u4efb\u52a1\u5217\u8868\u3001\u8fd8\u6709\u4ec0\u4e48\u6ca1\u505a\u65f6\u4f7f\u7528\u3002&#034;<\/span><\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">listTodos<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token operator\">:<\/span> ListTodoRequest<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> TodoResponse <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> mutex<span class=\"token punctuation\">.<\/span><span class=\"token function\">withLock<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">val<\/span> filtered <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">when<\/span> <span class=\"token punctuation\">(<\/span>request<span class=\"token punctuation\">.<\/span>filter<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;pending&#034;<\/span><\/span> <span class=\"token operator\">-&gt;<\/span> todos<span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token operator\">!<\/span>it<span class=\"token punctuation\">.<\/span>isCompleted <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;completed&#034;<\/span><\/span> <span class=\"token operator\">-&gt;<\/span> todos<span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span> <span class=\"token punctuation\">{<\/span> it<span class=\"token punctuation\">.<\/span>isCompleted <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token keyword\">else<\/span> <span class=\"token operator\">-&gt;<\/span> todos<span class=\"token punctuation\">.<\/span><span class=\"token function\">toList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token function\">TodoResponse<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                success <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                message <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u5171 <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">filtered<span class=\"token punctuation\">.<\/span>size<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\"> \u6761\u5f85\u529e&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n                items <span class=\"token operator\">&#061;<\/span> filtered<br \/>\n            <span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Tool<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        name <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;complete_todo&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n        description <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u5c06\u6307\u5b9a ID \u7684\u5f85\u529e\u4e8b\u9879\u6807\u8bb0\u4e3a\u5df2\u5b8c\u6210\u3002\u5f53\u7528\u6237\u8bf4\u5b8c\u6210\u4e86\u67d0\u4e8b\u3001\u505a\u5b8c\u4e86\u67d0\u4efb\u52a1\u65f6\u4f7f\u7528\u3002&#034;<\/span><\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">completeTodo<\/span><span class=\"token punctuation\">(<\/span>request<span class=\"token operator\">:<\/span> CompleteTodoRequest<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> TodoResponse <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> mutex<span class=\"token punctuation\">.<\/span><span class=\"token function\">withLock<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">val<\/span> index <span class=\"token operator\">&#061;<\/span> todos<span class=\"token punctuation\">.<\/span><span class=\"token function\">indexOfFirst<\/span> <span class=\"token punctuation\">{<\/span> it<span class=\"token punctuation\">.<\/span>id <span class=\"token operator\">&#061;&#061;<\/span> request<span class=\"token punctuation\">.<\/span>id <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>index <span class=\"token operator\">&#061;&#061;<\/span> <span class=\"token operator\">&#8211;<\/span><span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token function\">TodoResponse<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    success <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    message <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u672a\u627e\u5230 ID \u4e3a <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">request<span class=\"token punctuation\">.<\/span>id<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\"> \u7684\u5f85\u529e\u4e8b\u9879&#034;<\/span><\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                todos<span class=\"token punctuation\">[<\/span>index<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> todos<span class=\"token punctuation\">[<\/span>index<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">copy<\/span><span class=\"token punctuation\">(<\/span>isCompleted <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token function\">TodoResponse<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    success <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    message <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u5df2\u5b8c\u6210&#xff1a;\u300c<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">todos<span class=\"token punctuation\">[<\/span>index<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">.<\/span>title<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">\u300d&#034;<\/span><\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>5.4 \u5de5\u5177\u6ce8\u518c\u4e0e Agent \u7ed1\u5b9a<\/h4>\n<p><span class=\"token comment\">\/\/ shared\/src\/commonMain\/kotlin\/com\/example\/koogagent\/AgentFactory.kt&#xff08;\u5b8c\u6574\u5de5\u5177\u6ce8\u518c&#xff09;<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u521b\u5efa\u5e26\u6709\u5168\u90e8\u4e1a\u52a1\u5de5\u5177\u7684 Agent<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">fun<\/span> <span class=\"token function\">createBusinessAgent<\/span><span class=\"token punctuation\">(<\/span>apiKey<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> AIAgent <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">val<\/span> llmClient <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">OpenAILLMClient<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        configuration <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">LLMClientConfiguration<\/span><span class=\"token punctuation\">(<\/span>apiKey <span class=\"token operator\">&#061;<\/span> apiKey<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">val<\/span> promptExecutor <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">SingleLLMPromptExecutor<\/span><span class=\"token punctuation\">(<\/span>llmClient <span class=\"token operator\">&#061;<\/span> llmClient<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u6ce8\u518c\u6240\u6709\u5de5\u5177<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> toolSet <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ToolSet<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        tools <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">listOf<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token function\">WeatherTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span>    <span class=\"token comment\">\/\/ \u5929\u6c14\u67e5\u8be2<\/span><br \/>\n            <span class=\"token function\">TodoTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span>       <span class=\"token comment\">\/\/ \u5f85\u529e\u7ba1\u7406<\/span><br \/>\n            <span class=\"token function\">CalculatorTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ \u6570\u5b66\u8ba1\u7b97<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">return<\/span> <span class=\"token function\">AIAgent<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        promptExecutor <span class=\"token operator\">&#061;<\/span> promptExecutor<span class=\"token punctuation\">,<\/span><br \/>\n        model <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>model<span class=\"token punctuation\">,<\/span><br \/>\n        systemPrompt <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>systemPrompt<span class=\"token punctuation\">,<\/span><br \/>\n        tools <span class=\"token operator\">&#061;<\/span> toolSet<span class=\"token punctuation\">,<\/span><br \/>\n        maxIterations <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>MAX_TOOL_ITERATIONS<br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>5.5 \u5de5\u5177\u8c03\u7528\u94fe\u8def\u8c03\u8bd5<\/h4>\n<p><span class=\"token comment\">\/\/ \u542f\u7528 Koog \u5185\u7f6e\u7684\u8c03\u8bd5\u65e5\u5fd7<\/span><br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>core<span class=\"token punctuation\">.<\/span>config<span class=\"token punctuation\">.<\/span>AgentDebugConfig<\/p>\n<p><span class=\"token keyword\">val<\/span> agent <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">AIAgent<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    promptExecutor <span class=\"token operator\">&#061;<\/span> promptExecutor<span class=\"token punctuation\">,<\/span><br \/>\n    model <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>model<span class=\"token punctuation\">,<\/span><br \/>\n    systemPrompt <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>systemPrompt<span class=\"token punctuation\">,<\/span><br \/>\n    tools <span class=\"token operator\">&#061;<\/span> toolSet<span class=\"token punctuation\">,<\/span><br \/>\n    debugConfig <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">AgentDebugConfig<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        logPromptSent <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>       <span class=\"token comment\">\/\/ \u8bb0\u5f55\u53d1\u9001\u7ed9 LLM \u7684\u5b8c\u6574 Prompt<\/span><br \/>\n        logToolCalls <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>        <span class=\"token comment\">\/\/ \u8bb0\u5f55\u5de5\u5177\u8c03\u7528\u8be6\u60c5<\/span><br \/>\n        logToolResults <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>      <span class=\"token comment\">\/\/ \u8bb0\u5f55\u5de5\u5177\u8fd4\u56de\u7ed3\u679c<\/span><br \/>\n        logTokenUsage <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>       <span class=\"token comment\">\/\/ \u8bb0\u5f55 Token \u6d88\u8017<\/span><br \/>\n        logLevel <span class=\"token operator\">&#061;<\/span> AgentDebugConfig<span class=\"token punctuation\">.<\/span>LogLevel<span class=\"token punctuation\">.<\/span>DEBUG<br \/>\n    <span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u8c03\u8bd5\u8f93\u51fa\u793a\u4f8b&#xff1a;<\/span><br \/>\n<span class=\"token comment\">\/\/ [Koog DEBUG] &gt;&gt;&gt; Prompt sent to LLM (tokens: 342)<\/span><br \/>\n<span class=\"token comment\">\/\/ [Koog DEBUG] &lt;&lt;&lt; LLM response: tool_call {name: &#034;query_weather&#034;, args: {&#034;city&#034;: &#034;\u5317\u4eac&#034;}}<\/span><br \/>\n<span class=\"token comment\">\/\/ [Koog DEBUG] &gt;&gt;&gt; Executing tool: query_weather<\/span><br \/>\n<span class=\"token comment\">\/\/ [Koog DEBUG] &lt;&lt;&lt; Tool result: {&#034;city&#034;: &#034;\u5317\u4eac&#034;, &#034;temperature&#034;: 28.5, &#8230;}<\/span><br \/>\n<span class=\"token comment\">\/\/ [Koog DEBUG] &gt;&gt;&gt; Sending tool result back to LLM<\/span><br \/>\n<span class=\"token comment\">\/\/ [Koog DEBUG] &lt;&lt;&lt; Final response (tokens: 89)<\/span><\/p>\n<hr \/>\n<h3>\u516d\u3001\u6784\u5efa\u591a\u8f6e\u5bf9\u8bdd\u72b6\u6001\u673a\u4e0e\u7ba1\u7406\u4e0a\u4e0b\u6587\u8bb0\u5fc6<\/h3>\n<h4>6.1 \u5bf9\u8bdd\u5386\u53f2\u7684\u6570\u636e\u6a21\u578b<\/h4>\n<p><span class=\"token comment\">\/\/ shared\/src\/commonMain\/kotlin\/com\/example\/koogagent\/memory\/ConversationManager.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>memory<\/p>\n<p><span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>serialization<span class=\"token punctuation\">.<\/span>Serializable<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u5bf9\u8bdd\u6d88\u606f\u6a21\u578b<br \/>\n *\/<\/span><br \/>\n<span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n<span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">ConversationMessage<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> role<span class=\"token operator\">:<\/span> Role<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> content<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> timestamp<span class=\"token operator\">:<\/span> Long<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> toolCallId<span class=\"token operator\">:<\/span> String<span class=\"token operator\">?<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u5de5\u5177\u8c03\u7528\u5173\u8054 ID<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> metadata<span class=\"token operator\">:<\/span> Map<span class=\"token operator\">&lt;<\/span>String<span class=\"token punctuation\">,<\/span> String<span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">emptyMap<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">enum<\/span> <span class=\"token keyword\">class<\/span> Role <span class=\"token punctuation\">{<\/span><br \/>\n        SYSTEM<span class=\"token punctuation\">,<\/span>     <span class=\"token comment\">\/\/ \u7cfb\u7edf\u63d0\u793a<\/span><br \/>\n        USER<span class=\"token punctuation\">,<\/span>       <span class=\"token comment\">\/\/ \u7528\u6237\u8f93\u5165<\/span><br \/>\n        ASSISTANT<span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ AI \u56de\u590d<\/span><br \/>\n        TOOL        <span class=\"token comment\">\/\/ \u5de5\u5177\u7ed3\u679c<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u5bf9\u8bdd\u4f1a\u8bdd<br \/>\n *\/<\/span><br \/>\n<span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n<span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">ConversationSession<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> sessionId<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> messages<span class=\"token operator\">:<\/span> MutableList<span class=\"token operator\">&lt;<\/span>ConversationMessage<span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mutableListOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> createdAt<span class=\"token operator\">:<\/span> Long<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> lastActiveAt<span class=\"token operator\">:<\/span> Long<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> totalTokensUsed<span class=\"token operator\">:<\/span> Int <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<h4>6.2 \u4e0a\u4e0b\u6587\u7a97\u53e3\u7ba1\u7406\u7b56\u7565<\/h4>\n<p><span class=\"token comment\">\/**<br \/>\n * \u4e0a\u4e0b\u6587\u7a97\u53e3\u7ba1\u7406\u5668<br \/>\n * \u8d1f\u8d23\u5728 Token \u9650\u5236\u5185\u7ef4\u62a4\u6709\u6548\u7684\u5bf9\u8bdd\u5386\u53f2<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> <span class=\"token function\">ContextWindowManager<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> maxContextTokens<span class=\"token operator\">:<\/span> Int <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">128_000<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> reservedForResponse<span class=\"token operator\">:<\/span> Int <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4_096<\/span><br \/>\n<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u7b56\u7565&#xff1a;\u6ed1\u52a8\u7a97\u53e3 &#043; \u6458\u8981\u538b\u7f29<br \/>\n     * \u5f53\u5386\u53f2\u6d88\u606f\u8d85\u8fc7\u7a97\u53e3\u5927\u5c0f\u65f6&#xff1a;<br \/>\n     * 1. \u4fdd\u7559 System Prompt&#xff08;\u59cb\u7ec8\u4fdd\u7559&#xff09;<br \/>\n     * 2. \u4fdd\u7559\u6700\u8fd1 N \u8f6e\u5b8c\u6574\u5bf9\u8bdd<br \/>\n     * 3. \u5c06\u66f4\u65e9\u7684\u5bf9\u8bdd\u538b\u7f29\u4e3a\u6458\u8981<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">manageContext<\/span><span class=\"token punctuation\">(<\/span>messages<span class=\"token operator\">:<\/span> List<span class=\"token operator\">&lt;<\/span>ConversationMessage<span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> List<span class=\"token operator\">&lt;<\/span>ConversationMessage<span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> availableTokens <span class=\"token operator\">&#061;<\/span> maxContextTokens <span class=\"token operator\">&#8211;<\/span> reservedForResponse<\/p>\n<p>        <span class=\"token comment\">\/\/ \u4f30\u7b97\u5f53\u524d token \u6570&#xff08;\u7b80\u5316&#xff1a;1 \u4e2d\u6587\u5b57 \u2248 1.5 token&#xff09;<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> currentTokens <span class=\"token operator\">&#061;<\/span> messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">sumOf<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token function\">estimateTokens<\/span><span class=\"token punctuation\">(<\/span>it<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>currentTokens <span class=\"token operator\">&lt;&#061;<\/span> availableTokens<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">return<\/span> messages  <span class=\"token comment\">\/\/ \u672a\u8d85\u9650&#xff0c;\u5168\u90e8\u4fdd\u7559<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8d85\u9650\u5904\u7406&#xff1a;\u4fdd\u7559\u6700\u8fd1 10 \u8f6e &#043; \u538b\u7f29\u65e9\u671f\u5386\u53f2<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> recentMessages <span class=\"token operator\">&#061;<\/span> messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">takeLast<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">20<\/span><span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ 10\u8f6e &#061; 20\u6761\u6d88\u606f<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> earlyMessages <span class=\"token operator\">&#061;<\/span> messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">dropLast<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">20<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u5c06\u65e9\u671f\u6d88\u606f\u538b\u7f29\u4e3a\u6458\u8981<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> summary <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">compressToSummary<\/span><span class=\"token punctuation\">(<\/span>earlyMessages<span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">listOf<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token function\">ConversationMessage<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                role <span class=\"token operator\">&#061;<\/span> ConversationMessage<span class=\"token punctuation\">.<\/span>Role<span class=\"token punctuation\">.<\/span>SYSTEM<span class=\"token punctuation\">,<\/span><br \/>\n                content <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;[\u5386\u53f2\u5bf9\u8bdd\u6458\u8981] <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$<\/span><span class=\"token expression\">summary<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n                timestamp <span class=\"token operator\">&#061;<\/span> System<span class=\"token punctuation\">.<\/span><span class=\"token function\">currentTimeMillis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#043;<\/span> recentMessages<br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">estimateTokens<\/span><span class=\"token punctuation\">(<\/span>text<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> Int <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u7b80\u5316\u7684 token \u4f30\u7b97<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">(<\/span>text<span class=\"token punctuation\">.<\/span>length <span class=\"token operator\">*<\/span> <span class=\"token number\">1.5<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toInt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">compressToSummary<\/span><span class=\"token punctuation\">(<\/span>messages<span class=\"token operator\">:<\/span> List<span class=\"token operator\">&lt;<\/span>ConversationMessage<span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5b9e\u9645\u5b9e\u73b0\u4e2d\u53ef\u4ee5\u8c03\u7528 LLM \u751f\u6210\u6458\u8981<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u8fd9\u91cc\u7b80\u5316\u4e3a\u63d0\u53d6\u5173\u952e\u4fe1\u606f<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> userMessages <span class=\"token operator\">&#061;<\/span> messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">filter<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            it<span class=\"token punctuation\">.<\/span>role <span class=\"token operator\">&#061;&#061;<\/span> ConversationMessage<span class=\"token punctuation\">.<\/span>Role<span class=\"token punctuation\">.<\/span>USER<br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> &#034;\u7528\u6237\u4e4b\u524d\u8be2\u95ee\u4e86&#xff1a;$<span class=\"token punctuation\">{<\/span>userMessages<span class=\"token punctuation\">.<\/span><span class=\"token function\">joinToString<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u3001&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            it<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">.<\/span><span class=\"token function\">take<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">50<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">}<\/span>&#034;<br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>6.3 \u6301\u4e45\u5316\u8bb0\u5fc6&#xff1a;AIAgentStorage<\/h4>\n<p><span class=\"token comment\">\/\/ shared\/src\/commonMain\/kotlin\/com\/example\/koogagent\/memory\/AgentStorage.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>memory<\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>storage<span class=\"token punctuation\">.<\/span>AIAgentStorage<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>storage<span class=\"token punctuation\">.<\/span>StorageKey<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * Agent \u6301\u4e45\u5316\u5b58\u50a8<br \/>\n * \u652f\u6301\u8de8\u4f1a\u8bdd\u8bb0\u5fc6\u4fdd\u7559<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> PersistentAgentStorage <span class=\"token operator\">:<\/span> AIAgentStorage <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u5b9e\u9645\u9879\u76ee\u4e2d\u53ef\u66ff\u6362\u4e3a SQLDelight \/ Room \/ DataStore<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> storage <span class=\"token operator\">&#061;<\/span> mutableMapOf<span class=\"token operator\">&lt;<\/span>String<span class=\"token punctuation\">,<\/span> String<span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">override<\/span> <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">save<\/span><span class=\"token punctuation\">(<\/span>key<span class=\"token operator\">:<\/span> StorageKey<span class=\"token punctuation\">,<\/span> value<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        storage<span class=\"token punctuation\">[<\/span>key<span class=\"token punctuation\">.<\/span>id<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> value<br \/>\n        <span class=\"token comment\">\/\/ \u5b9e\u9645\u5b9e\u73b0&#xff1a;\u5199\u5165\u672c\u5730\u6570\u636e\u5e93<\/span><br \/>\n        <span class=\"token comment\">\/\/ database.insertOrReplace(key.id, value, System.currentTimeMillis())<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">override<\/span> <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">load<\/span><span class=\"token punctuation\">(<\/span>key<span class=\"token operator\">:<\/span> StorageKey<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String<span class=\"token operator\">?<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> storage<span class=\"token punctuation\">[<\/span>key<span class=\"token punctuation\">.<\/span>id<span class=\"token punctuation\">]<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u5b9e\u9645\u5b9e\u73b0&#xff1a;\u4ece\u6570\u636e\u5e93\u8bfb\u53d6<\/span><br \/>\n        <span class=\"token comment\">\/\/ return database.getById(key.id)?.value<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">override<\/span> <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">delete<\/span><span class=\"token punctuation\">(<\/span>key<span class=\"token operator\">:<\/span> StorageKey<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        storage<span class=\"token punctuation\">.<\/span><span class=\"token function\">remove<\/span><span class=\"token punctuation\">(<\/span>key<span class=\"token punctuation\">.<\/span>id<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">override<\/span> <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">clear<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        storage<span class=\"token punctuation\">.<\/span><span class=\"token function\">clear<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u4f7f\u7528\u793a\u4f8b&#xff1a;\u5728 Agent \u4e2d\u542f\u7528\u6301\u4e45\u5316<\/span><br \/>\n<span class=\"token keyword\">val<\/span> agent <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">AIAgent<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    promptExecutor <span class=\"token operator\">&#061;<\/span> promptExecutor<span class=\"token punctuation\">,<\/span><br \/>\n    model <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>model<span class=\"token punctuation\">,<\/span><br \/>\n    systemPrompt <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>systemPrompt<span class=\"token punctuation\">,<\/span><br \/>\n    tools <span class=\"token operator\">&#061;<\/span> toolSet<span class=\"token punctuation\">,<\/span><br \/>\n    storage <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">PersistentAgentStorage<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ \u542f\u7528\u6301\u4e45\u5316<\/span><br \/>\n    <span class=\"token comment\">\/\/ Agent \u4f1a\u81ea\u52a8\u4fdd\u5b58\/\u6062\u590d\u5bf9\u8bdd\u72b6\u6001<\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<h4>6.4 \u5386\u53f2\u538b\u7f29&#xff1a;\u964d\u4f4e Token \u6210\u672c<\/h4>\n<p><span class=\"token comment\">\/**<br \/>\n * \u5bf9\u8bdd\u5386\u53f2\u538b\u7f29\u5668<br \/>\n * \u5f53\u5bf9\u8bdd\u8fc7\u957f\u65f6&#xff0c;\u4f7f\u7528 LLM \u81ea\u8eab\u6765\u538b\u7f29\u5386\u53f2<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> <span class=\"token function\">HistoryCompressor<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> agent<span class=\"token operator\">:<\/span> AIAgent<br \/>\n<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u538b\u7f29\u5bf9\u8bdd\u5386\u53f2\u4e3a\u7b80\u77ed\u6458\u8981<br \/>\n     * &#064;param messages \u9700\u8981\u538b\u7f29\u7684\u5386\u53f2\u6d88\u606f<br \/>\n     * &#064;param maxSummaryTokens \u6458\u8981\u6700\u5927 token \u6570<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">compress<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        messages<span class=\"token operator\">:<\/span> List<span class=\"token operator\">&lt;<\/span>ConversationMessage<span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n        maxSummaryTokens<span class=\"token operator\">:<\/span> Int <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">500<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> historyText <span class=\"token operator\">&#061;<\/span> messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">joinToString<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\\\\n&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> msg <span class=\"token operator\">-&gt;<\/span><br \/>\n            <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;[<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">msg<span class=\"token punctuation\">.<\/span>role<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">]: <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">msg<span class=\"token punctuation\">.<\/span>content<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">val<\/span> compressionPrompt <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal multiline\"><span class=\"token string\">&#034;&#034;&#034;<br \/>\n            \u8bf7\u5c06\u4ee5\u4e0b\u5bf9\u8bdd\u5386\u53f2\u538b\u7f29\u4e3a\u4e0d\u8d85\u8fc7 <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">maxSummaryTokens<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\"> token \u7684\u6458\u8981\u3002<br \/>\n            \u4fdd\u7559\u5173\u952e\u4fe1\u606f&#xff1a;\u7528\u6237\u610f\u56fe\u3001\u91cd\u8981\u51b3\u5b9a\u3001\u5f85\u5904\u7406\u4e8b\u9879\u3002<br \/>\n            \u53bb\u9664\u5bd2\u6684\u3001\u91cd\u590d\u5185\u5bb9\u3002<\/p>\n<p>            \u5bf9\u8bdd\u5386\u53f2&#xff1a;<br \/>\n            <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$<\/span><span class=\"token expression\">historyText<\/span><\/span><span class=\"token string\"><\/p>\n<p>            \u538b\u7f29\u6458\u8981&#xff1a;<br \/>\n        &#034;&#034;&#034;<\/span><\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">trimIndent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token keyword\">val<\/span> result <span class=\"token operator\">&#061;<\/span> agent<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span>compressionPrompt<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> result<span class=\"token punctuation\">.<\/span>content<br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>6.5 \u591a\u8f6e\u5bf9\u8bdd UI \u96c6\u6210<\/h4>\n<p><span class=\"token comment\">\/\/ \u5728 ViewModel \u4e2d\u96c6\u6210\u4e0a\u4e0b\u6587\u7ba1\u7406<\/span><br \/>\n<span class=\"token keyword\">class<\/span> ChatViewModel <span class=\"token operator\">:<\/span> <span class=\"token function\">ViewModel<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> contextManager <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ContextWindowManager<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> conversationHistory <span class=\"token operator\">&#061;<\/span> mutableListOf<span class=\"token operator\">&lt;<\/span>ConversationMessage<span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">sendMessage<\/span><span class=\"token punctuation\">(<\/span>userInput<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ 1. \u6dfb\u52a0\u7528\u6237\u6d88\u606f<\/span><br \/>\n        conversationHistory<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token function\">ConversationMessage<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                role <span class=\"token operator\">&#061;<\/span> ConversationMessage<span class=\"token punctuation\">.<\/span>Role<span class=\"token punctuation\">.<\/span>USER<span class=\"token punctuation\">,<\/span><br \/>\n                content <span class=\"token operator\">&#061;<\/span> userInput<span class=\"token punctuation\">,<\/span><br \/>\n                timestamp <span class=\"token operator\">&#061;<\/span> System<span class=\"token punctuation\">.<\/span><span class=\"token function\">currentTimeMillis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 2. \u7ba1\u7406\u4e0a\u4e0b\u6587\u7a97\u53e3<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> managedContext <span class=\"token operator\">&#061;<\/span> contextManager<span class=\"token punctuation\">.<\/span><span class=\"token function\">manageContext<\/span><span class=\"token punctuation\">(<\/span>conversationHistory<span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ 3. \u5e26\u4e0a\u4e0b\u6587\u8c03\u7528 Agent<\/span><br \/>\n        viewModelScope<span class=\"token punctuation\">.<\/span><span class=\"token function\">launch<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">val<\/span> response <span class=\"token operator\">&#061;<\/span> agent<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                input <span class=\"token operator\">&#061;<\/span> userInput<span class=\"token punctuation\">,<\/span><br \/>\n                conversationHistory <span class=\"token operator\">&#061;<\/span> managedContext<br \/>\n            <span class=\"token punctuation\">)<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ 4. \u4fdd\u5b58 AI \u56de\u590d\u5230\u5386\u53f2<\/span><br \/>\n            conversationHistory<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token function\">ConversationMessage<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    role <span class=\"token operator\">&#061;<\/span> ConversationMessage<span class=\"token punctuation\">.<\/span>Role<span class=\"token punctuation\">.<\/span>ASSISTANT<span class=\"token punctuation\">,<\/span><br \/>\n                    content <span class=\"token operator\">&#061;<\/span> response<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">,<\/span><br \/>\n                    timestamp <span class=\"token operator\">&#061;<\/span> System<span class=\"token punctuation\">.<\/span><span class=\"token function\">currentTimeMillis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ 5. \u66f4\u65b0 UI<\/span><br \/>\n            _messages<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> conversationHistory<span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span> <span class=\"token punctuation\">{<\/span> it<span class=\"token punctuation\">.<\/span><span class=\"token function\">toUiMessage<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<hr \/>\n<h3>\u4e03\u3001\u8de8\u5e73\u53f0\u8fd0\u884c\u9a8c\u8bc1&#xff1a;iOS \u4e0e Desktop \u7aef\u7684\u65e0\u7f1d\u8fc1\u79fb<\/h3>\n<h4>7.1 iOS \u7aef\u96c6\u6210&#xff1a;Framework \u5bfc\u51fa\u4e0e SwiftUI \u6865\u63a5<\/h4>\n<p>\u6b65\u9aa4\u4e00&#xff1a;\u914d\u7f6e Kotlin\/Native Framework \u5bfc\u51fa<\/p>\n<p><span class=\"token comment\">\/\/ shared\/build.gradle.kts \u4e2d\u6dfb\u52a0 iOS framework \u914d\u7f6e<\/span><br \/>\nkotlin <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ &#8230; \u5df2\u6709\u7684 target \u914d\u7f6e &#8230;<\/span><\/p>\n<p>    <span class=\"token comment\">\/\/ \u914d\u7f6e iOS Framework \u5bfc\u51fa<\/span><br \/>\n    <span class=\"token function\">listOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">iosX64<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function\">iosArm64<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function\">iosSimulatorArm64<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">forEach<\/span> <span class=\"token punctuation\">{<\/span> target <span class=\"token operator\">-&gt;<\/span><br \/>\n        target<span class=\"token punctuation\">.<\/span>binaries<span class=\"token punctuation\">.<\/span><span class=\"token function\">framework<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            baseName <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;SharedKoogAgent&#034;<\/span><\/span><br \/>\n            isStatic <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span>  <span class=\"token comment\">\/\/ \u9759\u6001\u94fe\u63a5&#xff0c;\u7b80\u5316\u96c6\u6210<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u5bfc\u51fa Koog \u76f8\u5173\u4f9d\u8d56<\/span><br \/>\n            <span class=\"token function\">export<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;ai.koog:koog-agents-core:0.7.2&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token function\">export<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;ai.koog:koog-agents-tools:0.7.2&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u6b65\u9aa4\u4e8c&#xff1a;\u521b\u5efa iOS \u6865\u63a5\u5c42<\/p>\n<p><span class=\"token comment\">\/\/ shared\/src\/iosMain\/kotlin\/com\/example\/koogagent\/IOSAgentBridge.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<\/p>\n<p><span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span><span class=\"token operator\">*<\/span><br \/>\n<span class=\"token keyword\">import<\/span> platform<span class=\"token punctuation\">.<\/span>Foundation<span class=\"token punctuation\">.<\/span>NSBundle<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * iOS \u5e73\u53f0\u6865\u63a5\u7c7b<br \/>\n * \u5c06 Kotlin Agent \u66b4\u9732\u4e3a Objective-C\/Swift \u53cb\u597d\u7684 API<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> IOSAgentBridge <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> scope <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">CoroutineScope<\/span><span class=\"token punctuation\">(<\/span>Dispatchers<span class=\"token punctuation\">.<\/span>Default <span class=\"token operator\">&#043;<\/span> <span class=\"token function\">SupervisorJob<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">var<\/span> agent<span class=\"token operator\">:<\/span> AIAgent<span class=\"token operator\">?<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">null<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u521d\u59cb\u5316 Agent&#xff08;\u4ece Swift \u8c03\u7528&#xff09;<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">initializeAgent<\/span><span class=\"token punctuation\">(<\/span>apiKey<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        agent <span class=\"token operator\">&#061;<\/span> AgentFactory<span class=\"token punctuation\">.<\/span><span class=\"token function\">createFullAgent<\/span><span class=\"token punctuation\">(<\/span>apiKey<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u53d1\u9001\u6d88\u606f&#xff08;\u5f02\u6b65\u56de\u8c03\u65b9\u5f0f&#xff0c;\u5bf9 Swift \u53cb\u597d&#xff09;<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">sendMessage<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        message<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n        onSuccess<span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span>String<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> Unit<span class=\"token punctuation\">,<\/span><br \/>\n        onError<span class=\"token operator\">:<\/span> <span class=\"token punctuation\">(<\/span>String<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> Unit<br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        scope<span class=\"token punctuation\">.<\/span><span class=\"token function\">launch<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">val<\/span> response <span class=\"token operator\">&#061;<\/span> agent<span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span>message<span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token function\">withContext<\/span><span class=\"token punctuation\">(<\/span>Dispatchers<span class=\"token punctuation\">.<\/span>Main<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token function\">onSuccess<\/span><span class=\"token punctuation\">(<\/span>response<span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span>content <span class=\"token operator\">?:<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u65e0\u54cd\u5e94&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span>e<span class=\"token operator\">:<\/span> Exception<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token function\">withContext<\/span><span class=\"token punctuation\">(<\/span>Dispatchers<span class=\"token punctuation\">.<\/span>Main<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token function\">onError<\/span><span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">.<\/span>message <span class=\"token operator\">?:<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u672a\u77e5\u9519\u8bef&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u9500\u6bc1 Agent&#xff0c;\u91ca\u653e\u8d44\u6e90<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">destroy<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        scope<span class=\"token punctuation\">.<\/span><span class=\"token function\">cancel<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        agent <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">null<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ iOS \u5e73\u53f0\u83b7\u53d6 API Key<\/span><br \/>\n<span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">getApiKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> NSBundle<span class=\"token punctuation\">.<\/span>mainBundle<span class=\"token punctuation\">.<\/span>infoDictionary<br \/>\n        <span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;LLM_API_KEY&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span><span class=\"token operator\">?<\/span> String<br \/>\n        <span class=\"token operator\">?:<\/span> <span class=\"token keyword\">throw<\/span> <span class=\"token function\">IllegalStateException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;LLM_API_KEY not configured in Info.plist&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u6b65\u9aa4\u4e09&#xff1a;SwiftUI \u96c6\u6210<\/p>\n<p><span class=\"token comment\">\/\/ iosApp\/ContentView.swift<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token class-name\">SwiftUI<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token class-name\">SharedKoogAgent<\/span>  <span class=\"token comment\">\/\/ \u5bfc\u5165 Kotlin Framework<\/span><\/p>\n<p><span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">ContentView<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">View<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token attribute atrule\">&#064;StateObject<\/span> <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">var<\/span> chatVM <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">ChatViewModel<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">var<\/span> body<span class=\"token punctuation\">:<\/span> <span class=\"token keyword\">some<\/span> <span class=\"token class-name\">View<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token class-name\">VStack<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u6d88\u606f\u5217\u8868<\/span><br \/>\n            <span class=\"token class-name\">ScrollView<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">LazyVStack<\/span><span class=\"token punctuation\">(<\/span>alignment<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">.<\/span>leading<span class=\"token punctuation\">,<\/span> spacing<span class=\"token punctuation\">:<\/span> <span class=\"token number\">12<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token class-name\">ForEach<\/span><span class=\"token punctuation\">(<\/span>chatVM<span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> msg <span class=\"token keyword\">in<\/span><br \/>\n                        <span class=\"token class-name\">MessageBubbleView<\/span><span class=\"token punctuation\">(<\/span>message<span class=\"token punctuation\">:<\/span> msg<span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">padding<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><\/p>\n<p>            <span class=\"token comment\">\/\/ \u8f93\u5165\u680f<\/span><br \/>\n            <span class=\"token class-name\">HStack<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token class-name\">TextField<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal\"><span class=\"token string\">&#034;\u8f93\u5165\u6d88\u606f&#8230;&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> text<span class=\"token punctuation\">:<\/span> $chatVM<span class=\"token punctuation\">.<\/span>inputText<span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">textFieldStyle<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">.<\/span>roundedBorder<span class=\"token punctuation\">)<\/span><\/p>\n<p>                <span class=\"token class-name\">Button<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal\"><span class=\"token string\">&#034;\u53d1\u9001&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    chatVM<span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n                <span class=\"token punctuation\">.<\/span><span class=\"token function\">disabled<\/span><span class=\"token punctuation\">(<\/span>chatVM<span class=\"token punctuation\">.<\/span>isLoading<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">padding<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ ViewModel&#xff1a;\u6865\u63a5 Kotlin Agent<\/span><br \/>\n<span class=\"token keyword\">class<\/span> <span class=\"token class-name\">ChatViewModel<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">ObservableObject<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token attribute atrule\">&#064;Published<\/span> <span class=\"token keyword\">var<\/span> messages<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token class-name\">ChatMessageUI<\/span><span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><br \/>\n    <span class=\"token attribute atrule\">&#064;Published<\/span> <span class=\"token keyword\">var<\/span> inputText <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal\"><span class=\"token string\">&#034;&#034;<\/span><\/span><br \/>\n    <span class=\"token attribute atrule\">&#064;Published<\/span> <span class=\"token keyword\">var<\/span> isLoading <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">let<\/span> bridge <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">IOSAgentBridge<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token keyword\">init<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u521d\u59cb\u5316 Agent<\/span><br \/>\n        <span class=\"token keyword\">let<\/span> apiKey <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">Bundle<\/span><span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">.<\/span>infoDictionary<span class=\"token operator\">?<\/span><span class=\"token punctuation\">[<\/span><span class=\"token string-literal\"><span class=\"token string\">&#034;LLM_API_KEY&#034;<\/span><\/span><span class=\"token punctuation\">]<\/span> <span class=\"token keyword\">as<\/span><span class=\"token operator\">?<\/span> <span class=\"token class-name\">String<\/span> <span class=\"token operator\">??<\/span> <span class=\"token string-literal\"><span class=\"token string\">&#034;&#034;<\/span><\/span><br \/>\n        bridge<span class=\"token punctuation\">.<\/span><span class=\"token function\">initializeAgent<\/span><span class=\"token punctuation\">(<\/span>apiKey<span class=\"token punctuation\">:<\/span> apiKey<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">func<\/span> <span class=\"token function-definition function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">guard<\/span> <span class=\"token operator\">!<\/span>inputText<span class=\"token punctuation\">.<\/span>isEmpty <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> userMsg <span class=\"token operator\">&#061;<\/span> <span class=\"token class-name\">ChatMessageUI<\/span><span class=\"token punctuation\">(<\/span>role<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">.<\/span>user<span class=\"token punctuation\">,<\/span> content<span class=\"token punctuation\">:<\/span> inputText<span class=\"token punctuation\">)<\/span><br \/>\n        messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">append<\/span><span class=\"token punctuation\">(<\/span>userMsg<span class=\"token punctuation\">)<\/span><br \/>\n        isLoading <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><\/p>\n<p>        <span class=\"token keyword\">let<\/span> text <span class=\"token operator\">&#061;<\/span> inputText<br \/>\n        inputText <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal\"><span class=\"token string\">&#034;&#034;<\/span><\/span><\/p>\n<p>        bridge<span class=\"token punctuation\">.<\/span><span class=\"token function\">sendMessage<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            message<span class=\"token punctuation\">:<\/span> text<span class=\"token punctuation\">,<\/span><br \/>\n            onSuccess<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token keyword\">weak<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">]<\/span> response <span class=\"token keyword\">in<\/span><br \/>\n                <span class=\"token class-name\">DispatchQueue<\/span><span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">.<\/span><span class=\"token keyword\">async<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">self<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">append<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        <span class=\"token class-name\">ChatMessageUI<\/span><span class=\"token punctuation\">(<\/span>role<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">.<\/span>assistant<span class=\"token punctuation\">,<\/span> content<span class=\"token punctuation\">:<\/span> response<span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token keyword\">self<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span>isLoading <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            onError<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token keyword\">weak<\/span> <span class=\"token keyword\">self<\/span><span class=\"token punctuation\">]<\/span> error <span class=\"token keyword\">in<\/span><br \/>\n                <span class=\"token class-name\">DispatchQueue<\/span><span class=\"token punctuation\">.<\/span>main<span class=\"token punctuation\">.<\/span><span class=\"token keyword\">async<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">self<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span>messages<span class=\"token punctuation\">.<\/span><span class=\"token function\">append<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        <span class=\"token class-name\">ChatMessageUI<\/span><span class=\"token punctuation\">(<\/span>role<span class=\"token punctuation\">:<\/span> <span class=\"token punctuation\">.<\/span>assistant<span class=\"token punctuation\">,<\/span> content<span class=\"token punctuation\">:<\/span> <span class=\"token string-literal\"><span class=\"token string\">&#034;\u9519\u8bef: $error)&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token keyword\">self<\/span><span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span>isLoading <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">struct<\/span> <span class=\"token class-name\">ChatMessageUI<\/span><span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Identifiable<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">let<\/span> id <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">UUID<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">let<\/span> role<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">Role<\/span><br \/>\n    <span class=\"token keyword\">let<\/span> content<span class=\"token punctuation\">:<\/span> <span class=\"token class-name\">String<\/span><\/p>\n<p>    <span class=\"token keyword\">enum<\/span> <span class=\"token class-name\">Role<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token keyword\">case<\/span> user<span class=\"token punctuation\">,<\/span> assistant <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>7.2 Desktop \u7aef\u96c6\u6210&#xff1a;Compose Desktop \u5e94\u7528<\/h4>\n<p><span class=\"token comment\">\/\/ desktopApp\/src\/main\/kotlin\/Main.kt<\/span><br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>desktop<span class=\"token punctuation\">.<\/span>ui<span class=\"token punctuation\">.<\/span>tooling<span class=\"token punctuation\">.<\/span>preview<span class=\"token punctuation\">.<\/span>Preview<br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>material3<span class=\"token punctuation\">.<\/span>MaterialTheme<br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>runtime<span class=\"token punctuation\">.<\/span><span class=\"token operator\">*<\/span><br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>ui<span class=\"token punctuation\">.<\/span>window<span class=\"token punctuation\">.<\/span>Window<br \/>\n<span class=\"token keyword\">import<\/span> androidx<span class=\"token punctuation\">.<\/span>compose<span class=\"token punctuation\">.<\/span>ui<span class=\"token punctuation\">.<\/span>window<span class=\"token punctuation\">.<\/span>application<br \/>\n<span class=\"token keyword\">import<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>AgentFactory<br \/>\n<span class=\"token keyword\">import<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>getApiKey<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span>launch<\/p>\n<p><span class=\"token keyword\">fun<\/span> <span class=\"token function\">main<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> application <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function\">Window<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        onCloseRequest <span class=\"token operator\">&#061;<\/span> <span class=\"token operator\">::<\/span>exitApplication<span class=\"token punctuation\">,<\/span><br \/>\n        title <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;Koog AI Agent &#8211; Desktop&#034;<\/span><\/span><br \/>\n    <span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        MaterialTheme <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token function\">DesktopChatApp<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation builtin\">&#064;Composable<\/span><br \/>\n<span class=\"token keyword\">fun<\/span> <span class=\"token function\">DesktopChatApp<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ Desktop \u7aef\u4e0e Android \u7aef\u5171\u4eab\u5b8c\u5168\u76f8\u540c\u7684 Agent \u903b\u8f91<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u53ea\u6709 UI \u5e03\u5c40\u53ef\u80fd\u7565\u6709\u4e0d\u540c<\/span><br \/>\n    <span class=\"token function\">SharedChatScreen<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ \u5f15\u7528 shared \u6a21\u5757\u4e2d\u7684\u901a\u7528 UI<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>7.3 \u5e73\u53f0\u5dee\u5f02\u5904\u7406&#xff1a;expect\/actual \u6a21\u5f0f<\/h4>\n<p><span class=\"token comment\">\/\/ &#061;&#061;&#061; commonMain &#061;&#061;&#061;<\/span><br \/>\n<span class=\"token comment\">\/\/ shared\/src\/commonMain\/kotlin\/com\/example\/koogagent\/platform\/Platform.kt<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u5e73\u53f0\u62bd\u8c61&#xff1a;\u5904\u7406\u5404\u5e73\u53f0\u5dee\u5f02<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">expect<\/span> <span class=\"token keyword\">object<\/span> Platform <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/** \u5e73\u53f0\u540d\u79f0 *\/<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> name<span class=\"token operator\">:<\/span> String<\/p>\n<p>    <span class=\"token comment\">\/** \u83b7\u53d6\u5b89\u5168\u5b58\u50a8\u7684 API Key *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">getSecureApiKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String<\/p>\n<p>    <span class=\"token comment\">\/** \u83b7\u53d6\u7f51\u7edc\u5f15\u64ce *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">createHttpClient<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> HttpClient<\/p>\n<p>    <span class=\"token comment\">\/** \u65e5\u5fd7\u8f93\u51fa *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span>tag<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span> message<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ &#061;&#061;&#061; androidMain &#061;&#061;&#061;<\/span><br \/>\n<span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">object<\/span> Platform <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">val<\/span> name <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;Android <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">Build<span class=\"token punctuation\">.<\/span>VERSION<span class=\"token punctuation\">.<\/span>SDK_INT<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><\/p>\n<p>    <span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">getSecureApiKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u4f7f\u7528 Android Keystore \u6216 BuildConfig<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> BuildConfig<span class=\"token punctuation\">.<\/span>OPENAI_API_KEY<br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">createHttpClient<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> HttpClient <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token function\">HttpClient<\/span><span class=\"token punctuation\">(<\/span>OkHttp<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token function\">install<\/span><span class=\"token punctuation\">(<\/span>ContentNegotiation<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span>tag<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span> message<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        android<span class=\"token punctuation\">.<\/span>util<span class=\"token punctuation\">.<\/span>Log<span class=\"token punctuation\">.<\/span><span class=\"token function\">d<\/span><span class=\"token punctuation\">(<\/span>tag<span class=\"token punctuation\">,<\/span> message<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ &#061;&#061;&#061; iosMain &#061;&#061;&#061;<\/span><br \/>\n<span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">object<\/span> Platform <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">val<\/span> name <span class=\"token operator\">&#061;<\/span> UIDevice<span class=\"token punctuation\">.<\/span>currentDevice<span class=\"token punctuation\">.<\/span>systemName <span class=\"token operator\">&#043;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034; &#034;<\/span><\/span> <span class=\"token operator\">&#043;<\/span><br \/>\n                      UIDevice<span class=\"token punctuation\">.<\/span>currentDevice<span class=\"token punctuation\">.<\/span>systemVersion<\/p>\n<p>    <span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">getSecureApiKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> NSBundle<span class=\"token punctuation\">.<\/span>mainBundle<span class=\"token punctuation\">.<\/span>infoDictionary<br \/>\n            <span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;LLM_API_KEY&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">as<\/span><span class=\"token operator\">?<\/span> String <span class=\"token operator\">?:<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;&#034;<\/span><\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">createHttpClient<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> HttpClient <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token function\">HttpClient<\/span><span class=\"token punctuation\">(<\/span>Darwin<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token function\">install<\/span><span class=\"token punctuation\">(<\/span>ContentNegotiation<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span>tag<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span> message<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token function\">println<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;[<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$<\/span><span class=\"token expression\">tag<\/span><\/span><span class=\"token string\">] <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$<\/span><span class=\"token expression\">message<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ &#061;&#061;&#061; desktopMain &#061;&#061;&#061;<\/span><br \/>\n<span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">object<\/span> Platform <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">val<\/span> name <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;Desktop (<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">System<span class=\"token punctuation\">.<\/span><span class=\"token function\">getProperty<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;os.name&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">)&#034;<\/span><\/span><\/p>\n<p>    <span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">getSecureApiKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> System<span class=\"token punctuation\">.<\/span><span class=\"token function\">getenv<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;OPENAI_API_KEY&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">?:<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;&#034;<\/span><\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">createHttpClient<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> HttpClient <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token function\">HttpClient<\/span><span class=\"token punctuation\">(<\/span>CIO<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token function\">install<\/span><span class=\"token punctuation\">(<\/span>ContentNegotiation<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token keyword\">actual<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span>tag<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span> message<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token function\">println<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;[<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$<\/span><span class=\"token expression\">tag<\/span><\/span><span class=\"token string\">] <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$<\/span><span class=\"token expression\">message<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>7.4 \u4e09\u7aef\u7edf\u4e00\u6d4b\u8bd5\u9a8c\u8bc1<\/h4>\n<p><span class=\"token comment\">\/\/ shared\/src\/commonTest\/kotlin\/com\/example\/koogagent\/AgentIntegrationTest.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<\/p>\n<p><span class=\"token keyword\">import<\/span> kotlin<span class=\"token punctuation\">.<\/span>test<span class=\"token punctuation\">.<\/span>Test<br \/>\n<span class=\"token keyword\">import<\/span> kotlin<span class=\"token punctuation\">.<\/span>test<span class=\"token punctuation\">.<\/span>assertNotNull<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span>test<span class=\"token punctuation\">.<\/span>runTest<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u8de8\u5e73\u53f0\u96c6\u6210\u6d4b\u8bd5<br \/>\n * \u6b64\u6d4b\u8bd5\u4f1a\u5728\u6240\u6709\u76ee\u6807\u5e73\u53f0\u4e0a\u8fd0\u884c<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> AgentIntegrationTest <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Test<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">testAgentCreation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> runTest <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u9a8c\u8bc1 Agent \u53ef\u4ee5\u6b63\u5e38\u521b\u5efa<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> agent <span class=\"token operator\">&#061;<\/span> AgentFactory<span class=\"token punctuation\">.<\/span><span class=\"token function\">createBasicAgent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;test-api-key&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token function\">assertNotNull<\/span><span class=\"token punctuation\">(<\/span>agent<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Test<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">testToolRegistration<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> runTest <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u9a8c\u8bc1\u5de5\u5177\u6ce8\u518c\u6b63\u786e<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> agent <span class=\"token operator\">&#061;<\/span> AgentFactory<span class=\"token punctuation\">.<\/span><span class=\"token function\">createFullAgent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;test-api-key&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token function\">assertNotNull<\/span><span class=\"token punctuation\">(<\/span>agent<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u9a8c\u8bc1\u5de5\u5177\u6570\u91cf<\/span><br \/>\n        <span class=\"token comment\">\/\/ assertEquals(3, agent.tools.size)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token annotation builtin\">&#064;Test<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">testContextManagement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;<\/span> runTest <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u9a8c\u8bc1\u4e0a\u4e0b\u6587\u7ba1\u7406\u5668<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> manager <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ContextWindowManager<\/span><span class=\"token punctuation\">(<\/span>maxContextTokens <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">1000<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> messages <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token number\">1<\/span><span class=\"token operator\">..<\/span><span class=\"token number\">100<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span> <span class=\"token punctuation\">{<\/span> i <span class=\"token operator\">-&gt;<\/span><br \/>\n            <span class=\"token function\">ConversationMessage<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                role <span class=\"token operator\">&#061;<\/span> ConversationMessage<span class=\"token punctuation\">.<\/span>Role<span class=\"token punctuation\">.<\/span>USER<span class=\"token punctuation\">,<\/span><br \/>\n                content <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u6d88\u606f <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$<\/span><span class=\"token expression\">i<\/span><\/span><span class=\"token string\">&#xff1a;\u8fd9\u662f\u4e00\u6bb5\u6d4b\u8bd5\u6587\u672c&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n                timestamp <span class=\"token operator\">&#061;<\/span> System<span class=\"token punctuation\">.<\/span><span class=\"token function\">currentTimeMillis<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">val<\/span> managed <span class=\"token operator\">&#061;<\/span> manager<span class=\"token punctuation\">.<\/span><span class=\"token function\">manageContext<\/span><span class=\"token punctuation\">(<\/span>messages<span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u9a8c\u8bc1\u538b\u7f29\u540e\u6d88\u606f\u6570\u91cf\u51cf\u5c11<\/span><br \/>\n        <span class=\"token function\">assert<\/span><span class=\"token punctuation\">(<\/span>managed<span class=\"token punctuation\">.<\/span>size <span class=\"token operator\">&lt;<\/span> messages<span class=\"token punctuation\">.<\/span>size<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u8fd0\u884c\u6d4b\u8bd5&#xff1a;<\/p>\n<p><span class=\"token comment\"># \u8fd0\u884c\u6240\u6709\u5e73\u53f0\u7684\u6d4b\u8bd5<\/span><br \/>\n.\/gradlew :shared:allTests<\/p>\n<p><span class=\"token comment\"># \u53ea\u8fd0\u884c Desktop (JVM) \u6d4b\u8bd5<\/span><br \/>\n.\/gradlew :shared:desktopTest<\/p>\n<p><span class=\"token comment\"># \u53ea\u8fd0\u884c Android \u6d4b\u8bd5<\/span><br \/>\n.\/gradlew :shared:testDebugUnitTest<\/p>\n<p><span class=\"token comment\"># \u8fd0\u884c iOS \u6d4b\u8bd5&#xff08;\u9700\u8981 macOS &#043; Xcode&#xff09;<\/span><br \/>\n.\/gradlew :shared:iosSimulatorArm64Test<\/p>\n<hr \/>\n<h3>\u516b\u3001\u5e38\u89c1\u7f16\u8bd1\u62a5\u9519\u6392\u67e5\u4e0e\u4f9d\u8d56\u51b2\u7a81\u89e3\u51b3\u65b9\u6848<\/h3>\n<h4>8.1 Kotlin\/Native \u7f16\u8bd1\u9519\u8bef<\/h4>\n<p>\u9519\u8bef 1&#xff1a;Unresolved reference: ai.koog<\/p>\n<p>e: file.kt: (3, 20): Unresolved reference: ai<\/p>\n<p>\u539f\u56e0&#xff1a;iOS target \u672a\u6b63\u786e\u914d\u7f6e Koog \u4f9d\u8d56\u3002<\/p>\n<p>\u89e3\u51b3\u65b9\u6848&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ \u786e\u4fdd iosMain \u7684 dependencies \u4e2d\u5305\u542b Koog<\/span><br \/>\n<span class=\"token keyword\">val<\/span> iosMain <span class=\"token keyword\">by<\/span> creating <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function\">dependsOn<\/span><span class=\"token punctuation\">(<\/span>commonMain<span class=\"token punctuation\">)<\/span><br \/>\n    dependencies <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ Koog \u4f9d\u8d56\u5728 commonMain \u4e2d\u58f0\u660e\u5373\u53ef<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u4f46\u9700\u8981\u786e\u4fdd Ktor \u5f15\u64ce\u6b63\u786e<\/span><br \/>\n        <span class=\"token function\">implementation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;io.ktor:ktor-client-darwin:3.1.0&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u9519\u8bef 2&#xff1a;Cannot find &#039;libkoog&#039; in framework<\/p>\n<p>ld: library not found for -lkoog<\/p>\n<p>\u89e3\u51b3\u65b9\u6848&#xff1a;\u6e05\u7406\u6784\u5efa\u7f13\u5b58\u91cd\u65b0\u7f16\u8bd1&#xff1a;<\/p>\n<p>.\/gradlew clean<br \/>\n.\/gradlew :shared:compileKotlinIosArm64<br \/>\n<span class=\"token comment\"># \u5982\u679c\u4ecd\u7136\u5931\u8d25&#xff0c;\u5220\u9664 .gradle \u548c build \u76ee\u5f55<\/span><br \/>\n<span class=\"token function\">rm<\/span> <span class=\"token parameter variable\">-rf<\/span> .gradle build shared\/build<br \/>\n.\/gradlew :shared:compileKotlinIosArm64<\/p>\n<h4>8.2 \u4f9d\u8d56\u7248\u672c\u51b2\u7a81<\/h4>\n<p>\u9519\u8bef 3&#xff1a;Conflict found for kotlinx-coroutines-core<\/p>\n<p>&gt; Conflict found for org.jetbrains.kotlinx:kotlinx-coroutines-core:<br \/>\n  &#8211; version 1.8.1 required by project :shared<br \/>\n  &#8211; version 1.9.0 required by ai.koog:koog-agents-core:0.7.2<\/p>\n<p>\u89e3\u51b3\u65b9\u6848&#xff1a;\u5728\u6839 build.gradle.kts \u4e2d\u5f3a\u5236\u7edf\u4e00\u7248\u672c&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ build.gradle.kts (root)<\/span><br \/>\nsubprojects <span class=\"token punctuation\">{<\/span><br \/>\n    configurations<span class=\"token punctuation\">.<\/span><span class=\"token function\">all<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        resolutionStrategy <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u5f3a\u5236\u4f7f\u7528\u9ad8\u7248\u672c<\/span><br \/>\n            <span class=\"token function\">force<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token function\">force<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token function\">force<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;io.ktor:ktor-client-core:3.1.0&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u6216\u8005\u4f7f\u7528 Version Catalog&#xff08;\u63a8\u8350&#xff09;&#xff1a;<\/p>\n<p># gradle\/libs.versions.toml<br \/>\n[versions]<br \/>\nkotlin &#061; &#034;2.2.20&#034;<br \/>\ncoroutines &#061; &#034;1.9.0&#034;<br \/>\nserialization &#061; &#034;1.7.3&#034;<br \/>\nktor &#061; &#034;3.1.0&#034;<br \/>\nkoog &#061; &#034;0.7.2&#034;<\/p>\n<p>[libraries]<br \/>\nkoog-core &#061; { module &#061; &#034;ai.koog:koog-agents-core&#034;, version.ref &#061; &#034;koog&#034; }<br \/>\nkoog-tools &#061; { module &#061; &#034;ai.koog:koog-agents-tools&#034;, version.ref &#061; &#034;koog&#034; }<br \/>\nkoog-executor &#061; { module &#061; &#034;ai.koog:koog-prompt-executor&#034;, version.ref &#061; &#034;koog&#034; }<br \/>\nkoog-openai &#061; { module &#061; &#034;ai.koog:koog-llm-client-openai&#034;, version.ref &#061; &#034;koog&#034; }<br \/>\ncoroutines-core &#061; { module &#061; &#034;org.jetbrains.kotlinx:kotlinx-coroutines-core&#034;, version.ref &#061; &#034;coroutines&#034; }<br \/>\nserialization-json &#061; { module &#061; &#034;org.jetbrains.kotlinx:kotlinx-serialization-json&#034;, version.ref &#061; &#034;serialization&#034; }<br \/>\nktor-core &#061; { module &#061; &#034;io.ktor:ktor-client-core&#034;, version.ref &#061; &#034;ktor&#034; }<\/p>\n<h4>8.3 Ktor \u5f15\u64ce\u51b2\u7a81<\/h4>\n<p>\u9519\u8bef 4&#xff1a;No Http client engine found<\/p>\n<p>io.ktor.client.engine.HttpClientEngineNotFoundException:<br \/>\nNo Http client engine found. Please add engine dependency.<\/p>\n<p>\u539f\u56e0&#xff1a;commonMain \u4e2d\u4f7f\u7528\u4e86 HttpClient \u4f46\u672a\u5728\u5e73\u53f0\u6a21\u5757\u4e2d\u6dfb\u52a0\u5f15\u64ce\u3002<\/p>\n<p>\u89e3\u51b3\u65b9\u6848&#xff1a;\u786e\u4fdd\u6bcf\u4e2a\u5e73\u53f0\u6a21\u5757\u90fd\u6709\u5bf9\u5e94\u5f15\u64ce&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ androidMain \u2192 ktor-client-okhttp<\/span><br \/>\n<span class=\"token comment\">\/\/ iosMain \u2192 ktor-client-darwin  <\/span><br \/>\n<span class=\"token comment\">\/\/ desktopMain (jvm) \u2192 ktor-client-cio \u6216 ktor-client-java<\/span><\/p>\n<h4>8.4 \u5e8f\u5217\u5316\u4e0e\u53cd\u5c04\u95ee\u9898<\/h4>\n<p>\u9519\u8bef 5&#xff1a;Serializer for class &#039;XXX&#039; is not found<\/p>\n<p>kotlinx.serialization.SerializationException:<br \/>\nSerializer for class &#039;WeatherRequest&#039; is not found.<\/p>\n<p>\u539f\u56e0&#xff1a;\u6570\u636e\u7c7b\u7f3a\u5c11 &#064;Serializable \u6ce8\u89e3\u6216\u5e8f\u5217\u5316\u63d2\u4ef6\u672a\u5e94\u7528\u3002<\/p>\n<p>\u89e3\u51b3\u65b9\u6848&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ 1. \u786e\u4fdd build.gradle.kts \u4e2d\u5e94\u7528\u4e86\u5e8f\u5217\u5316\u63d2\u4ef6<\/span><br \/>\nplugins <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function\">kotlin<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;plugin.serialization&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> version <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;2.2.20&#034;<\/span><\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ 2. \u6240\u6709\u9700\u8981\u5e8f\u5217\u5316\u7684\u7c7b\u90fd\u52a0 &#064;Serializable<\/span><br \/>\n<span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n<span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">WeatherRequest<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> city<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> date<span class=\"token operator\">:<\/span> String <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;&#034;<\/span><\/span><br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<h4>8.5 \u5185\u5b58\u4e0e GC \u76f8\u5173\u95ee\u9898<\/h4>\n<p>\u9519\u8bef 6&#xff1a;iOS \u7aef OutOfMemoryError<\/p>\n<p>Kotlin\/Native \u7684\u5185\u5b58\u6a21\u578b\u4e0e JVM \u4e0d\u540c&#xff0c;\u957f\u5bf9\u8bdd\u53ef\u80fd\u5bfc\u81f4\u5185\u5b58\u538b\u529b\u3002<\/p>\n<p>\u89e3\u51b3\u65b9\u6848&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ \u9650\u5236\u5bf9\u8bdd\u5386\u53f2\u957f\u5ea6<\/span><br \/>\n<span class=\"token keyword\">val<\/span> MAX_HISTORY_SIZE <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">50<\/span>  <span class=\"token comment\">\/\/ \u6700\u591a\u4fdd\u7559 50 \u6761\u6d88\u606f<\/span><\/p>\n<p><span class=\"token keyword\">fun<\/span> <span class=\"token function\">addToHistory<\/span><span class=\"token punctuation\">(<\/span>message<span class=\"token operator\">:<\/span> ConversationMessage<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    history<span class=\"token punctuation\">.<\/span><span class=\"token function\">add<\/span><span class=\"token punctuation\">(<\/span>message<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>history<span class=\"token punctuation\">.<\/span>size <span class=\"token operator\">&gt;<\/span> MAX_HISTORY_SIZE<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u79fb\u9664\u6700\u65e9\u7684\u6d88\u606f<\/span><br \/>\n        history<span class=\"token punctuation\">.<\/span><span class=\"token function\">removeAt<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<hr \/>\n<h3>\u4e5d\u3001\u6027\u80fd\u4f18\u5316\u6280\u5de7&#xff1a;\u6d41\u5f0f\u54cd\u5e94\u5904\u7406\u4e0e\u540e\u53f0\u7ebf\u7a0b\u8c03\u5ea6<\/h3>\n<h4>9.1 \u6d41\u5f0f\u54cd\u5e94&#xff08;Streaming&#xff09;\u5b9e\u73b0<\/h4>\n<p>\u6d41\u5f0f\u54cd\u5e94\u8ba9\u7528\u6237\u65e0\u9700\u7b49\u5f85\u5b8c\u6574\u751f\u6210&#xff0c;\u53ef\u4ee5\u9010\u5b57\u770b\u5230 AI \u56de\u590d&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ shared\/src\/commonMain\/kotlin\/com\/example\/koogagent\/streaming\/StreamingAgent.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>streaming<\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>core<span class=\"token punctuation\">.<\/span>agent<span class=\"token punctuation\">.<\/span>AIAgent<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>executor<span class=\"token punctuation\">.<\/span>StreamingPromptExecutor<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>executor<span class=\"token punctuation\">.<\/span>clients<span class=\"token punctuation\">.<\/span>openai<span class=\"token punctuation\">.<\/span>OpenAILLMClient<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span>flow<span class=\"token punctuation\">.<\/span>Flow<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span>flow<span class=\"token punctuation\">.<\/span>map<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u6d41\u5f0f Agent&#xff1a;\u652f\u6301\u9010 token \u8f93\u51fa<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> <span class=\"token function\">StreamingAgent<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> agent<span class=\"token operator\">:<\/span> AIAgent<br \/>\n<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u6d41\u5f0f\u6267\u884c&#xff1a;\u8fd4\u56de Flow&lt;String&gt;&#xff0c;\u6bcf\u4e2a\u5143\u7d20\u662f\u4e00\u4e2a token\/chunk<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">executeStreaming<\/span><span class=\"token punctuation\">(<\/span>input<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> Flow<span class=\"token operator\">&lt;<\/span>String<span class=\"token operator\">&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> agent<span class=\"token punctuation\">.<\/span><span class=\"token function\">executeStreaming<\/span><span class=\"token punctuation\">(<\/span>input<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span> <span class=\"token punctuation\">{<\/span> chunk <span class=\"token operator\">-&gt;<\/span><br \/>\n                chunk<span class=\"token punctuation\">.<\/span>delta<span class=\"token operator\">?<\/span><span class=\"token punctuation\">.<\/span>content <span class=\"token operator\">?:<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;&#034;<\/span><\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5728 ViewModel \u4e2d\u4f7f\u7528<\/span><br \/>\n<span class=\"token keyword\">class<\/span> ChatViewModel <span class=\"token operator\">:<\/span> <span class=\"token function\">ViewModel<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">sendStreamingMessage<\/span><span class=\"token punctuation\">(<\/span>userInput<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        _messages<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#043;&#061;<\/span> <span class=\"token function\">ChatMessage<\/span><span class=\"token punctuation\">(<\/span>role <span class=\"token operator\">&#061;<\/span> USER<span class=\"token punctuation\">,<\/span> content <span class=\"token operator\">&#061;<\/span> userInput<span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u521b\u5efa\u4e00\u4e2a\u5360\u4f4d\u7684 AI \u6d88\u606f<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> aiMessageIndex <span class=\"token operator\">&#061;<\/span> _messages<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">.<\/span>size<br \/>\n        _messages<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#043;&#061;<\/span> <span class=\"token function\">ChatMessage<\/span><span class=\"token punctuation\">(<\/span>role <span class=\"token operator\">&#061;<\/span> ASSISTANT<span class=\"token punctuation\">,<\/span> content <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>        viewModelScope<span class=\"token punctuation\">.<\/span><span class=\"token function\">launch<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                streamingAgent<span class=\"token punctuation\">.<\/span><span class=\"token function\">executeStreaming<\/span><span class=\"token punctuation\">(<\/span>userInput<span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token punctuation\">.<\/span><span class=\"token function\">collect<\/span> <span class=\"token punctuation\">{<\/span> token <span class=\"token operator\">-&gt;<\/span><br \/>\n                        <span class=\"token comment\">\/\/ \u9010 token \u66f4\u65b0 UI<\/span><br \/>\n                        <span class=\"token keyword\">val<\/span> current <span class=\"token operator\">&#061;<\/span> _messages<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">[<\/span>aiMessageIndex<span class=\"token punctuation\">]<\/span><br \/>\n                        _messages<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> _messages<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">.<\/span><span class=\"token function\">toMutableList<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">apply<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                            <span class=\"token keyword\">this<\/span><span class=\"token punctuation\">[<\/span>aiMessageIndex<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> current<span class=\"token punctuation\">.<\/span><span class=\"token function\">copy<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                                content <span class=\"token operator\">&#061;<\/span> current<span class=\"token punctuation\">.<\/span>content <span class=\"token operator\">&#043;<\/span> token<br \/>\n                            <span class=\"token punctuation\">)<\/span><br \/>\n                        <span class=\"token punctuation\">}<\/span><br \/>\n                    <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span>e<span class=\"token operator\">:<\/span> Exception<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                _error<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u6d41\u5f0f\u8bf7\u6c42\u5931\u8d25&#xff1a;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">e<span class=\"token punctuation\">.<\/span>message<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>9.2 \u534f\u7a0b\u8c03\u5ea6\u5668\u9009\u62e9<\/h4>\n<p><span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span><span class=\"token operator\">*<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u534f\u7a0b\u8c03\u5ea6\u6700\u4f73\u5b9e\u8df5<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">object<\/span> AgentDispatcher <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * Agent \u6267\u884c&#xff1a;\u4f7f\u7528 IO \u8c03\u5ea6\u5668&#xff08;\u7f51\u7edc\u5bc6\u96c6\u578b&#xff09;<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> agentExecution <span class=\"token operator\">&#061;<\/span> Dispatchers<span class=\"token punctuation\">.<\/span>IO<\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u5de5\u5177\u6267\u884c&#xff1a;\u6839\u636e\u5de5\u5177\u7c7b\u578b\u9009\u62e9<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> toolExecution <span class=\"token operator\">&#061;<\/span> Dispatchers<span class=\"token punctuation\">.<\/span>Default  <span class=\"token comment\">\/\/ CPU \u5bc6\u96c6\u578b\u5de5\u5177<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * UI \u66f4\u65b0&#xff1a;\u4e3b\u7ebf\u7a0b<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> uiUpdate <span class=\"token operator\">&#061;<\/span> Dispatchers<span class=\"token punctuation\">.<\/span>Main<\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u793a\u4f8b&#xff1a;\u6b63\u786e\u7684\u534f\u7a0b\u4f7f\u7528<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">executeAgentWithProperDispatch<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        agent<span class=\"token operator\">:<\/span> AIAgent<span class=\"token punctuation\">,<\/span><br \/>\n        input<span class=\"token operator\">:<\/span> String<br \/>\n    <span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ Agent \u8c03\u7528\u5728 IO \u7ebf\u7a0b<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token function\">withContext<\/span><span class=\"token punctuation\">(<\/span>agentExecution<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token keyword\">val<\/span> response <span class=\"token operator\">&#061;<\/span> agent<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span>input<span class=\"token punctuation\">)<\/span><br \/>\n            response<span class=\"token punctuation\">.<\/span>content<br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u56de\u5230\u8c03\u7528\u8005\u7684\u7ebf\u7a0b&#xff08;\u901a\u5e38\u662f Main&#xff09;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5728 ViewModel \u4e2d<\/span><br \/>\nviewModelScope<span class=\"token punctuation\">.<\/span><span class=\"token function\">launch<\/span><span class=\"token punctuation\">(<\/span>AgentDispatcher<span class=\"token punctuation\">.<\/span>agentExecution<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> result <span class=\"token operator\">&#061;<\/span> agent<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span>userInput<span class=\"token punctuation\">)<\/span><\/p>\n<p>    <span class=\"token function\">withContext<\/span><span class=\"token punctuation\">(<\/span>AgentDispatcher<span class=\"token punctuation\">.<\/span>uiUpdate<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u66f4\u65b0 UI<\/span><br \/>\n        _messages<span class=\"token punctuation\">.<\/span>value <span class=\"token operator\">&#043;&#061;<\/span> <span class=\"token function\">ChatMessage<\/span><span class=\"token punctuation\">(<\/span>ASSISTANT<span class=\"token punctuation\">,<\/span> result<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>9.3 \u5e76\u884c\u5de5\u5177\u8c03\u7528<\/h4>\n<p>\u5f53 LLM \u4e00\u6b21\u8fd4\u56de\u591a\u4e2a tool_call \u65f6&#xff0c;\u53ef\u4ee5\u5e76\u884c\u6267\u884c&#xff1a;<\/p>\n<p><span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span>async<br \/>\n<span class=\"token keyword\">import<\/span> kotlinx<span class=\"token punctuation\">.<\/span>coroutines<span class=\"token punctuation\">.<\/span>awaitAll<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u5e76\u884c\u5de5\u5177\u6267\u884c\u5668<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> <span class=\"token function\">ParallelToolExecutor<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> tools<span class=\"token operator\">:<\/span> Map<span class=\"token operator\">&lt;<\/span>String<span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">suspend<\/span> <span class=\"token punctuation\">(<\/span>String<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span> String<span class=\"token operator\">&gt;<\/span><br \/>\n<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u5e76\u884c\u6267\u884c\u591a\u4e2a\u5de5\u5177\u8c03\u7528<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">executeParallel<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        toolCalls<span class=\"token operator\">:<\/span> List<span class=\"token operator\">&lt;<\/span>ToolCall<span class=\"token operator\">&gt;<\/span><br \/>\n    <span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> List<span class=\"token operator\">&lt;<\/span>ToolResult<span class=\"token operator\">&gt;<\/span> <span class=\"token operator\">&#061;<\/span> coroutineScope <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u4e3a\u6bcf\u4e2a\u5de5\u5177\u8c03\u7528\u521b\u5efa\u5f02\u6b65\u4efb\u52a1<\/span><br \/>\n        toolCalls<span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span> <span class=\"token punctuation\">{<\/span> call <span class=\"token operator\">-&gt;<\/span><br \/>\n            <span class=\"token function\">async<\/span><span class=\"token punctuation\">(<\/span>Dispatchers<span class=\"token punctuation\">.<\/span>Default<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token keyword\">val<\/span> toolFn <span class=\"token operator\">&#061;<\/span> tools<span class=\"token punctuation\">[<\/span>call<span class=\"token punctuation\">.<\/span>functionName<span class=\"token punctuation\">]<\/span><br \/>\n                        <span class=\"token operator\">?:<\/span> <span class=\"token keyword\">throw<\/span> <span class=\"token function\">IllegalArgumentException<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;Unknown tool: <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">call<span class=\"token punctuation\">.<\/span>functionName<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>                    <span class=\"token keyword\">val<\/span> result <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">toolFn<\/span><span class=\"token punctuation\">(<\/span>call<span class=\"token punctuation\">.<\/span>arguments<span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token function\">ToolResult<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        toolCallId <span class=\"token operator\">&#061;<\/span> call<span class=\"token punctuation\">.<\/span>id<span class=\"token punctuation\">,<\/span><br \/>\n                        content <span class=\"token operator\">&#061;<\/span> result<span class=\"token punctuation\">,<\/span><br \/>\n                        isError <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">false<\/span><br \/>\n                    <span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span>e<span class=\"token operator\">:<\/span> Exception<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n                    <span class=\"token function\">ToolResult<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                        toolCallId <span class=\"token operator\">&#061;<\/span> call<span class=\"token punctuation\">.<\/span>id<span class=\"token punctuation\">,<\/span><br \/>\n                        content <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u5de5\u5177\u6267\u884c\u5931\u8d25&#xff1a;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">e<span class=\"token punctuation\">.<\/span>message<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span><br \/>\n                        isError <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><br \/>\n                    <span class=\"token punctuation\">)<\/span><br \/>\n                <span class=\"token punctuation\">}<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">awaitAll<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span>  <span class=\"token comment\">\/\/ \u7b49\u5f85\u6240\u6709\u5de5\u5177\u5b8c\u6210<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n<span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">ToolCall<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> id<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> functionName<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> arguments<span class=\"token operator\">:<\/span> String<br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<p><span class=\"token annotation builtin\">&#064;Serializable<\/span><br \/>\n<span class=\"token keyword\">data<\/span> <span class=\"token keyword\">class<\/span> <span class=\"token function\">ToolResult<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> toolCallId<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> content<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">val<\/span> isError<span class=\"token operator\">:<\/span> Boolean<br \/>\n<span class=\"token punctuation\">)<\/span><\/p>\n<h4>9.4 \u7f51\u7edc\u5c42\u4f18\u5316<\/h4>\n<p><span class=\"token comment\">\/**<br \/>\n * \u4f18\u5316\u7684 HttpClient \u914d\u7f6e<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">fun<\/span> <span class=\"token function\">createOptimizedHttpClient<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> HttpClient <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> HttpClient <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u8fde\u63a5\u8d85\u65f6<\/span><br \/>\n        <span class=\"token function\">install<\/span><span class=\"token punctuation\">(<\/span>HttpTimeout<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            connectTimeoutMillis <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">10_000<\/span>      <span class=\"token comment\">\/\/ \u8fde\u63a5\u8d85\u65f6 10s<\/span><br \/>\n            requestTimeoutMillis <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">60_000<\/span>      <span class=\"token comment\">\/\/ \u8bf7\u6c42\u8d85\u65f6 60s&#xff08;LLM \u53ef\u80fd\u8f83\u6162&#xff09;<\/span><br \/>\n            socketTimeoutMillis <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">60_000<\/span>       <span class=\"token comment\">\/\/ Socket \u8d85\u65f6<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u81ea\u52a8\u91cd\u8bd5<\/span><br \/>\n        <span class=\"token function\">install<\/span><span class=\"token punctuation\">(<\/span>HttpRetry<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token function\">retryOnServerErrors<\/span><span class=\"token punctuation\">(<\/span>maxRetries <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">3<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token function\">retryOnException<\/span><span class=\"token punctuation\">(<\/span>maxRetries <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">2<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            delayMillis <span class=\"token punctuation\">{<\/span> retry <span class=\"token operator\">-&gt;<\/span><br \/>\n                <span class=\"token number\">1000L<\/span> <span class=\"token operator\">*<\/span> retry  <span class=\"token comment\">\/\/ \u9012\u589e\u5ef6\u8fdf&#xff1a;1s, 2s, 3s<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ JSON \u5e8f\u5217\u5316<\/span><br \/>\n        <span class=\"token function\">install<\/span><span class=\"token punctuation\">(<\/span>ContentNegotiation<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            <span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span>Json <span class=\"token punctuation\">{<\/span><br \/>\n                ignoreUnknownKeys <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><br \/>\n                isLenient <span class=\"token operator\">&#061;<\/span> <span class=\"token boolean\">true<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8fde\u63a5\u6c60&#xff08;JVM \u5e73\u53f0&#xff09;<\/span><br \/>\n        engine <span class=\"token punctuation\">{<\/span><br \/>\n            maxConnectionsCount <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">20<\/span><br \/>\n            endpoint <span class=\"token punctuation\">{<\/span><br \/>\n                maxConnectionsPerRoute <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">10<\/span><br \/>\n                keepAliveTime <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">30_000<\/span><br \/>\n            <span class=\"token punctuation\">}<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>9.5 \u5185\u5b58\u4e0e Token \u9884\u7b97\u63a7\u5236<\/h4>\n<p><span class=\"token comment\">\/**<br \/>\n * Token \u9884\u7b97\u7ba1\u7406\u5668<br \/>\n * \u9632\u6b62\u5355\u6b21\u8bf7\u6c42\u6d88\u8017\u8fc7\u591a Token<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> <span class=\"token function\">TokenBudgetManager<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> maxTokensPerRequest<span class=\"token operator\">:<\/span> Int <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">4_096<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> maxTokensPerSession<span class=\"token operator\">:<\/span> Int <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">100_000<\/span><br \/>\n<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">var<\/span> sessionTokensUsed <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u68c0\u67e5\u662f\u5426\u8fd8\u6709\u9884\u7b97<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">canProceed<\/span><span class=\"token punctuation\">(<\/span>estimatedTokens<span class=\"token operator\">:<\/span> Int<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> Boolean <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">(<\/span>sessionTokensUsed <span class=\"token operator\">&#043;<\/span> estimatedTokens<span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&lt;&#061;<\/span> maxTokensPerSession<br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u8bb0\u5f55\u6d88\u8017<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">recordUsage<\/span><span class=\"token punctuation\">(<\/span>tokensUsed<span class=\"token operator\">:<\/span> Int<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        sessionTokensUsed <span class=\"token operator\">&#043;&#061;<\/span> tokensUsed<br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u83b7\u53d6\u5269\u4f59\u9884\u7b97<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">remainingBudget<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> Int <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> maxTokensPerSession <span class=\"token operator\">&#8211;<\/span> sessionTokensUsed<br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u91cd\u7f6e&#xff08;\u65b0\u4f1a\u8bdd&#xff09;<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">reset<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n        sessionTokensUsed <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">0<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<hr \/>\n<h3>\u5341\u3001\u8fdb\u9636\u573a\u666f&#xff1a;\u8131\u79bb Python \u670d\u52a1\u5b9e\u73b0\u7eaf Kotlin \u7aef\u4fa7\u667a\u80fd\u4f53<\/h3>\n<h4>10.1 \u7aef\u4fa7\u63a8\u7406\u6a21\u578b\u96c6\u6210&#xff08;Ollama \/ llama.cpp&#xff09;<\/h4>\n<p><span class=\"token comment\">\/\/ shared\/src\/commonMain\/kotlin\/com\/example\/koogagent\/local\/LocalModelAgent.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>local<\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>llm<span class=\"token punctuation\">.<\/span>LLModel<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>llm<span class=\"token punctuation\">.<\/span>LLMProvider<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>executor<span class=\"token punctuation\">.<\/span>SingleLLMPromptExecutor<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>executor<span class=\"token punctuation\">.<\/span>clients<span class=\"token punctuation\">.<\/span>ollama<span class=\"token punctuation\">.<\/span>OllamaLLMClient<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>prompt<span class=\"token punctuation\">.<\/span>executor<span class=\"token punctuation\">.<\/span>clients<span class=\"token punctuation\">.<\/span>LLMClientConfiguration<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u7eaf\u7aef\u4fa7 Agent&#xff1a;\u4f7f\u7528\u672c\u5730 Ollama \u6a21\u578b<br \/>\n * \u5b8c\u5168\u4e0d\u9700\u8981\u4e91\u7aef API&#xff0c;\u6570\u636e\u4e0d\u51fa\u8bbe\u5907<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">object<\/span> LocalAgentFactory <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u521b\u5efa\u672c\u5730 Agent<br \/>\n     * \u524d\u63d0&#xff1a;\u8bbe\u5907\u4e0a\u5df2\u8fd0\u884c Ollama \u670d\u52a1<br \/>\n     * &#8211; Android&#xff1a;\u901a\u8fc7 Termux \u6216\u4e13\u7528 App \u8fd0\u884c Ollama<br \/>\n     * &#8211; Desktop&#xff1a;\u76f4\u63a5\u5b89\u88c5 Ollama<br \/>\n     * &#8211; iOS&#xff1a;\u4f7f\u7528 llama.cpp \u7684 iOS \u7ed1\u5b9a<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">fun<\/span> <span class=\"token function\">createLocalAgent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> AIAgent <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u914d\u7f6e\u672c\u5730 Ollama \u8fde\u63a5<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> localConfig <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">LLMClientConfiguration<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            baseUrl <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;http:\/\/localhost:11434&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ Ollama \u9ed8\u8ba4\u7aef\u53e3<\/span><br \/>\n            apiKey <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;&#034;<\/span><\/span>  <span class=\"token comment\">\/\/ \u672c\u5730\u6a21\u578b\u4e0d\u9700\u8981 API Key<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token keyword\">val<\/span> ollamaClient <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">OllamaLLMClient<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            configuration <span class=\"token operator\">&#061;<\/span> localConfig<br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token keyword\">val<\/span> promptExecutor <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">SingleLLMPromptExecutor<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            llmClient <span class=\"token operator\">&#061;<\/span> ollamaClient<br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u4f7f\u7528\u672c\u5730\u6a21\u578b<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> localModel <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">LLModel<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            provider <span class=\"token operator\">&#061;<\/span> LLMProvider<span class=\"token punctuation\">.<\/span>Ollama<span class=\"token punctuation\">,<\/span><br \/>\n            id <span class=\"token operator\">&#061;<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;llama3.1:8b&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span>  <span class=\"token comment\">\/\/ 8B \u53c2\u6570\u6a21\u578b&#xff0c;\u9002\u5408\u7aef\u4fa7<\/span><br \/>\n            capabilities <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">setOf<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                LLMCapability<span class=\"token punctuation\">.<\/span>Completion<span class=\"token punctuation\">,<\/span><br \/>\n                LLMCapability<span class=\"token punctuation\">.<\/span>Tools<br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            contextLength <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">8_192<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            maxOutputTokens <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">2_048<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">AIAgent<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            promptExecutor <span class=\"token operator\">&#061;<\/span> promptExecutor<span class=\"token punctuation\">,<\/span><br \/>\n            model <span class=\"token operator\">&#061;<\/span> localModel<span class=\"token punctuation\">,<\/span><br \/>\n            systemPrompt <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>systemPrompt<span class=\"token punctuation\">,<\/span><br \/>\n            tools <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ToolSet<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                tools <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">listOf<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                    <span class=\"token function\">TodoTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                    <span class=\"token function\">CalculatorTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n                    <span class=\"token comment\">\/\/ \u6ce8\u610f&#xff1a;\u7aef\u4fa7\u6a21\u578b\u80fd\u529b\u6709\u9650&#xff0c;\u5de5\u5177\u4e0d\u5b9c\u8fc7\u591a<\/span><br \/>\n                <span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            maxIterations <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">5<\/span>  <span class=\"token comment\">\/\/ \u7aef\u4fa7\u6a21\u578b\u8fed\u4ee3\u6b21\u6570\u8981\u5c11<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>10.2 MCP \u534f\u8bae\u5bf9\u63a5\u5916\u90e8\u7cfb\u7edf<\/h4>\n<p>MCP&#xff08;Model Context Protocol&#xff09;\u662f Koog \u652f\u6301\u7684\u6807\u51c6\u534f\u8bae&#xff0c;\u7528\u4e8e\u8fde\u63a5\u5916\u90e8\u5de5\u5177\u548c\u6570\u636e\u6e90&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ shared\/src\/commonMain\/kotlin\/com\/example\/koogagent\/mcp\/MCPIntegration.kt<\/span><br \/>\n<span class=\"token keyword\">package<\/span> com<span class=\"token punctuation\">.<\/span>example<span class=\"token punctuation\">.<\/span>koogagent<span class=\"token punctuation\">.<\/span>mcp<\/p>\n<p><span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>mcp<span class=\"token punctuation\">.<\/span>MCPClient<br \/>\n<span class=\"token keyword\">import<\/span> ai<span class=\"token punctuation\">.<\/span>koog<span class=\"token punctuation\">.<\/span>agents<span class=\"token punctuation\">.<\/span>mcp<span class=\"token punctuation\">.<\/span>MCPToolProvider<\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * MCP \u96c6\u6210&#xff1a;\u8fde\u63a5\u5916\u90e8\u5de5\u5177\u670d\u52a1<br \/>\n * MCP \u5141\u8bb8 Agent \u52a8\u6001\u53d1\u73b0\u548c\u8c03\u7528\u5916\u90e8\u7cfb\u7edf\u7684\u80fd\u529b<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> MCPIntegration <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u8fde\u63a5 MCP \u670d\u52a1\u5668\u5e76\u83b7\u53d6\u53ef\u7528\u5de5\u5177<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">connectToMCPServer<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        serverUrl<span class=\"token operator\">:<\/span> String<br \/>\n    <span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> MCPToolProvider <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token keyword\">val<\/span> mcpClient <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">MCPClient<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            serverUrl <span class=\"token operator\">&#061;<\/span> serverUrl<span class=\"token punctuation\">,<\/span><br \/>\n            <span class=\"token comment\">\/\/ \u53ef\u9009&#xff1a;\u8ba4\u8bc1\u4fe1\u606f<\/span><br \/>\n            headers <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">mapOf<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;Authorization&#034;<\/span><\/span> <span class=\"token keyword\">to<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;Bearer <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\"><span class=\"token function\">getApiKey<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u8fde\u63a5\u5e76\u53d1\u73b0\u53ef\u7528\u5de5\u5177<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> toolProvider <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">MCPToolProvider<\/span><span class=\"token punctuation\">(<\/span>mcpClient<span class=\"token punctuation\">)<\/span><br \/>\n        toolProvider<span class=\"token punctuation\">.<\/span><span class=\"token function\">initialize<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u6253\u5370\u53d1\u73b0\u7684\u5de5\u5177<\/span><br \/>\n        toolProvider<span class=\"token punctuation\">.<\/span>availableTools<span class=\"token punctuation\">.<\/span><span class=\"token function\">forEach<\/span> <span class=\"token punctuation\">{<\/span> tool <span class=\"token operator\">-&gt;<\/span><br \/>\n            Platform<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;MCP&#034;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u53d1\u73b0\u5de5\u5177: <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">tool<span class=\"token punctuation\">.<\/span>name<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\"> &#8211; <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token expression\">tool<span class=\"token punctuation\">.<\/span>description<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> toolProvider<br \/>\n    <span class=\"token punctuation\">}<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u5c06 MCP \u5de5\u5177\u6ce8\u5165 Agent<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">createAgentWithMCP<\/span><span class=\"token punctuation\">(<\/span><br \/>\n        apiKey<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">,<\/span><br \/>\n        mcpServerUrl<span class=\"token operator\">:<\/span> String<br \/>\n    <span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> AIAgent <span class=\"token punctuation\">{<\/span><\/p>\n<p>        <span class=\"token keyword\">val<\/span> mcpTools <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">connectToMCPServer<\/span><span class=\"token punctuation\">(<\/span>mcpServerUrl<span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token keyword\">return<\/span> <span class=\"token function\">AIAgent<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            promptExecutor <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">SingleLLMPromptExecutor<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token function\">OpenAILLMClient<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">LLMClientConfiguration<\/span><span class=\"token punctuation\">(<\/span>apiKey <span class=\"token operator\">&#061;<\/span> apiKey<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n            model <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>model<span class=\"token punctuation\">,<\/span><br \/>\n            systemPrompt <span class=\"token operator\">&#061;<\/span> AgentConfig<span class=\"token punctuation\">.<\/span>systemPrompt<span class=\"token punctuation\">,<\/span><br \/>\n            tools <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">ToolSet<\/span><span class=\"token punctuation\">(<\/span><br \/>\n                <span class=\"token comment\">\/\/ \u5408\u5e76\u672c\u5730\u5de5\u5177\u548c MCP \u8fdc\u7a0b\u5de5\u5177<\/span><br \/>\n                tools <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">listOf<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">TodoTool<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n                externalToolProviders <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">listOf<\/span><span class=\"token punctuation\">(<\/span>mcpTools<span class=\"token punctuation\">)<\/span><br \/>\n            <span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>10.3 \u591a Agent \u534f\u4f5c\u67b6\u6784<\/h4>\n<p><span class=\"token comment\">\/**<br \/>\n * \u591a Agent \u534f\u4f5c&#xff1a;\u4e0d\u540c Agent \u8d1f\u8d23\u4e0d\u540c\u9886\u57df<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">class<\/span> MultiAgentOrchestrator <span class=\"token punctuation\">{<\/span><\/p>\n<p>    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> weatherAgent<span class=\"token operator\">:<\/span> AIAgent  <span class=\"token comment\">\/\/ \u5929\u6c14\u4e13\u5bb6<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> scheduleAgent<span class=\"token operator\">:<\/span> AIAgent <span class=\"token comment\">\/\/ \u65e5\u7a0b\u4e13\u5bb6<\/span><br \/>\n    <span class=\"token keyword\">private<\/span> <span class=\"token keyword\">val<\/span> routerAgent<span class=\"token operator\">:<\/span> AIAgent   <span class=\"token comment\">\/\/ \u8def\u7531 Agent<\/span><\/p>\n<p>    <span class=\"token comment\">\/**<br \/>\n     * \u8def\u7531 Agent \u51b3\u5b9a\u5c06\u8bf7\u6c42\u5206\u53d1\u7ed9\u54ea\u4e2a\u4e13\u5bb6 Agent<br \/>\n     *\/<\/span><br \/>\n    <span class=\"token keyword\">suspend<\/span> <span class=\"token keyword\">fun<\/span> <span class=\"token function\">handleRequest<\/span><span class=\"token punctuation\">(<\/span>input<span class=\"token operator\">:<\/span> String<span class=\"token punctuation\">)<\/span><span class=\"token operator\">:<\/span> String <span class=\"token punctuation\">{<\/span><br \/>\n        <span class=\"token comment\">\/\/ \u7b2c\u4e00\u6b65&#xff1a;\u8def\u7531\u5224\u65ad<\/span><br \/>\n        <span class=\"token keyword\">val<\/span> routingResult <span class=\"token operator\">&#061;<\/span> routerAgent<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span><br \/>\n            <span class=\"token string-literal multiline\"><span class=\"token string\">&#034;&#034;&#034;<br \/>\n            \u5206\u6790\u4ee5\u4e0b\u7528\u6237\u8bf7\u6c42&#xff0c;\u5224\u65ad\u5e94\u8be5\u7531\u54ea\u4e2a\u4e13\u5bb6\u5904\u7406&#xff1a;<br \/>\n            &#8211; weather: \u5929\u6c14\u76f8\u5173<br \/>\n            &#8211; schedule: \u65e5\u7a0b\/\u5f85\u529e\u76f8\u5173<br \/>\n            &#8211; general: \u901a\u7528\u95ee\u9898<\/p>\n<p>            \u7528\u6237\u8bf7\u6c42&#xff1a;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$<\/span><span class=\"token expression\">input<\/span><\/span><span class=\"token string\"><\/p>\n<p>            \u53ea\u56de\u7b54\u5206\u7c7b\u7ed3\u679c&#xff08;weather\/schedule\/general&#xff09;&#xff1a;<br \/>\n            &#034;&#034;&#034;<\/span><\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">trimIndent<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><br \/>\n        <span class=\"token punctuation\">)<\/span><\/p>\n<p>        <span class=\"token comment\">\/\/ \u7b2c\u4e8c\u6b65&#xff1a;\u5206\u53d1\u5230\u5bf9\u5e94\u4e13\u5bb6<\/span><br \/>\n        <span class=\"token keyword\">return<\/span> <span class=\"token keyword\">when<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n            routingResult<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;weather&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span><br \/>\n                weatherAgent<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span>input<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>content<br \/>\n            routingResult<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">.<\/span><span class=\"token function\">contains<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string-literal singleline\"><span class=\"token string\">&#034;schedule&#034;<\/span><\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">-&gt;<\/span><br \/>\n                scheduleAgent<span class=\"token punctuation\">.<\/span><span class=\"token function\">execute<\/span><span class=\"token punctuation\">(<\/span>input<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>content<br \/>\n            <span class=\"token keyword\">else<\/span> <span class=\"token operator\">-&gt;<\/span><br \/>\n                <span class=\"token string-literal singleline\"><span class=\"token string\">&#034;\u6211\u662f\u901a\u7528\u52a9\u624b\u3002<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">$<\/span><span class=\"token expression\">input<\/span><\/span><span class=\"token string\"> \u7684\u56de\u7b54\u662f&#8230;&#034;<\/span><\/span><br \/>\n        <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h4>10.4 \u751f\u4ea7\u73af\u5883\u90e8\u7f72\u6e05\u5355<\/h4>\n<table>\n<tr>\u68c0\u67e5\u9879\u72b6\u6001\u8bf4\u660e<\/tr>\n<tbody>\n<tr>\n<td>API Key \u5b89\u5168\u7ba1\u7406<\/td>\n<td>\u2610<\/td>\n<td>\u4f7f\u7528\u52a0\u5bc6\u5b58\u50a8&#xff0c;\u4e0d\u786c\u7f16\u7801<\/td>\n<\/tr>\n<tr>\n<td>\u7f51\u7edc\u8d85\u65f6\u914d\u7f6e<\/td>\n<td>\u2610<\/td>\n<td>\u8bbe\u7f6e\u5408\u7406\u8d85\u65f6&#xff0c;\u907f\u514d ANR<\/td>\n<\/tr>\n<tr>\n<td>\u9519\u8bef\u91cd\u8bd5\u7b56\u7565<\/td>\n<td>\u2610<\/td>\n<td>\u6307\u6570\u9000\u907f\u91cd\u8bd5<\/td>\n<\/tr>\n<tr>\n<td>Token \u9884\u7b97\u63a7\u5236<\/td>\n<td>\u2610<\/td>\n<td>\u9632\u6b62\u6210\u672c\u5931\u63a7<\/td>\n<\/tr>\n<tr>\n<td>\u5bf9\u8bdd\u5386\u53f2\u9650\u5236<\/td>\n<td>\u2610<\/td>\n<td>\u907f\u514d\u5185\u5b58\u6ea2\u51fa<\/td>\n<\/tr>\n<tr>\n<td>\u7528\u6237\u8f93\u5165\u6821\u9a8c<\/td>\n<td>\u2610<\/td>\n<td>\u9632\u6ce8\u5165\u653b\u51fb<\/td>\n<\/tr>\n<tr>\n<td>\u65e5\u5fd7\u8131\u654f<\/td>\n<td>\u2610<\/td>\n<td>\u4e0d\u8bb0\u5f55\u654f\u611f\u4fe1\u606f<\/td>\n<\/tr>\n<tr>\n<td>\u79bb\u7ebf\u964d\u7ea7\u65b9\u6848<\/td>\n<td>\u2610<\/td>\n<td>\u7f51\u7edc\u4e0d\u53ef\u7528\u65f6\u7684\u515c\u5e95<\/td>\n<\/tr>\n<tr>\n<td>\u7248\u672c\u517c\u5bb9<\/td>\n<td>\u2610<\/td>\n<td>\u6a21\u578b API \u7248\u672c\u9501\u5b9a<\/td>\n<\/tr>\n<tr>\n<td>\u6027\u80fd\u76d1\u63a7<\/td>\n<td>\u2610<\/td>\n<td>\u54cd\u5e94\u65f6\u95f4\u3001\u6210\u529f\u7387<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h3>\u5341\u4e00\u3001\u5e38\u89c1\u9677\u9631\u4e0e\u95ee\u9898\u6392\u9664\u901f\u67e5\u8868<\/h3>\n<table>\n<tr>#\u95ee\u9898\u73b0\u8c61\u539f\u56e0\u89e3\u51b3\u65b9\u6848<\/tr>\n<tbody>\n<tr>\n<td>1<\/td>\n<td>Unresolved reference: ai.koog<\/td>\n<td>\u4f9d\u8d56\u672a\u6b63\u786e\u6dfb\u52a0<\/td>\n<td>\u68c0\u67e5 commonMain dependencies<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>Serializer not found<\/td>\n<td>\u7f3a\u5c11 &#064;Serializable \u6216\u63d2\u4ef6<\/td>\n<td>\u6dfb\u52a0\u6ce8\u89e3 &#043; \u5e94\u7528 serialization \u63d2\u4ef6<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>No HttpClient engine<\/td>\n<td>\u5e73\u53f0\u6a21\u5757\u7f3a\u5c11\u5f15\u64ce\u4f9d\u8d56<\/td>\n<td>\u5404\u5e73\u53f0\u6dfb\u52a0\u5bf9\u5e94 Ktor \u5f15\u64ce<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>Agent \u65e0\u54cd\u5e94\/\u8d85\u65f6<\/td>\n<td>API Key \u65e0\u6548\u6216\u7f51\u7edc\u95ee\u9898<\/td>\n<td>\u9a8c\u8bc1 Key&#xff0c;\u68c0\u67e5\u7f51\u7edc\u4ee3\u7406\u8bbe\u7f6e<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>\u5de5\u5177\u4e0d\u88ab\u8c03\u7528<\/td>\n<td>Tool description \u4e0d\u591f\u6e05\u6670<\/td>\n<td>\u4f18\u5316 description&#xff0c;\u660e\u786e\u89e6\u53d1\u6761\u4ef6<\/td>\n<\/tr>\n<tr>\n<td>6<\/td>\n<td>\u65e0\u9650\u5faa\u73af\u8c03\u7528\u5de5\u5177<\/td>\n<td>maxIterations \u672a\u8bbe\u7f6e<\/td>\n<td>\u8bbe\u7f6e\u5408\u7406\u4e0a\u9650&#xff08;5-10&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>7<\/td>\n<td>iOS \u7f16\u8bd1\u5931\u8d25<\/td>\n<td>Kotlin\/Native \u7f13\u5b58\u95ee\u9898<\/td>\n<td>.\/gradlew clean &#043; \u5220\u9664 build<\/td>\n<\/tr>\n<tr>\n<td>8<\/td>\n<td>\u5185\u5b58\u6ea2\u51fa&#xff08;iOS&#xff09;<\/td>\n<td>\u5bf9\u8bdd\u5386\u53f2\u8fc7\u957f<\/td>\n<td>\u9650\u5236\u5386\u53f2\u957f\u5ea6 &#043; \u5b9a\u671f\u538b\u7f29<\/td>\n<\/tr>\n<tr>\n<td>9<\/td>\n<td>\u7248\u672c\u51b2\u7a81<\/td>\n<td>\u591a\u5e93\u4f9d\u8d56\u540c\u4e00\u5e93\u4e0d\u540c\u7248\u672c<\/td>\n<td>resolutionStrategy \u5f3a\u5236\u7edf\u4e00<\/td>\n<\/tr>\n<tr>\n<td>10<\/td>\n<td>\u6d41\u5f0f\u54cd\u5e94\u5361\u987f<\/td>\n<td>UI \u7ebf\u7a0b\u963b\u585e<\/td>\n<td>\u786e\u4fdd collect \u5728\u6b63\u786e\u8c03\u5ea6\u5668<\/td>\n<\/tr>\n<tr>\n<td>11<\/td>\n<td>401 Unauthorized<\/td>\n<td>API Key \u8fc7\u671f\u6216\u683c\u5f0f\u9519\u8bef<\/td>\n<td>\u91cd\u65b0\u751f\u6210 Key&#xff0c;\u68c0\u67e5\u524d\u7f00<\/td>\n<\/tr>\n<tr>\n<td>12<\/td>\n<td>429 Rate Limit<\/td>\n<td>\u8bf7\u6c42\u9891\u7387\u8d85\u9650<\/td>\n<td>\u6dfb\u52a0\u9650\u6d41\u5668&#xff0c;\u6307\u6570\u9000\u907f<\/td>\n<\/tr>\n<tr>\n<td>13<\/td>\n<td>Android \u5d29\u6e83 NetworkOnMainThread<\/td>\n<td>\u4e3b\u7ebf\u7a0b\u53d1\u8d77\u7f51\u7edc\u8bf7\u6c42<\/td>\n<td>\u786e\u4fdd\u5728\u534f\u7a0b IO \u8c03\u5ea6\u5668\u4e2d\u6267\u884c<\/td>\n<\/tr>\n<tr>\n<td>14<\/td>\n<td>Desktop \u7a97\u53e3\u65e0\u54cd\u5e94<\/td>\n<td>\u540c\u6b65\u963b\u585e UI \u7ebf\u7a0b<\/td>\n<td>\u4f7f\u7528 suspend &#043; viewModelScope<\/td>\n<\/tr>\n<tr>\n<td>15<\/td>\n<td>\u4e2d\u6587\u4e71\u7801<\/td>\n<td>\u7f16\u7801\u8bbe\u7f6e\u95ee\u9898<\/td>\n<td>\u786e\u4fdd UTF-8&#xff0c;\u68c0\u67e5 Content-Type<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h3>\u5341\u4e8c\u3001\u603b\u7ed3\u4e0e\u5c55\u671b<\/h3>\n<h4>\u6838\u5fc3\u8981\u70b9\u56de\u987e<\/h4>\n<p>\u901a\u8fc7\u672c\u6559\u7a0b&#xff0c;\u6211\u4eec\u5b8c\u6210\u4e86\u4ee5\u4e0b\u5b8c\u6574\u94fe\u8def&#xff1a;<\/p>\n<li>\u73af\u5883\u642d\u5efa&#xff1a;\u4ece\u96f6\u914d\u7f6e\u4e86\u652f\u6301 Android\/iOS\/Desktop \u4e09\u7aef\u7684 KMP \u9879\u76ee<\/li>\n<li>\u6846\u67b6\u7406\u89e3&#xff1a;\u6df1\u5165\u7406\u89e3\u4e86 Koog \u7684\u4e94\u5c42\u67b6\u6784\u3001Prompt\/Tool\/Strategy \u6838\u5fc3\u6982\u5ff5<\/li>\n<li>Agent \u521b\u5efa&#xff1a;\u5728 Android \u7aef\u6210\u529f\u521d\u59cb\u5316\u5e76\u8fd0\u884c\u4e86\u7b2c\u4e00\u4e2a AI Agent<\/li>\n<li>\u5de5\u5177\u5f00\u53d1&#xff1a;\u5b9e\u73b0\u4e86\u5929\u6c14\u67e5\u8be2\u3001\u5f85\u529e\u7ba1\u7406\u7b49\u7c7b\u578b\u5b89\u5168\u7684\u81ea\u5b9a\u4e49\u5de5\u5177<\/li>\n<li>\u5bf9\u8bdd\u7ba1\u7406&#xff1a;\u6784\u5efa\u4e86\u591a\u8f6e\u5bf9\u8bdd\u72b6\u6001\u673a&#xff0c;\u5b9e\u73b0\u4e86\u4e0a\u4e0b\u6587\u7a97\u53e3\u7ba1\u7406\u548c\u6301\u4e45\u5316<\/li>\n<li>\u8de8\u5e73\u53f0\u9a8c\u8bc1&#xff1a;\u5c06\u540c\u4e00\u5957 Agent \u903b\u8f91\u65e0\u7f1d\u8fc1\u79fb\u5230 iOS \u548c Desktop<\/li>\n<li>\u95ee\u9898\u6392\u67e5&#xff1a;\u638c\u63e1\u4e86\u5e38\u89c1\u7f16\u8bd1\u9519\u8bef\u548c\u8fd0\u884c\u65f6\u95ee\u9898\u7684\u89e3\u51b3\u65b9\u6cd5<\/li>\n<li>\u6027\u80fd\u4f18\u5316&#xff1a;\u5b9e\u73b0\u4e86\u6d41\u5f0f\u54cd\u5e94\u3001\u5e76\u884c\u5de5\u5177\u8c03\u7528\u3001Token \u9884\u7b97\u63a7\u5236<\/li>\n<li>\u8fdb\u9636\u65b9\u6848&#xff1a;\u63a2\u7d22\u4e86\u7eaf\u7aef\u4fa7\u63a8\u7406\u3001MCP \u534f\u8bae\u3001\u591a Agent \u534f\u4f5c<\/li>\n<h4>2026 \u5e74\u540e\u7684\u5c55\u671b<\/h4>\n<ul>\n<li>Koog \u751f\u6001\u6210\u719f&#xff1a;\u9884\u8ba1 2026 \u4e0b\u534a\u5e74 Koog \u5c06\u8fbe\u5230 1.0 \u7a33\u5b9a\u7248<\/li>\n<li>\u7aef\u4fa7\u6a21\u578b\u8fdb\u6b65&#xff1a;\u968f\u7740\u624b\u673a NPU \u6027\u80fd\u63d0\u5347&#xff0c;8B \u751a\u81f3 13B \u6a21\u578b\u7684\u7aef\u4fa7\u63a8\u7406\u5c06\u6210\u4e3a\u5e38\u6001<\/li>\n<li>MCP \u6807\u51c6\u5316&#xff1a;MCP \u534f\u8bae\u5c06\u6210\u4e3a Agent \u5de5\u5177\u4e92\u64cd\u4f5c\u7684\u4e8b\u5b9e\u6807\u51c6<\/li>\n<li>KMP &#043; AI \u878d\u5408&#xff1a;KotlinConf 2026 \u5df2\u660e\u786e AI \u00d7 Multiplatform \u662f\u6838\u5fc3\u65b9\u5411<\/li>\n<\/ul>\n<p>\u4e00\u53e5\u8bdd\u603b\u7ed3&#xff1a;2026 \u5e74&#xff0c;Kotlin \u5f00\u53d1\u8005\u4e0d\u518d\u9700\u8981 Python \u6765\u6784\u5efa AI Agent\u3002Koog &#043; KMP \u8ba9\u4f60\u7528\u719f\u6089\u7684\u8bed\u8a00\u3001\u719f\u6089\u7684\u5de5\u5177\u94fe&#xff0c;\u5728\u5168\u5e73\u53f0\u6784\u5efa\u7c7b\u578b\u5b89\u5168\u3001\u53ef\u9884\u6d4b\u3001\u4f01\u4e1a\u5c31\u7eea\u7684\u539f\u751f\u667a\u80fd\u4f53\u3002<\/p>\n<hr \/>\n<h3>\u5341\u4e09\u3001\u8be6\u7ec6\u53c2\u8003\u8d44\u6599<\/h3>\n<table>\n<tr>\u8d44\u6e90\u94fe\u63a5\u8bf4\u660e<\/tr>\n<tbody>\n<tr>\n<td>Koog \u5b98\u65b9\u7f51\u7ad9<\/td>\n<td>https:\/\/www.jetbrains.com\/koog\/<\/td>\n<td>\u5b98\u65b9\u6587\u6863\u4e0e\u4e0b\u8f7d<\/td>\n<\/tr>\n<tr>\n<td>Koog GitHub<\/td>\n<td>https:\/\/github.com\/JetBrains\/koog<\/td>\n<td>\u6e90\u7801\u4e0e\u793a\u4f8b<\/td>\n<\/tr>\n<tr>\n<td>Koog \u53d1\u5e03\u516c\u544a<\/td>\n<td>https:\/\/blog.jetbrains.com\/ai\/2025\/06\/meet-koog\/<\/td>\n<td>KotlinConf \u53d1\u5e03\u535a\u5ba2<\/td>\n<\/tr>\n<tr>\n<td>KMP \u5b98\u65b9\u6587\u6863<\/td>\n<td>https:\/\/kotlinlang.org\/docs\/multiplatform.html<\/td>\n<td>KMP \u6838\u5fc3\u6587\u6863<\/td>\n<\/tr>\n<tr>\n<td>KMP \u9879\u76ee\u5411\u5bfc<\/td>\n<td>https:\/\/kmp.jetbrains.com<\/td>\n<td>\u5728\u7ebf\u521b\u5efa KMP \u9879\u76ee<\/td>\n<\/tr>\n<tr>\n<td>Compose Multiplatform<\/td>\n<td>https:\/\/www.jetbrains.com\/compose-multiplatform\/<\/td>\n<td>\u8de8\u5e73\u53f0 UI<\/td>\n<\/tr>\n<tr>\n<td>Kotlin 2.2 \u53d1\u5e03\u8bf4\u660e<\/td>\n<td>https:\/\/kotlinlang.org\/docs\/whatsnew22.html<\/td>\n<td>\u65b0\u8bed\u8a00\u7279\u6027<\/td>\n<\/tr>\n<tr>\n<td>JetBrains Blog (Koog for Java)<\/td>\n<td>https:\/\/blog.jetbrains.com\/ai\/2026\/03\/koog-comes-to-java\/<\/td>\n<td>Java API \u53d1\u5e03<\/td>\n<\/tr>\n<tr>\n<td>OpenAI API \u6587\u6863<\/td>\n<td>https:\/\/platform.openai.com\/docs<\/td>\n<td>\u6a21\u578b API \u53c2\u8003<\/td>\n<\/tr>\n<tr>\n<td>Ollama \u5b98\u65b9<\/td>\n<td>https:\/\/ollama.ai<\/td>\n<td>\u672c\u5730\u6a21\u578b\u8fd0\u884c<\/td>\n<\/tr>\n<tr>\n<td>MCP \u534f\u8bae\u89c4\u8303<\/td>\n<td>https:\/\/modelcontextprotocol.io<\/td>\n<td>Agent \u5de5\u5177\u4e92\u64cd\u4f5c\u6807\u51c6<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<h3>\u9644\u5f55<\/h3>\n<h4>\u9644\u5f55 A&#xff1a;\u5b8c\u6574\u9879\u76ee\u7ed3\u6784\u6811<\/h4>\n<p>KoogAgentDemo\/<br \/>\n\u251c\u2500\u2500 settings.gradle.kts<br \/>\n\u251c\u2500\u2500 build.gradle.kts<br \/>\n\u251c\u2500\u2500 gradle\/<br \/>\n\u2502   \u2514\u2500\u2500 libs.versions.toml          # \u7248\u672c\u76ee\u5f55<br \/>\n\u251c\u2500\u2500 local.properties                 # API Key&#xff08;\u4e0d\u63d0\u4ea4 Git&#xff09;<br \/>\n\u251c\u2500\u2500 shared\/                          # \u5171\u4eab\u6a21\u5757&#xff08;\u6838\u5fc3&#xff09;<br \/>\n\u2502   \u251c\u2500\u2500 build.gradle.kts<br \/>\n\u2502   \u2514\u2500\u2500 src\/<br \/>\n\u2502       \u251c\u2500\u2500 commonMain\/kotlin\/com\/example\/koogagent\/<br \/>\n\u2502       \u2502   \u251c\u2500\u2500 AgentConfig.kt       # Agent \u914d\u7f6e<br \/>\n\u2502       \u2502   \u251c\u2500\u2500 AgentFactory.kt      # Agent \u5de5\u5382<br \/>\n\u2502       \u2502   \u251c\u2500\u2500 tools\/<br \/>\n\u2502       \u2502   \u2502   \u251c\u2500\u2500 WeatherTool.kt   # \u5929\u6c14\u5de5\u5177<br \/>\n\u2502       \u2502   \u2502   \u251c\u2500\u2500 TodoTool.kt      # \u5f85\u529e\u5de5\u5177<br \/>\n\u2502       \u2502   \u2502   \u2514\u2500\u2500 CalculatorTool.kt<br \/>\n\u2502       \u2502   \u251c\u2500\u2500 memory\/<br \/>\n\u2502       \u2502   \u2502   \u251c\u2500\u2500 ConversationManager.kt<br \/>\n\u2502       \u2502   \u2502   \u251c\u2500\u2500 ContextWindowManager.kt<br \/>\n\u2502       \u2502   \u2502   \u2514\u2500\u2500 AgentStorage.kt<br \/>\n\u2502       \u2502   \u251c\u2500\u2500 streaming\/<br \/>\n\u2502       \u2502   \u2502   \u2514\u2500\u2500 StreamingAgent.kt<br \/>\n\u2502       \u2502   \u251c\u2500\u2500 local\/<br \/>\n\u2502       \u2502   \u2502   \u2514\u2500\u2500 LocalModelAgent.kt<br \/>\n\u2502       \u2502   \u2514\u2500\u2500 platform\/<br \/>\n\u2502       \u2502       \u2514\u2500\u2500 Platform.kt      # expect \u58f0\u660e<br \/>\n\u2502       \u251c\u2500\u2500 commonTest\/kotlin\/<br \/>\n\u2502       \u2502   \u2514\u2500\u2500 AgentIntegrationTest.kt<br \/>\n\u2502       \u251c\u2500\u2500 androidMain\/kotlin\/<br \/>\n\u2502       \u2502   \u2514\u2500\u2500 platform\/Platform.android.kt<br \/>\n\u2502       \u251c\u2500\u2500 iosMain\/kotlin\/<br \/>\n\u2502       \u2502   \u251c\u2500\u2500 platform\/Platform.ios.kt<br \/>\n\u2502       \u2502   \u2514\u2500\u2500 IOSAgentBridge.kt<br \/>\n\u2502       \u2514\u2500\u2500 desktopMain\/kotlin\/<br \/>\n\u2502           \u2514\u2500\u2500 platform\/Platform.desktop.kt<br \/>\n\u251c\u2500\u2500 androidApp\/                      # Android \u58f3\u5de5\u7a0b<br \/>\n\u2502   \u251c\u2500\u2500 build.gradle.kts<br \/>\n\u2502   \u2514\u2500\u2500 src\/main\/<br \/>\n\u2502       \u251c\u2500\u2500 java\/&#8230;\/<br \/>\n\u2502       \u2502   \u251c\u2500\u2500 MainActivity.kt<br \/>\n\u2502       \u2502   \u251c\u2500\u2500 ChatViewModel.kt<br \/>\n\u2502       \u2502   \u2514\u2500\u2500 ChatScreen.kt<br \/>\n\u2502       \u2514\u2500\u2500 AndroidManifest.xml<br \/>\n\u251c\u2500\u2500 iosApp\/                          # iOS \u5de5\u7a0b<br \/>\n\u2502   \u251c\u2500\u2500 iosApp.xcodeproj<br \/>\n\u2502   \u2514\u2500\u2500 iosApp\/<br \/>\n\u2502       \u251c\u2500\u2500 ContentView.swift<br \/>\n\u2502       \u2514\u2500\u2500 Info.plist<br \/>\n\u2514\u2500\u2500 desktopApp\/                      # Desktop \u58f3\u5de5\u7a0b<br \/>\n    \u251c\u2500\u2500 build.gradle.kts<br \/>\n    \u2514\u2500\u2500 src\/main\/kotlin\/Main.kt<\/p>\n<h4>\u9644\u5f55 B&#xff1a;Gradle \u7248\u672c\u517c\u5bb9\u77e9\u9635<\/h4>\n<table>\n<tr>KotlinAGPGradleKoogKtorCoroutines<\/tr>\n<tbody>\n<tr>\n<td>2.2.20<\/td>\n<td>9.0.0<\/td>\n<td>8.10<\/td>\n<td>0.7.2<\/td>\n<td>3.1.0<\/td>\n<td>1.9.0<\/td>\n<\/tr>\n<tr>\n<td>2.2.0<\/td>\n<td>8.7.0<\/td>\n<td>8.9<\/td>\n<td>0.7.0<\/td>\n<td>3.0.3<\/td>\n<td>1.9.0<\/td>\n<\/tr>\n<tr>\n<td>2.1.20<\/td>\n<td>8.5.0<\/td>\n<td>8.7<\/td>\n<td>0.6.4<\/td>\n<td>3.0.1<\/td>\n<td>1.8.1<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u26a0\ufe0f Koog 0.7.x \u8981\u6c42 Kotlin \u2265 2.2.0\u3002\u4f7f\u7528\u65e7\u7248 Kotlin \u4f1a\u5bfc\u81f4\u7f16\u8bd1\u9519\u8bef\u3002<\/p>\n<h4>\u9644\u5f55 C&#xff1a;Koog API \u901f\u67e5\u8868<\/h4>\n<table>\n<tr>\u7c7b\/\u51fd\u6570\u5305\u8def\u5f84\u7528\u9014<\/tr>\n<tbody>\n<tr>\n<td>AIAgent<\/td>\n<td>ai.koog.agents.core.agent<\/td>\n<td>Agent \u4e3b\u7c7b<\/td>\n<\/tr>\n<tr>\n<td>SingleLLMPromptExecutor<\/td>\n<td>ai.koog.prompt.executor<\/td>\n<td>\u5355\u6a21\u578b\u6267\u884c\u5668<\/td>\n<\/tr>\n<tr>\n<td>OpenAILLMClient<\/td>\n<td>ai.koog.prompt.executor.clients.openai<\/td>\n<td>OpenAI \u5ba2\u6237\u7aef<\/td>\n<\/tr>\n<tr>\n<td>OllamaLLMClient<\/td>\n<td>ai.koog.prompt.executor.clients.ollama<\/td>\n<td>Ollama \u5ba2\u6237\u7aef<\/td>\n<\/tr>\n<tr>\n<td>LLModel<\/td>\n<td>ai.koog.prompt.llm<\/td>\n<td>\u6a21\u578b\u5b9a\u4e49<\/td>\n<\/tr>\n<tr>\n<td>LLMProvider<\/td>\n<td>ai.koog.prompt.llm<\/td>\n<td>\u63d0\u4f9b\u5546\u679a\u4e3e<\/td>\n<\/tr>\n<tr>\n<td>LLMCapability<\/td>\n<td>ai.koog.prompt.llm<\/td>\n<td>\u6a21\u578b\u80fd\u529b<\/td>\n<\/tr>\n<tr>\n<td>&#064;Tool<\/td>\n<td>ai.koog.agents.tools.annotation<\/td>\n<td>\u5de5\u5177\u6ce8\u89e3<\/td>\n<\/tr>\n<tr>\n<td>&#064;ToolParam<\/td>\n<td>ai.koog.agents.tools.annotation<\/td>\n<td>\u53c2\u6570\u6ce8\u89e3<\/td>\n<\/tr>\n<tr>\n<td>ToolSet<\/td>\n<td>ai.koog.agents.tools<\/td>\n<td>\u5de5\u5177\u96c6\u5408<\/td>\n<\/tr>\n<tr>\n<td>PromptTemplate<\/td>\n<td>ai.koog.prompt.template<\/td>\n<td>\u63d0\u793a\u8bcd\u6a21\u677f<\/td>\n<\/tr>\n<tr>\n<td>AIAgentStorage<\/td>\n<td>ai.koog.agents.storage<\/td>\n<td>\u6301\u4e45\u5316\u63a5\u53e3<\/td>\n<\/tr>\n<tr>\n<td>MCPClient<\/td>\n<td>ai.koog.agents.mcp<\/td>\n<td>MCP \u5ba2\u6237\u7aef<\/td>\n<\/tr>\n<tr>\n<td>GraphAgentStrategy<\/td>\n<td>ai.koog.agents.graph<\/td>\n<td>\u56fe\u5de5\u4f5c\u6d41\u7b56\u7565<\/td>\n<\/tr>\n<tr>\n<td>FunctionalAgentStrategy<\/td>\n<td>ai.koog.agents.strategy<\/td>\n<td>\u51fd\u6570\u5f0f\u7b56\u7565<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>\u9644\u5f55 D&#xff1a;\u672f\u8bed\u8868<\/h4>\n<table>\n<tr>\u672f\u8bed\u82f1\u6587\u89e3\u91ca<\/tr>\n<tbody>\n<tr>\n<td>Agent<\/td>\n<td>AI Agent<\/td>\n<td>\u5177\u5907\u81ea\u4e3b\u51b3\u7b56\u548c\u5de5\u5177\u8c03\u7528\u80fd\u529b\u7684 AI \u5b9e\u4f53<\/td>\n<\/tr>\n<tr>\n<td>Prompt<\/td>\n<td>Prompt<\/td>\n<td>\u53d1\u9001\u7ed9 LLM \u7684\u6307\u4ee4\/\u4e0a\u4e0b\u6587\u6587\u672c<\/td>\n<\/tr>\n<tr>\n<td>Tool Calling<\/td>\n<td>Function Calling<\/td>\n<td>LLM \u8c03\u7528\u5916\u90e8\u51fd\u6570\u83b7\u53d6\u4fe1\u606f\u6216\u6267\u884c\u64cd\u4f5c<\/td>\n<\/tr>\n<tr>\n<td>Strategy<\/td>\n<td>Strategy<\/td>\n<td>Agent \u7684\u51b3\u7b56\u903b\u8f91\/\u6267\u884c\u6d41\u7a0b<\/td>\n<\/tr>\n<tr>\n<td>Graph Workflow<\/td>\n<td>Graph Workflow<\/td>\n<td>\u57fa\u4e8e\u6709\u5411\u56fe\u7684\u590d\u6742\u5de5\u4f5c\u6d41<\/td>\n<\/tr>\n<tr>\n<td>GOAP<\/td>\n<td>Goal-Oriented Action Planning<\/td>\n<td>\u76ee\u6807\u5bfc\u5411\u884c\u52a8\u89c4\u5212<\/td>\n<\/tr>\n<tr>\n<td>MCP<\/td>\n<td>Model Context Protocol<\/td>\n<td>\u6a21\u578b\u4e0a\u4e0b\u6587\u534f\u8bae&#xff0c;Agent \u5de5\u5177\u4e92\u64cd\u4f5c\u6807\u51c6<\/td>\n<\/tr>\n<tr>\n<td>RAG<\/td>\n<td>Retrieval-Augmented Generation<\/td>\n<td>\u68c0\u7d22\u589e\u5f3a\u751f\u6210<\/td>\n<\/tr>\n<tr>\n<td>Token<\/td>\n<td>Token<\/td>\n<td>LLM \u5904\u7406\u6587\u672c\u7684\u57fa\u672c\u5355\u4f4d<\/td>\n<\/tr>\n<tr>\n<td>Context Window<\/td>\n<td>Context Window<\/td>\n<td>\u6a21\u578b\u4e00\u6b21\u80fd\u5904\u7406\u7684\u6700\u5927 token \u6570<\/td>\n<\/tr>\n<tr>\n<td>Streaming<\/td>\n<td>Streaming<\/td>\n<td>\u9010 token \u6d41\u5f0f\u8f93\u51fa\u54cd\u5e94<\/td>\n<\/tr>\n<tr>\n<td>KMP<\/td>\n<td>Kotlin Multiplatform<\/td>\n<td>Kotlin \u8de8\u5e73\u53f0\u6280\u672f<\/td>\n<\/tr>\n<tr>\n<td>expect\/actual<\/td>\n<td>expect\/actual<\/td>\n<td>KMP \u5e73\u53f0\u5dee\u5f02\u5316\u5b9e\u73b0\u673a\u5236<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<hr \/>\n<p>\u672c\u6587\u5199\u4e8e 2026 \u5e74 8 \u6708&#xff0c;\u57fa\u4e8e Koog 0.7.x \u4e0e Kotlin 2.2&#043;\u3002\u6846\u67b6 API \u53ef\u80fd\u968f\u7248\u672c\u66f4\u65b0\u800c\u53d8\u5316&#xff0c;\u8bf7\u4ee5\u5b98\u65b9\u6587\u6863\u4e3a\u51c6\u3002<\/p>\n<p>\u4f5c\u8005\u6ce8&#xff1a;\u5982\u679c\u672c\u6587\u5bf9\u4f60\u6709\u5e2e\u52a9&#xff0c;\u6b22\u8fce\u70b9\u8d5e\u6536\u85cf\u3002\u9047\u5230\u95ee\u9898\u53ef\u5728\u8bc4\u8bba\u533a\u4ea4\u6d41\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>KMP \u5168\u6808\u5f00\u53d1&#xff1a;\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent\u6458\u8981<br \/>\n2026 \u5e74&#xff0c;Kotlin Multiplatform&#xff08;KMP&#xff09;\u5df2\u4ece\u5b9e\u9a8c\u6027\u6280\u672f\u8dc3\u8fc1\u4e3a\u4f01\u4e1a\u7ea7\u751f\u4ea7\u65b9\u6848&#xff0c;\u800c JetBrains \u63a8\u51fa\u7684 Koog \u6846\u67b6\u5219\u586b\u8865\u4e86 JVM\/Kotlin \u751f\u6001\u5728 AI Agent \u9886\u57df\u7684\u7a7a\u767d\u3002\u672c\u6587\u662f\u4e00\u7bc7\u9762\u5411\u65b0\u624b\u7684\u5b8c\u6574\u5b9e\u6218\u6559\u7a0b&#xff0c;\u4ece\u96f6\u5f00\u59cb\u624b\u628a\u624b\u5e26\u4f60\u4f7f\u7528 Koog \u6846\u67b6\u5728 KMP \u9879\u76ee\u4e2d\u6784\u5efa\u539f\u751f AI Age<\/p>\n","protected":false},"author":2,"featured_media":91996,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[50],"topic":[],"class_list":["post-91997","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server","tag-50"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>KMP \u5168\u6808\u5f00\u53d1\uff1a\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/91997.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"KMP \u5168\u6808\u5f00\u53d1\uff1a\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"KMP \u5168\u6808\u5f00\u53d1&#xff1a;\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent\u6458\u8981 2026 \u5e74&#xff0c;Kotlin Multiplatform&#xff08;KMP&#xff09;\u5df2\u4ece\u5b9e\u9a8c\u6027\u6280\u672f\u8dc3\u8fc1\u4e3a\u4f01\u4e1a\u7ea7\u751f\u4ea7\u65b9\u6848&#xff0c;\u800c JetBrains \u63a8\u51fa\u7684 Koog \u6846\u67b6\u5219\u586b\u8865\u4e86 JVM\/Kotlin \u751f\u6001\u5728 AI Agent \u9886\u57df\u7684\u7a7a\u767d\u3002\u672c\u6587\u662f\u4e00\u7bc7\u9762\u5411\u65b0\u624b\u7684\u5b8c\u6574\u5b9e\u6218\u6559\u7a0b&#xff0c;\u4ece\u96f6\u5f00\u59cb\u624b\u628a\u624b\u5e26\u4f60\u4f7f\u7528 Koog \u6846\u67b6\u5728 KMP \u9879\u76ee\u4e2d\u6784\u5efa\u539f\u751f AI Age\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/91997.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-08T14:17:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/08\/20260808141700-6a773a5c637e9.jpg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"29 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/91997.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/91997.html\",\"name\":\"KMP \u5168\u6808\u5f00\u53d1\uff1a\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-08-08T14:17:06+00:00\",\"dateModified\":\"2026-08-08T14:17:06+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/91997.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/91997.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/91997.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"KMP \u5168\u6808\u5f00\u53d1\uff1a\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"KMP \u5168\u6808\u5f00\u53d1\uff1a\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/91997.html","og_locale":"zh_CN","og_type":"article","og_title":"KMP \u5168\u6808\u5f00\u53d1\uff1a\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"KMP \u5168\u6808\u5f00\u53d1&#xff1a;\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent\u6458\u8981 2026 \u5e74&#xff0c;Kotlin Multiplatform&#xff08;KMP&#xff09;\u5df2\u4ece\u5b9e\u9a8c\u6027\u6280\u672f\u8dc3\u8fc1\u4e3a\u4f01\u4e1a\u7ea7\u751f\u4ea7\u65b9\u6848&#xff0c;\u800c JetBrains \u63a8\u51fa\u7684 Koog \u6846\u67b6\u5219\u586b\u8865\u4e86 JVM\/Kotlin \u751f\u6001\u5728 AI Agent \u9886\u57df\u7684\u7a7a\u767d\u3002\u672c\u6587\u662f\u4e00\u7bc7\u9762\u5411\u65b0\u624b\u7684\u5b8c\u6574\u5b9e\u6218\u6559\u7a0b&#xff0c;\u4ece\u96f6\u5f00\u59cb\u624b\u628a\u624b\u5e26\u4f60\u4f7f\u7528 Koog \u6846\u67b6\u5728 KMP \u9879\u76ee\u4e2d\u6784\u5efa\u539f\u751f AI Age","og_url":"https:\/\/www.wsisp.com\/helps\/91997.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-08-08T14:17:06+00:00","og_image":[{"url":"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/08\/20260808141700-6a773a5c637e9.jpg"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"29 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/91997.html","url":"https:\/\/www.wsisp.com\/helps\/91997.html","name":"KMP \u5168\u6808\u5f00\u53d1\uff1a\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-08-08T14:17:06+00:00","dateModified":"2026-08-08T14:17:06+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/91997.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/91997.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/91997.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"KMP \u5168\u6808\u5f00\u53d1\uff1a\u7528 Koog \u6846\u67b6\u6784\u5efa\u539f\u751f AI Agent"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/91997","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=91997"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/91997\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media\/91996"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=91997"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=91997"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=91997"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=91997"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}