十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Spring 创始人的 Agent 框架Embabel,为什么不让大模型决定每一步?

Spring 创始人的 Agent 框架Embabel,为什么不让大模型决定每一步? Spring 创始人的 Agent 框架为什么不让大模型决定每一步事实边界说明文中“近期变化”按本地源码main分支的0f6073a04..10d5dde8e区间核实62 个提交、316 个文件、约 2.1 万行新增最新稳定 tag 是v1.5.1当前main已进入1.5.2-SNAPSHOT。main上的能力不等于v1.5.1已发布的能力文中会分开表述。先解释标题避免误读Embabel 并不排除大模型。它要做的是把“下一步调用哪个 action”这个决定从模型的临场判断里拿出来至于 action 内部怎么做内容生成LLM 依然是主力。一、为什么现在重新看 Embabel8 月 7 日我把 Embabel 的源码同步到本地停在0f6073a04当时还是1.5.0-SNAPSHOT。三周后的 8 月 28 日再快进已经到了10d5dde8e中间 62 个提交改动 316 个文件新增约 2.1 万行代码。期间发布了v1.5.0和v1.5.1两个稳定版当前main已经进入1.5.2-SNAPSHOT。再往前看一个数字v1.0.0的 tag commit 日期是 7 月 19 日v1.5.1是 8 月 24 日——两个稳定版本点之间只隔了约 36 天。如果只看标签很容易把 Embabel 概括成“Rod Johnson 做的 JVM GOAP 框架”。但这 62 个提交里最能说明项目方向的并不是又换了一套规划算法而是这些工程能力模型角色解析独立成RoleResolverSPI并增加运行时模型选择上下文BYOK自带密钥从单纯传入 Key扩展到 LLM、Embedding、角色与凭证端点RAG 增加按章节读取、相邻块扩展、过滤与检索分数修正Skills 可以通过 embedding 按语义选择OpenAI Responses API、流式能力探测、限流识别、重试与空响应恢复持续补强基线升级到 Spring Boot 4.1.1 与 Spring AI 2.0.1。一个以“规划”为卖点的框架为什么最近花了这么多力气处理模型凭证、知识检索、技能选择和失败恢复我的回答是因为规划器只能决定下一步应该调用哪个 action要让 action 在真实系统里可靠执行模型、知识、工具和运行上下文都必须成为可管理的能力。这 62 个提交就是在补这块地基。二、Embabel 到底改变了什么对 Java 与 Spring 团队来说Embabel 真正的新意不在“可以调用很多模型和工具”——这件事每个框架都在做。它提供了第三种流程控制方式不是由开发者预先画死所有边固定工作流也不是把每一步都交给 LLM 在 ReAct 循环里临场选择而是由开发者声明 action、输入、产出、条件、目标与成本再由规划器依据当前状态计算下一步。用一个假设的“订单售后”场景来说明。售后处理有几种可能路径金额小、风险低的订单可以自动退款金额大或命中风控的要转人工审批信息不足的还要先补齐材料。传统写法是一棵 if-else 树或者一张画死的流程图ReAct 写法是把订单扔给 LLM让它自己决定调哪个工具。Embabel 的写法是声明式的// AfterSalesAgent.javaAgent(description订单售后处理,version1.0.0)publicclassAfterSalesAgent{Action(description查询订单详情,cost0.1)OrderDetailloadOrder(RefundRequestrequest){returnorderRepository.findDetail(request.orderId());}Action(description风险评估,cost0.2)RiskAssessmentassessRisk(OrderDetailorder,Aiai){returnai.withLlmByRole(cheapest).createObject(评估该订单退款风险: order,RiskAssessment.class);}Condition(namelowRisk)booleanlowRisk(RiskAssessmentrisk){returnrisk.level()RiskLevel.LOWrisk.amount().compareTo(AUTO_REFUND_LIMIT)0;}AchievesGoal(description完成低风险订单自动退款,value0.8)Action(pre{lowRisk},description自动退款,cost0.3)RefundResultautoRefund(OrderDetailorder,RiskAssessmentrisk){returnpaymentClient.refund(order);}AchievesGoal(description高风险订单转人工审批完成售后,value0.6)Action(description转人工审批,cost0.7)ApprovalTicketescalate(OrderDetailorder,RiskAssessmentrisk){returnticketSystem.create(order,risk);}}注意这段代码里没有一行在写“先做什么、后做什么”。loadOrder需要RefundRequest、产出OrderDetailassessRisk需要OrderDetail、产出RiskAssessmentautoRefund除了需要这两个领域对象还要求命名条件lowRisk成立。参数类型表达“执行前需要什么”返回类型表达“执行后得到什么”——规划元数据寄生在类型系统上开发者写的是正常的方法签名框架自动拿到 STRIPS 风格的动作描述。运行时领域对象进入 Blackboard黑板成为规划器每个 tick 看到的当前世界状态。规划器据此生成当前计划只执行计划中的第一个 actionaction 更新黑板后下一 tick 重新规划。如果风险评估出来是低风险路径收敛到autoRefund如果用户中途补充了材料、风险等级变化下一 tick 的计划会跟着变。所以 Embabel 更像导航系统不像一次性生成的行程单它知道目的地、可走的路和当前所在位置每走一步都会重新判断下一段路。三种方式的核心差异维度固定工作流ReActEmbabelPlanner-first路径由谁决定开发者编译期LLM运行时临场规划器按当前状态计算路径可见性完全可见事后从历史重建每个 tick 可见当轮计划成本模型静态可知未知轮数不定cost/value 参与寻优适应变化改代码模型自己适应也可能跑偏下一 tick 自动重规划可达性检查靠人审运行时才发现死路启动期即可校验三、它为什么不是一张“会自动生成的流程图”这是最容易产生的误解需要单独说清。第一“由规划器决定下一步”不等于整个执行过程确定。规划确定的是 action 的选择与顺序action 内部如果调了 LLM比如上面的assessRisk输出仍然是概率性的。Embabel 不是“确定性 Agent 框架”同样输入不保证同样路径——黑板状态、成本计算、模型输出任何一项变化都可能让下一 tick 的计划不同。第二“每 tick 重规划”不等于启动时算出完整路径然后执行到底。SimpleAgentProcess每轮都基于当前世界状态重新求计划只执行第一个 action。这是正常运行方式不是异常兜底。action 或工具如果在本轮就发现路线不再适用还可以抛ReplanRequestedException显式请求重规划。第三GOAP 是默认规划器不是唯一规划器。稳定版的PlannerType枚举包含 GOAP、UTILITY、HYBRID、SUPERVISOR 四种。GOAP 用 A* 在条件状态空间搜索低代价路径Utility 按效用打分选 action。说“Embabel 就是 GOAP/A*”是不准确的。第四Open 模式有明确边界。它允许跨 agent 组合 action但平台依然只执行开发者声明过的步骤——不存在模型现场发明一个新 action 的可能。第五可检查性有边界。Embabel 的事件体系能记录当轮计划、执行历史、LLM 调用留痕规划依据确实比 ReAct 更容易审计但这不等于 action 内部每一次 LLM 判断都可解释也不能仅凭“有事件”就推导出满足某个行业的合规要求。还有一个容易被忽略的红利部署期校验。GoapPathToCompletionValidator在 agent 启动时对每个 goal 验证“从初始条件出发存在至少一条可达路径”。字符串条件拼错比如pre [lowRisk]写成[lowRIsk]导致 goal 不可达启动即报错而不是运行时才卡死。这是“规划可静态分析”的直接兑现。四、最近 62 个提交真正补了什么回到开头的问题。近期最密集的源码变化集中在规划器外围可以归为四条线。模型资源模型不再是一个固定 Bean而是运行时资源。RoleResolver从固定的 role→model 配置中独立出来允许按ModelSelectionContext在运行时解析模型BYOK 增加CredentialEndpoint覆盖 LLM 与 Embedding不再要求应用直接说出底层 SPI 类型PlaceholderLlmService与PlaceholderEmbeddingService让缺少凭证的应用能先启动再在运行时补齐能力。这意味着best、cheapest这类角色不只是配置别名而是在把模型质量、成本、租户凭证和可用性变成运行时决策的一部分。对多租户 SaaS 场景这是刚需不同租户自带不同 Key模型选择必须在请求上下文中完成而不是应用启动时绑死。知识与能力知识和技能也开始进入“选择”体系。SectionReader让 Agent 可以按章节名读取文档而不是只拿孤立的相似块RAG 增加相邻块扩展、metadata/entity filter、文本查询语义说明和 BM25 分数归一化等修正EmbeddingSkillSelector用语义相似度从技能集合中选出候选技能。规划不仅需要知道“有哪些 action”还要控制 action 能看到哪些知识、拿到哪些技能。Embabel 正在把这些能力从提示词堆叠变成可选择、可过滤的运行时资源。运行可靠性真实运行首先会遇到失败而不是漂亮路径。OpenAI 新模型按能力路由到 Responses API并处理不支持的请求参数流式能力探测结果会缓存避免反复探测重试逻辑统一处理限流识别与日志工具循环可对空响应再次提示AgentProcess在线程切换时恢复上下文提示词组装增加性能回归测试。工程基线项目升级到 Spring Boot 4.1.1 与 Spring AI 2.0.1。Embabel 的模型接入底座是 Spring AI——Rod Johnson 那个“Servlet API 之于 Spring MVC”的类比落在代码上就是Embabel 不重新发明模型客户端而是把 Spring AI 的 bean 生态收编为自己的路由池自己负责更上层的规划与运行语义。五、这些变化共同指向什么把这四条线合起来看它们表面上是模型适配、RAG 与容错实质上在回答同一个问题规划器选中了一个 action 之后这个 action 能不能在不同用户、不同模型、不同知识范围和失败条件下真正执行。一个 Planner-first 框架要进入真实应用难点从来不只是“能不能算出下一步”还包括这一步调用哪个模型、凭证从哪里来、知识范围是什么、失败后是否该重试、上下文是否会丢。所以我的判断是近期变化没有削弱 Embabel 的规划器定位反而说明它正在从“有辨识度的规划模型”向“可承载规划模型的 Agent 运行平台”推进。但注意措辞——我说的是“正在推进”不是“已经生产成熟”。源码活跃与工程能力增加都不能替代公开生产案例和长期稳定性证据。据我目前所见Embabel 还没有公开的生产案例。六、我的态度方向值得研究现在仍然观望看到 Rod Johnson、GOAP、连续发布的新版本很容易得出一个结论方向独特、迭代又快应该尽早上车。这个想法的问题在于它把“项目进步快”和“应用可以稳定跟进”混成了一件事。1.0.0之后约 36 天就走到1.5.1当前main又升级了 Spring Boot、Spring AI、模型路由和多项运行机制。对源码研究来说这是活跃对生产团队来说这意味着接口、配置、依赖和迁移说明需要持续重验。此时接入团队承担的不只是学习新框架的成本还有持续跟随变化的迁移成本。同时规划器不会自动理解业务。它能看到的世界取决于开发者是否把领域对象、action 边界、前置条件、效果、目标和成本表达清楚。框架变化快与领域建模成本会叠加成真实的采用门槛。所以我把采用决策拆成两个独立判断方法是否值得研究值得。它把流程判断搬回领域模型与规划器提供了区别于固定工作流和 ReAct 的第三条路线。当前版本是否适合成为默认生产底座我暂时不会这样判断。版本节奏、依赖基线和平台能力仍在快速变化。真正决定采用时机的不是发布速度本身而是关键接口是否稳定、升级成本是否可控、目标业务是否适合领域建模以及团队能否用真实试点验证收益。现阶段适合用来试验的任务目标明确但达成目标存在多条可选路径输入、产出和关键状态能用领域对象表达action 的前置条件与效果相对稳定路径选择需要考虑成本、价值或当前资源团队需要检查“当时为什么选择这个 action”业务链可以与核心系统隔离升级或重写不会造成高迁移成本。现阶段不适合直接承载的任务任务本身是开放式探索下一步无法提前收敛成稳定 action 集合业务条件主要存在于自然语言和个人经验中短期内无法建模流程本来就固定且简单普通代码或状态图已经足够团队只想快速做一个工具调用 Demo不准备维护领域模型与测试需要多年稳定维护、依赖升级窗口严格、框架变更成本很高的核心链路。如果要做试点我建议的最小路径选一条规则清楚、结果可验证的真实业务链只定义 3—5 个 action、1 个 goal 和最少的领域对象固定世界状态断言规划结果与第一个 action而不是断言所有 LLM 文本完全一致再测试一次 action 失败、状态变化后的重规划固定到一个稳定版本记录每次升级需要修改的 API、配置和依赖最后才引入 BYOK、RAG 或 Embedding Skills验证它们是否解决了真实问题。七、结尾Embabel 提出的编程方式值得研究先说清系统处于什么状态、允许做什么、做完会改变什么再让规划器选择下一步。它把 Agent 编排从“写死路径”或“模型猜路径”变成“根据当前状态计算路径”。但在版本与运行底座稳定下来之前我更愿意保持观望持续跟源码、做隔离的小范围试点而不是让核心业务跟着框架一起快速变化。我会继续研究 Embabel因为它提出了一个好问题我不会急着把它用于核心生产因为它自己的答案还在快速变化。数据与版本说明近期变化按本地源码main的0f6073a04..10d5dde8e校验62 个提交316 个文件约 2.1 万行新增最新稳定 tag 为v1.5.1当前main为1.5.2-SNAPSHOT。文中只以正式 release 作为能力基线不把main、Snapshot 或里程碑版本混入稳定版能力。
返回列表