Google ADK Kotlin 智能体开发实战:工具、会话与多Agent编排
1. 为什么 ADK 要专门支持 Kotlin先搞清楚这东西到底解决什么问题Kotlin 后端圈子里最近有件挺值得琢磨的事——Google 把自家的 Agent Development KitADK搬到了 JVM 生态上而 Kotlin 因为和 Java 的无缝互操作等于直接拿到了这套 AI Agent 框架的入场券。很多人第一反应是又一个套壳 SDK但我实际翻了一遍它的结构之后发现它想解决的问题和之前的那些轻量封装完全不是一个量级。它不是在教你怎么调一次模型接口而是在给一个能自己规划、能调工具、能记住上下文、能多轮协作的智能体提供一套标准骨架。这件事对写 Kotlin 的人来说意义不小因为过去我们想在 JVM 上搭一套像样的 Agent 流程基本只能自己拼装 HTTP 客户端、自己设计会话状态、自己写工具调用的解析逻辑一通下来代码量惊人且难以维护。ADK 出现的价值就在这儿它把 AI Agent 拆成了几个明确的构件——模型、指令、工具、会话、记忆、运行器然后给每个构件定义好接口和生命周期。你写 Kotlin 的时候只需要关心我的业务逻辑是什么而不用再操心这段对话的状态存在哪工具调用的参数怎么校验多轮之间怎么传递上下文这些脏活。适合谁来学我的判断是三类人一是已经在做 Android 或者后端服务、想往 AI 能力上延伸的 Kotlin 开发者二是手里有一堆内部 API想把这些 API 变成模型能调用的工具的人三是想搞清楚Agent 到底是怎么跑起来的、不想只停留在提示词层面的学习者。1.1 ADK 和手搓一个 Agent的本质区别在哪先说清楚一个概念很多人会把调用大模型 API和构建 Agent混为一谈。调 API 是你发一段文字、它回一段文字一次性的、无状态的而 Agent 的核心在于它能自己决定下一步做什么。这个决定从哪来来自模型看到当前上下文后判断需要调用哪个工具、传什么参数、拿到结果后再决定是继续调工具还是给用户答复。这一整套循环就是一个 Agent 的最小运行逻辑。手搓这套循环最麻烦的地方在于工具调用的编排。你得把工具的描述转成模型能理解的格式通常是 JSON Schema拿到模型的 function call 响应后解析参数调用本地函数再把结果按特定格式回灌给模型同时还要处理模型可能连续调用多个工具、可能调用失败、可能传错参数补全等一堆边界情况。ADK 把这些全部封装进了Runner和FunctionTool两层抽象里工具只需要声明名字、描述和参数结构运行器负责整条链路。我个人的体会是这套抽象省下来的不是几十行代码而是让你少踩一大堆状态管理上的坑。1.2 Kotlin 在这套体系里的位置比你想的更靠前有人会问ADK 官方主打的是 JavaKotlin 用起来会不会处处别扭实测下来完全不会原因有两个。第一Kotlin 与 Java 是 100% 双向互操作Java 的框架 Kotlin 可以直接消费反过来也一样。第二Kotlin 本身的几个特性恰好特别适合写 Agent 代码data class天然适合定义工具的参数和返回值协程coroutine处理流式响应比 Java 的响应式流写起来更顺手扩展函数可以给框架的基类加一些符合业务习惯的语法糖。我举个具体的感受——ADK 里模型输出是流式的Java 侧用的是响应式流Kotlin 里你可以用协程的Flow把它包一层然后写起来就是runner.runAsync(...).asFlow()这种干净的样子。所以别被官方是 Java 版这句话劝退Kotlin 在这儿不但能用而且写起来更舒服。1.3 这套东西的能力边界提前说清楚免得踩空在动手之前得有个清醒的预期。ADK 是框架不是模型它本身不提供任何推理能力你得接一个模型后端官方默认对接的是 Gemini 系列同时通过适配层也能桥接其他兼容接口的模型。它也不负责帮你做数据存储会话状态的持久化、记忆的落盘框架给的是接口和几种现成实现真上生产还是得你自己替换成合适的外部存储。还有就是工具的安全性——框架会老老实实按模型的意图去调用你注册的工具如果工具本身能删数据、能发请求那出问题的责任在你自己这边。把这三条记在心里后面看代码就不会有落差。2. 环境准备与项目骨架版本选择背后的坑动手搭环境这一步看似简单其实是新手翻车最多的地方。ADK 是跑在 JVM 上的框架对 JDK 版本、构建工具、依赖坐标都有要求而 Kotlin 项目通常又叠加了 Gradle 的 Kotlin DSL几个版本之间只要有一个对不齐编译就会报一堆看不懂的错。我把自己搭环境和后面帮别人排错的经历整理一遍尽量让你少走弯路。2.1 JDK 和 Kotlin 版本怎么选才不折腾ADK 的 Java 实现基于较新的语言特性稳妥的起点是 JDK 17 及以上。我建议直接用 JDK 21它是长期支持版本和 Kotlin 的兼容性也最好。Kotlin 版本这边建议用 1.9 之后的稳定版因为它对 Java 的互操作支持在持续打磨尤其是涉及泛型和函数式接口的地方版本太老会遇到类型推断的奇怪问题。构建工具我强烈建议用 Gradle 配合 Kotlin DSL原因很实在ADK 的依赖树里带着响应式流、JSON 解析、HTTP 客户端等好几层传递依赖Gradle 的依赖解析和冲突处理比 Maven 更透明出问题时dependencies任务一跑冲突一目了然。用 Maven 也不是不行但排查依赖冲突的时候你会想念 Gradle。提示不要一上来就去追最新版本号。框架和它的传递依赖之间耦合比较紧最新的未必和你的 Kotlin 版本对得上。先用官方文档里写的推荐版本跑通确认能跑再考虑升级。2.2 依赖引入与第一个能跑的 Agent项目初始化完之后核心就是加依赖。ADK 的 Maven 坐标大致长这样具体版本号以官方仓库当前最新为准// build.gradle.kts dependencies { implementation(com.google.adk:google-adk:0.2.0) implementation(io.reactivex.rxjava3:rxjava:3.1.8) implementation(org.jetbrains.kotlinx:kotlinx-coroutines-rx3:1.8.0) }那个kotlinx-coroutines-rx3是干嘛的就是前面提到的桥接层它让响应式流和协程能互相转换。加上它之后你写流式处理就不用再和Flowable的订阅回调打交道了。第一个能跑的 Agent 我建议从最简单的纯对话开始先不挂任何工具就验证模型能通、会话能建、输出能拿到。核心代码大致是这样val agent LlmAgent.builder() .name(hello_agent) .model(gemini-2.0-flash) .description(一个最基础的对话智能体) .instruction(你是一个说话简洁的助手回答控制在三句话以内。) .build() val runner InMemoryRunner(agent) val session runner.sessionService() .createSession(demo_app, user_001) .blockingGet() runner.runAsync(user_001, session.id(), Content.fromParts(Part.fromText(你好))) .asFlow() .collect { event - event.content()?.parts()?.forEach { part - part.text()?.let { print(it) } } }这段代码里几个点值得单独说。LlmAgent.builder()是链式构建器模式这是 Java 框架的典型写法Kotlin 用起来也不别扭。instruction相当于系统提示词是给模型定人设和行为规范的地方这个字段的写法直接决定了 Agent 的输出质量后面我会专门展开。InMemoryRunner是内存版运行器会话状态存在进程内存里重启就没了只适合开发调试。2.3 目录结构上的一个约定ADK 对目录结构没有硬性要求但我建议把三块东西分开agents放 Agent 的定义tools放各种工具类runner或者service放启动和会话管理逻辑。这么分不是为了好看而是因为 Agent 项目一旦长大工具数量会快速膨胀混在一起之后你很难分清哪些工具属于哪个 Agent。我见过一个项目把二十多个工具全塞在一个文件里后来要改一个工具的说明都找不到地方非常痛苦。另外配置项别硬编码在代码里。API 密钥、模型名称、区域配置这些全部走环境变量或者外部配置文件Kotlin 里读环境变量就是System.getenv(XXX)。把密钥写进源码然后提交这个失误的后果不用我多说。3. 核心概念拆解Agent、Tool、Session、Memory 四件套掌握了环境搭建接下来得把 ADK 的几个核心概念吃透。这四样东西构成了一个 Agent 的骨架理解它们之间的关系比死记 API 重要得多。我会用生活化的类比来解释再落到 Kotlin 代码上尽量让你既知道是什么也知道为什么要这么设计。3.1 LlmAgent把提示词 模型 工具打包成一个对象LlmAgent是整个框架的核心类你可以把它理解成一个员工档案它规定了这个人是谁name、用什么大脑思考model、该遵守什么工作规范instruction、有哪些权限可以调用的工具tools、以及把这个员工交给谁管理subAgents多 Agent 场景用。这里我想重点说instruction因为它是新手最容易写坏的地方。很多人的指令写得像产品需求文档又长又啰嗦结果模型反而抓不住重点。我实践下来的经验是指令要短、要有明确的角色、要有输出格式约定、要有边界。比如一个客服 Agent 的指令好的写法是你是XX产品的客服助手。只回答和产品使用相关的问题其他问题礼貌拒答并建议联系人工。回答不超过 200 字。——角色、边界、格式三样齐了。而坏的写法是堆一大段公司介绍和客套话模型反而不知道该干嘛。model字段填的是模型标识不同后端标识不同。这里有个细节模型选择不是越强越好而要看任务复杂度 vs 成本 vs 延迟的三角平衡。简单意图识别用轻量模型就够复杂推理再用强模型这个思路后面性能章节我还会展开。3.2 工具的定义一个 Kotlin 函数怎么变成模型能调的能力工具Tool是 Agent 真正干活的手。在 ADK 里定义工具本质上是把你的函数描述给模型看让模型知道这个函数叫什么、能干什么、要传什么参数然后由框架负责在合适的时机调用它。ADK 提供了函数式工具的方式大致是通过注解把方法暴露出去。一个查天气的工具写起来像这样class WeatherTool : FunctionTool() { override fun name() get_weather override fun description() 查询指定城市的实时天气。当用户询问天气、气温、是否下雨时调用。 Schema(description 城市名称使用中文例如杭州) fun getWeather(city: String): MapString, Any { // 真实场景这里去调用你的气象数据源 return mapOf( city to city, temperature to 24, condition to 多云转晴, humidity to 62 ) } }这里有几个关键细节都是踩过坑才知道的。第一description不是写给人看的是写给模型看的它决定了模型什么时候会想到调用这个工具所以描述里要写清楚触发场景比如上面我专门加了当用户询问天气时调用。第二参数说明同样重要Schema里的描述会影响模型传参的准确率参数含义模糊的时候模型经常传错。第三返回值我用了Map而不是自定义对象因为这个结果会被序列化后交给模型阅读结构越简单模型理解得越准。注意工具的描述文字会占用上下文长度。如果你的工具很多每个都写一大段描述token 消耗会非常可观模型的注意力也会被稀释。描述要精准但不冗长。再补充一个设计上的原则一个工具只做一件事不要写万能工具。我见过有人把增删改查塞进一个工具里靠参数区分结果模型经常搞不清该传哪个操作值调用错误率很高。拆成独立的工具虽然数量多了但每个的成功率高得多。3.3 Session 和 State多轮对话的状态到底存在哪这是很多人第一次用 Agent 框架会困惑的地方。大模型 API 本身是无状态的每次请求都得把完整历史带上而Session就是帮你管理这次对话的完整上下文的对象。它包含两样东西一个是事件历史用户说了什么、模型回了什么、调了哪些工具一个是状态字典你可以往里塞任何想跨轮次共享的数据。SessionService负责会话的创建、读取和持久化。框架自带内存实现适合开发生产环境下你得换成基于数据库或者缓存服务的实现因为多实例部署的时候内存会话根本没法共享。这是我强烈建议早点规划的一点——很多项目最早图省事用内存会话等要上线了才发现多副本之间状态对不上那时候改起来牵动的地方特别多。State的用法很灵活。比如你可以在状态里存一个用户等级然后每次对话开始前读出来动态调整模型的行为。它的作用是把那些不该让模型自己记、但需要跨轮次保持一致的信息固定下来。session.state()[user_tier] premium session.state()[preferred_language] zh-CN这里要提醒一个概念上的区分State是给当前这次会话用的不是长期记忆。会话结束它就没了。如果你要的是这个用户上次聊过什么、有什么偏好这种跨会话来记住的信息那要用的是下一节的 Memory。3.4 Memory 与回调长期记忆和流程钩子Memory解决的是跨会话的记忆问题。它把历史对话提炼成可检索的内容下次用户来的时候可以按相似度召回相关片段塞进上下文。这个机制的实现细节框架给了接口具体用向量库还是关键词检索取决于你接的后端。我的经验是记忆功能不要一上来就开先把无记忆的闭环跑通再逐步引入否则一旦回答出问题你很难判断是模型的问题、工具的问题还是召回内容的问题。回调Callback是另一个实用工具。它允许你在 Agent 执行流程的特定节点插入自己的逻辑比如每次模型调用前打日志、每次工具调用后做审计、出错时做兜底。这几个钩子在生产环境里特别重要因为 Agent 的行为天然带有不确定性你得有地方能观测它、约束它。框架提供了模型前、模型后、工具前、工具后等几个回调点用起来就是把函数注册进去具体签名以官方文档为准。我个人特别看重工具调用前的回调因为你可以在这里做参数校验和权限判断——模型传的参数不一定靠谱在真正执行前拦一道能避免很多意外。4. 完整实操从零写一个能查天气、能记账的 Kotlin Agent纸上谈兵到这儿够了我们从头搭一个稍微像样点的东西一个个人助理 Agent能查天气、能记账、能按日期查账。这个例子虽小但把工具定义、多工具路由、会话状态、流式输出全串起来了你可以直接拿来改。下面我按需求拆解 → 工具实现 → 组装 → 运行的顺序走一遍。4.1 需求拆解与工具划分先想清楚要哪些能力。查天气是一个工具记一笔账是另一个工具按日期查询账目是第三个。这里有个设计细节值得讲记账的时候要记日期、金额、类别、备注查询的时候按日期范围查。要不要把查询和统计合成一个工具我倾向于分开因为统计逻辑复杂、参数不同混在一起模型的传参准确率会下降。工具清单如下工具名作用关键参数触发场景get_weather查实时天气city用户问天气、气温add_expense记录一笔支出amount, category, note用户说记一笔花了多少query_expense按日期查支出startDate, endDate用户问某天花了多少4.2 工具函数的 Kotlin 实现记账工具我用内存列表模拟存储实际项目里换成数据库即可。这里重点是感受一下参数定义的写法。class ExpenseRepository { private val records mutableListOfExpense() fun add(e: Expense) { records.add(e) } fun query(start: String, end: String): ListExpense records.filter { it.date start it.date end } } data class Expense( val date: String, val amount: Double, val category: String, val note: String ) class AddExpenseTool(private val repo: ExpenseRepository) : FunctionTool() { override fun name() add_expense override fun description() 记录一笔支出。当用户说记一笔、花了多少钱、消费了时调用。 Schema(description 金额单位元正数) fun addExpense( Schema(description 支出类别如餐饮、交通、购物) category: String, Schema(description 金额单位元) amount: Double, Schema(description 备注说明) note: String, Schema(description 日期格式 yyyy-MM-dd默认今天) date: String ): MapString, Any { if (amount 0) return mapOf(success to false, msg to 金额必须为正数) repo.add(Expense(date, amount, category, note)) return mapOf(success to true, msg to 已记录$category $amount 元) } }这里我特意在函数里加了一个金额校验。为什么因为模型传参不一定永远正确与其让它把一条错误数据写进库里不如在工具层面挡掉返回一个失败的结果让模型去跟用户澄清。这个工具层做防御的思路是我做 Agent 项目时反复强调的一点——永远不要假设模型的输入是对的。4.3 组装 Agent 与 Runner工具齐了之后把它们挂到 Agent 上再接上运行器。val expenseRepo ExpenseRepository() val assistant LlmAgent.builder() .name(personal_assistant) .model(gemini-2.0-flash) .description(个人生活助理能查天气和管理日常支出) .instruction( 你是一个个人助理。根据用户意图选择合适的工具。 规则 1. 记录支出前如果用户没说类别先追问类别不要瞎猜。 2. 查询支出时若用户没给日期范围默认查询今天。 3. 涉及金额一律用阿拉伯数字保留两位小数。 4. 回答简洁不要重复用户的话。 .trimIndent() ) .tools( WeatherTool(), AddExpenseTool(expenseRepo), QueryExpenseTool(expenseRepo) ) .build() val runner InMemoryRunner(assistant)注意instruction里那几条规则。这里的第二条没说日期默认查今天和第一条没说类别要追问其实是在用自然语言给 Agent 定行为边界。这类规则的写法很讲究能明确说清的就说清模糊的交给模型判断。我试过把每条规则都写得无比细致结果模型反而变得死板遇到稍微变化的说法就不知道怎么处理了。指令的粒度需要反复调没有标准答案。4.4 流式输出与多轮交互最后是驱动它跑起来。流式输出对体验影响很大尤其是回答较长的时候等待整段生成完再显示会让人觉得很卡。suspend fun chat(runner: InMemoryRunner, userId: String, sessionId: String, text: String) { runner.runAsync(userId, sessionId, Content.fromParts(Part.fromText(text))) .asFlow() .collect { event - event.content()?.parts()?.forEach { part - part.text()?.let { print(it) } } } println() }多轮交互的关键在于复用同一个sessionId。每次调用都传同一个会话 ID框架就会自动把这一轮追加到历史里模型下一轮就能看到之前说过什么。如果每轮都新建会话那每次对话都是失忆的这个坑我踩过当时排查了半天才发现是会话 ID 没复用。实操心得调试的时候把每轮收到的完整 event 打出来包括模型的思考过程、工具调用的参数和返回值。很多模型答非所问的问题看一眼工具实际收到的参数就明白了比反复改指令有效得多。5. 多 Agent 协作与工作流编排把复杂任务拆开单个 Agent 能应付的场景有限。任务一复杂一个 Agent 挂十几个工具模型的判断准确率就会明显下滑——工具越多选错的概率越大。这时候正确的做法是拆成多个专职 Agent让它们各管一摊再通过编排组合起来。ADK 在这方面提供了几种现成的范式理解它们的适用场景比会用更重要。5.1 顺序、并行、循环三种基础编排顺序执行的意思很直白前一个 Agent 的输出作为后一个的输入像流水线一样。典型场景是信息收集 → 分析 → 生成报告这种有明确先后依赖的流程。ADK 里通过SequentialAgent之类的组合器把子 Agent 串起来每个子 Agent 通过共享的会话状态传递数据。并行执行是几个 Agent 同时干活最后汇总结果。适合互相独立的子任务比如同时查天气、查日历、查交通然后合成一个出行建议。它的好处是省时间坏处是得处理结果汇总的逻辑不能让几个 Agent 的输出互相打架。循环执行是让一个 Agent 反复跑直到满足某个条件或者跑固定的轮数。适合审稿-修改-再审这类需要迭代打磨的任务。这里要特别注意设置最大轮数上限否则一旦条件永远不满足就会陷入死循环烧掉大量额度。我给所有循环都设一个硬上限宁可提前退出也不放任它转。5.2 LLM 驱动的动态路由比固定编排更灵活的是让模型来决定走哪条路。做法是设一个调度 Agent把可选的子 Agent 作为它的下级用户请求进来后由调度 Agent 判断该交给谁。举个例子一个客服系统下有售前咨询售后维修账单查询三个子 Agent用户问的问题由调度层判断归谁管。这种方式的优点是能处理开放式输入用户不用按固定格式提问缺点是调度判断本身也会出错而且多了一层模型调用延迟和成本都会增加。我的经验是子 Agent 的description在这个场景里格外关键调度 Agent 主要靠这些描述来做判断所以每个子 Agent 的描述要写得互斥、清晰别出现两个 Agent 的描述都很像的情况。编排方式适用场景主要风险顺序有明确先后依赖的流水线中间环节失败会卡住整条链并行子任务互相独立结果汇总逻辑复杂循环需要迭代打磨的任务不设上限会死循环LLM 路由开放式输入、多种意图调度误判、额外延迟成本5.3 人工确认环节什么时候必须让人介入有些操作不能全交给模型自动执行比如涉及付款、删除数据、发送对外消息。ADK 支持在工具调用前插入人工确认的环节让流程暂停等人拍板。实现方式通常是在工具执行前抛出一个需要确认的信号由外层应用捕获后展示给用户用户确认了再继续。这个机制看着简单但在实际业务里非常关键。我参与过一个自动化审批的项目起初所有操作全自动结果模型把一批本来该人工复核的申请直接通过了。后来加了确认环节高风险操作必须人工点一下问题就解决了。判断标准我一般这么做只读操作全自动写操作按风险分级涉及资金和对外的必须确认。6. 常见问题与排查技巧实录这部分是纯实战经验都是我自己和身边人踩过的坑。Agent 项目的报错往往不那么直观因为出错的可能不是代码而是模型的行为。下面按问题类型整理附上排查路径。6.1 依赖冲突与版本对不齐最常见的就是编译期或运行期的类找不到、方法签名不匹配。这类问题九成是依赖版本冲突。排查方法先跑./gradlew dependencies找到 ADK 及其传递依赖的版本看有没有同一个库出现多个版本。如果有用resolutionStrategy强制统一。还有一个隐蔽的坑是 Kotlin 版本和 Java 目标版本不匹配。症状是编译能过但运行时报NoSuchMethodError。解决办法是明确设置jvmTarget和 Java 兼容版本别让它们各自为政。6.2 工具调用失败的排查路径模型该调工具却没调或者调了但参数不对这是最高频的问题。我总结的排查顺序是这样的第一看工具的description是不是太模糊模型没意识到该调用它第二看参数名和描述是否清晰模型传参错多半是这里的问题第三看是不是工具太多导致模型选择困难试着拆分成多个 Agent第四把模型返回的原始响应打出来看它到底有没有生成工具调用请求。避坑技巧给工具名起名要有区分度。我见过两个工具叫query和search模型经常搞混。改成query_expense_by_date和search_weather_by_city之后准确率立刻上去了。6.3 上下文超限与 token 控制多轮对话跑久了会撞上模型的上下文长度上限。症状是对话到一定轮次后突然报错或者模型开始忘事。应对方法有几个层次最直接的是精简历史只保留最近 N 轮更进一步是对早期对话做摘要把摘要而不是原文放进上下文再进一步是接入记忆检索只召回和当前问题相关的片段。我一般先用最简单的截断如果业务确实需要长期记忆再上摘要和检索。要提醒的是工具的定义和描述本身也占上下文。工具一多光描述就吃掉一大块额度。所以工具设计上要克制不常用的工具别一股脑全挂上。6.4 常见问题速查表现象可能原因处理方向编译报错找不到类依赖版本冲突检查依赖树统一版本运行时报方法不存在Kotlin 与 Java 目标版本不匹配对齐 jvmTarget 和兼容版本模型不调用工具工具描述模糊或工具太多优化描述拆分 Agent工具参数传错参数说明不清晰完善参数描述加类型约束对话久了报错上下文超限截断历史或做摘要多实例状态不一致用了内存会话换成外部持久化会话循环停不下来没设最大轮数加硬上限回答风格飘忽指令不够明确补充角色和格式约束6.5 几条花钱买来的经验最后说几条不太好归类但很值钱的经验。第一永远先在开发环境用小额度跑通完整闭环再去连真实业务系统因为 Agent 的不确定性意味着它可能以你意想不到的方式调用工具。第二给所有会写数据的工具加校验和幂等模型重复调用同一个工具的情况比你想的常见。第三日志要打全尤其是每次工具调用的入参和出参出了问题这些日志就是唯一的线索。第四成本和延迟要尽早监控Agent 的多轮循环很容易在你不注意的时候把额度吃掉。7. 部署与工程化的几句实话把 Demo 跑通和上线是两码事。部署这块我踩过的坑主要集中三点。会话存储必须外部化前面反复提过内存会话在多实例下必挂。可观测性必须跟上Agent 的行为不像传统程序那样确定你得能看到它每一步在干什么日志、链路追踪、每次模型调用和工具调用的记录一个都不能少。成本控制要有手段设置超时、限制最大轮数、对高频操作做缓存这些都是常规操作。关于模型选择我的建议是分级使用。简单的意图识别用轻量模型复杂的推理和生成用强模型这样能明显压成本。ADK 支持在 Agent 层面指定模型也可以在多 Agent 场景下给不同的子 Agent 配不同模型这个灵活度要用起来。至于从哪个方向继续深入我个人的路径是先把单 Agent 加工具这块彻底吃透包括错误处理、状态管理、安全边界再往多 Agent 编排走最后才是记忆和检索这些进阶能力。贪多嚼不烂Agent 这东西每加一层复杂度排查难度都是翻倍的。我在实际使用中的体会是ADK 这类框架的价值不在于它帮你省了多少行代码而在于它把 Agent 的各个组成部分规范化了让不同人写出来的东西有共同的骨架可循。真正决定项目成败的还是你对业务的理解、对边界的把控以及对模型可能会犯错这件事的敬畏。工具调用前的校验多做一道生产环境里就能少一次事故。

相关新闻

CANN ops-math 源码构建完全指南:自定义算子包、ops-math 包与静态库的编译、安装与验证

CANN ops-math 源码构建完全指南:自定义算子包、ops-math 包与静态库的编译、安装与验证

CANN ops-math 源码构建完全指南:自定义算子包、ops-math 包与静态库的编译、安装与验证 【免费下载链接】ops-math 本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-math 本指南系统…

2026/9/19 6:50:02 阅读更多 →
Win11下CH340串口驱动识别失败排查与稳定性加固指南

Win11下CH340串口驱动识别失败排查与稳定性加固指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/19 6:50:02 阅读更多 →
graph-autofusion V2 节点性能建模实战:基于 af-perf-modeler 的 Cast/Reduce/Compare 算子性能公式推导指南

graph-autofusion V2 节点性能建模实战:基于 af-perf-modeler 的 Cast/Reduce/Compare 算子性能公式推导指南

graph-autofusion V2 节点性能建模实战:基于 af-perf-modeler 的 Cast/Reduce/Compare 算子性能公式推导指南 【免费下载链接】graph-autofusion Graph-autofusion 是一个面向昇腾(Ascend)芯片的轻量级、解耦式组件集合,旨在通过自…

2026/9/19 6:50:02 阅读更多 →

最新新闻

连锁超市进销存系统设计:UML建模与数据库账实一致实践

连锁超市进销存系统设计:UML建模与数据库账实一致实践

简介:面向连锁超市进销存管理场景的信息系统分析与设计课程设计报告,适合计算机、信息管理相关专业学生作为课程设计或毕业设计的参考资料。内容覆盖系统背景、可行性分析、系统分析与设计、系统实施测试全流程,结构完整,具有较强…

2026/9/19 7:36:25 阅读更多 →
OpenCore Legacy Patcher:把 2007 年起的老旧 Intel Mac 推进 macOS Sequoia 15 的引导补丁工具

OpenCore Legacy Patcher:把 2007 年起的老旧 Intel Mac 推进 macOS Sequoia 15 的引导补丁工具

OpenCore Legacy Patcher:把 2007 年起的老旧 Intel Mac 推进 macOS Sequoia 15 的引导补丁工具 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 一…

2026/9/19 7:36:25 阅读更多 →
AssetRipper:3 步跑通的 Unity 资源提取器,免费开源

AssetRipper:3 步跑通的 Unity 资源提取器,免费开源

AssetRipper:3 步跑通的 Unity 资源提取器,免费开源 【免费下载链接】AssetRipper GUI application to analyze game files 项目地址: https://gitcode.com/GitHub_Trending/as/AssetRipper AssetRipper 是一款免费开源的 Unity 资源提取工具。它…

2026/9/19 7:36:25 阅读更多 →
XGBoost R 包开发指南:如何将核心库新参数同步到 xgb.params 与 xgboost

XGBoost R 包开发指南:如何将核心库新参数同步到 xgb.params 与 xgboost

XGBoost R 包开发指南:如何将核心库新参数同步到 xgb.params 与 xgboost 【免费下载链接】xgboost Scalable, Portable and Distributed Gradient Boosting (GBDT, GBRT or GBM) Library, for Python, R, Java, Scala, C and more. Runs on single machine, Hadoop,…

2026/9/19 7:36:25 阅读更多 →
Umi-OCR 离线文字识别保姆级上手指南:10分钟跑通截图、批量与PDF识别

Umi-OCR 离线文字识别保姆级上手指南:10分钟跑通截图、批量与PDF识别

Umi-OCR 离线文字识别保姆级上手指南:10分钟跑通截图、批量与PDF识别 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码…

2026/9/19 7:36:25 阅读更多 →
从App到Agent:智能服务架构的技术演进与实践

从App到Agent:智能服务架构的技术演进与实践

1. 从App到Agent的技术范式转移最近两年,我观察到行业里一个有趣的现象:传统App开发的热度正在消退,而基于Agent的智能化服务架构正在快速崛起。这种转变不是简单的技术迭代,而是一次根本性的范式转移。就像当年从桌面软件转向移动…

2026/9/19 7:35:25 阅读更多 →

日新闻

BP神经网络时序预测:滑窗长度与多窗口平均策略

BP神经网络时序预测:滑窗长度与多窗口平均策略

简介:面向机器学习、深度学习与数据建模学习者的一份完整研究文献,聚焦BP神经网络在农业产量预测中的应用。文档以1980—2018年全国棉花产量为样本,系统讲解数据归一化处理、激活函数原理、多层神经网络结构搭建及训练流程,展示敏…

2026/9/19 0:00:30 阅读更多 →
Transformer训练实时监控实战:基于MindSpore的损失曲线可视化方案

Transformer训练实时监控实战:基于MindSpore的损失曲线可视化方案

上个月调一个Deformable DETR模型,在单卡上要跑将近两天。第二天早上我下意识打开终端翻日志,发现loss从凌晨两点就开始往上爬,一路从0.8涨到1.35,整整六个小时没人发现。那六个小时的训练不仅白跑,还霸占着卡——等于…

2026/9/19 0:00:30 阅读更多 →
OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南

OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南

OpenCloud 中的 Go 类型安全转换库 spf13/cast:从零值回退到泛型 API 的完整实战指南 【免费下载链接】opencloud 🌤️ OpenCloud is the open source platform for file management, sharing and collaboration. Simple and sovereign. 项目地址: htt…

2026/9/19 0:00:30 阅读更多 →

周新闻

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and ag…

2026/9/19 3:59:36 阅读更多 →
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitH…

2026/9/19 3:53:08 阅读更多 →
Flutter应用改名全指南:从Android到iOS的配置与工具实践

Flutter应用改名全指南:从Android到iOS的配置与工具实践

刚接一个外包项目时,甲方要求把工程里临时用的应用名改成正式产品名。我本来觉得“改名”这种小事,打开配置文件改一行不就完了?结果真动手才发现,Flutter项目里“应用名称”根本不是一处配置,而是一整套散落在 Androi…

2026/9/19 4:02:43 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/16 22:31:27 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/15 21:39:18 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/16 22:32:59 阅读更多 →