资讯动态

openJiuwen agent-core-java 旧版 LLM 调用兼容层:LLMCall 包装器全面解析

发布时间:2026/10/14 1:59:34 来源:尧图企业网站定制
人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习【免费下载链接】agent-core-javaopenJiuwen agent core Java是 openJiuwen Core的 Java版本提供AI Agent开发、运行、调优与演进相关的全套SDK能力。项目地址https://gitcode.com/openJiuwen/agent-core-java点击查看免费下载LLMCall 是 openJiuwen agent-core-java 在旧版兼容路径上提供的 LLM 调用包装器负责按system history user顺序组装消息、驱动模型推理并在调用完成后触发旧版 optimizer 回调是提示词调优tune链路中可直接绑定优化的参数句柄。本文将以 LLMCall.md 文档为主体结合仓库源码与测试用例完整讲解其构造参数、核心 API、流式聚合机制、回调协议以及与新版LLMCallOperator的差异帮助开发者在迁移到算子化体系前快速接入或复用这一兼容层。一、定位旧版兼容路径上的 LLM 调用包装器LLMCall位于com.openjiuwen.core.operator.legacy.llm_call包对应实现文件为 LLMCall.java。从源码注释可以看到它镜像自 Python 版openjiuwen/core/operator/legacy/llm_call/base.py是 pre-operator 时代的 LLM 调用封装承担两件核心职责消息格式化按照system history user的顺序把PromptTemplate渲染结果、会话历史与用户输入组装成ListBaseMessage再交给底层Model执行推理完成回调在收到完整响应或流式场景聚合完所有 chunk后触发已设置的LegacyOptimizerCallback为提示词调优提供观察与梯度采集入口。需要特别强调的是该兼容类不继承Operator因此不会像新版LLMCallOperator那样把当前算子 ID 写入Session。这意味着它不参与新版自演化算子的 checkpoint 与算子归因体系属于纯调用 回调的轻量封装。二、构造方法详解2.1 全参构造7 参数public LLMCall(String modelName, Model llm, Object systemPrompt, Object userPrompt, boolean freezeSystemPrompt, boolean freezeUserPrompt, String llmCallId)各参数含义与取值规则如下参数说明默认回退行为modelName调用的模型名称写入ModelInvokeOptions.model无llm底层大模型封装com.openjiuwen.core.foundation.llm.Model无systemPrompt系统提示词可为字符串、消息列表或模板内容无userPrompt用户提示词可为字符串、消息列表或模板内容为null、空字符串或空列表时回退到默认模板{{query}}freezeSystemPrompt是否冻结系统提示词false默认不冻结freezeUserPrompt是否冻结用户提示词全参构造由调用方显式传入llmCallId本次调用标识会透传给 optimizer 回调为null时回退为llm_call从源码看构造时会将systemPrompt与userPrompt分别包装为PromptTemplatePromptTemplate.builder().content(...).build()其中默认用户提示词常量为public static final String DEFAULT_USER_PROMPT {{query}};{{query}}是占位符语法在invoke/stream时通过PromptTemplate.format(MapString, Object keywords)渲染query即来自inputs入参中的键。2.2 便捷构造4 参数public LLMCall(String modelName, Model llm, Object systemPrompt, Object userPrompt)等价于使用默认参数调用全参构造this(modelName, llm, systemPrompt, userPrompt, false, true, llm_call);即默认值为freezeSystemPrompt false系统提示词默认不冻结后续updateSystemPrompt()生效freezeUserPrompt true用户提示词默认冻结后续updateUserPrompt()不生效llmCallId llm_call。注意这一默认组合的差异便捷构造下用户提示词被冻结、系统提示词可更新这与LLMCallOperator的默认行为freezeSystemPromptfalse, freezeUserPrompttrue, operatorIdllm_call保持一致。三、核心 API 一览方法返回类型说明invoke(MapString, Object inputs, Object session, ListBaseMessage history, ListToolInfo tools)CompletionStageAssistantMessage格式化 prompt 后调用Model.invoke(...)若设置了LegacyOptimizerCallback收到完整响应后触发回调invoke(MapString, Object inputs, Object session)CompletionStageAssistantMessage不传history/tools的便捷重载内部传nullstream(MapString, Object inputs, Object session, ListBaseMessage history, ListToolInfo tools)IteratorAssistantMessageChunk调用Model.stream(...)流关闭或自然结束时把全部 chunk 聚合为字符串再触发回调stream(MapString, Object inputs, Object session)IteratorAssistantMessageChunk不传history/tools的流式便捷重载getOptimizerCallback()/setOptimizerCallback(LegacyOptimizerCallback)LegacyOptimizerCallback/void读取或设置旧版完成回调getSystemPrompt()/getUserPrompt()PromptTemplate返回当前系统/用户 prompt 模板对象updateSystemPrompt(Object)/updateUserPrompt(Object)void在对应 freeze 开关关闭时替换 prompt 模板setFreezeSystemPrompt(boolean)/setFreezeUserPrompt(boolean)void切换系统/用户 prompt 的冻结状态getFreezeSystemPrompt()/getFreezeUserPrompt()boolean读取当前冻结状态说明文档 API 表中session参数类型标注为Session而当前源码实现为Object session以保持对旧版 Session 与新版会话对象的双向兼容stream实际返回的是内部类LegacyStream实现了IteratorAssistantMessageChunk与AutoCloseable。四、消息组装与 invoke 调用链4.1 消息顺序system history userinvoke的核心逻辑位于源码formatLlmInput(...)LLMCall.javaprivate ListBaseMessage formatLlmInput(MapString, Object inputs, ListBaseMessage history) { ListBaseMessage systemMessages new ArrayList(); for (BaseMessage message : systemPrompt.format(inputs).toMessages()) { systemMessages.add(new SystemMessage(message.getContentAsString(), message.getName())); } ListBaseMessage userMessages userPrompt.format(inputs).toMessages(); ListBaseMessage historyMessages history null ? List.of() : history; ... messages.addAll(systemMessages); messages.addAll(historyMessages); messages.addAll(userMessages); return messages; }组装顺序明确为系统提示词渲染后 → 历史消息 → 用户提示词渲染后。其中系统提示词会统一转换为SystemMessage保留namehistory为null时按空列表处理用户提示词支持字符串、消息列表或带role/content/name的Map列表normalizePromptContent(...)与toMessage(...)负责把这些异构输入归一化为BaseMessagerole缺省按user处理支持system、user及自定义角色。4.2 底层模型调用invoke通过ModelInvokeOptions携带模型名与工具信息调用底层模型private ModelInvokeOptions invokeOptions(ListToolInfo tools) { return ModelInvokeOptions.builder() .model(modelName) .tools(tools null ? null : List.copyOf(tools)) .build(); }随后执行llm.invoke(messages, invokeOptions(tools))返回CompletionStageAssistantMessage。若未设置optimizerCallback直接原样返回该异步结果若已设置则通过response.thenCompose(...)在完整响应到达后执行optimizerCallback.onComplete(llmCallId, safeInputs, message, session);回调异常会通过CompletableFuture.failedFuture(exception)传播而inputs为null时会被safeInputs(...)归一化为空Map。五、流式 stream 与 chunk 聚合机制stream并不直接返回裸迭代器而是返回内部静态类LegacyStream见 LLMCall.java其行为如下逐 chunk 消费next()取出AssistantMessageChunk后将其内容追加到内部StringBuildernullchunk 会追加字符串null自然结束即聚合回调hasNext()返回false或next()后检测到无后续元素时自动调用close()close 触发回调close()内仅执行一次把所有 chunk 聚合为完整字符串调用callback.onComplete(llmCallId, inputs, response.toString(), session);也就是说流式场景下回调收到的response是拼接后的完整字符串而非AssistantMessage对象——这与invoke场景回调收到完整AssistantMessage不同是两类调用方式的重要差异。另外close()中回调若抛出异常会包装为IllegalStateException(Legacy LLMCall stream callback failed, exception)抛出但文档同时说明在兼容路径上消费方如果捕获异常则不影响主流程关闭兜底以AutoCloseable语义保证清理。六、LegacyOptimizerCallback 回调协议回调接口定义于 LegacyOptimizerCallback.java是一个函数式接口FunctionalInterface public interface LegacyOptimizerCallback { void onComplete(String llmCallId, MapString, Object inputs, Object response, Object session) throws Exception; }四个参数的含义参数含义llmCallId本次调用的标识缺省为llm_call用于区分同一批绑定中的多个调用点inputs本次调用的入参Map即 prompt 渲染所需的 keyword 来源response调用结果invoke场景为完整AssistantMessagestream场景为聚合后的字符串session会话对象可用于追溯会话上下文正是通过这个回调旧版调优框架才能把一次 LLM 调用的输入输出记录进优化历史作为后续梯度计算的样本详见下一节。七、实战在提示词调优tune链路中的角色LLMCall是旧版 prompt 调优dev_tools/tune体系的参数载体。相关代码位于core/src/main/java/com/openjiuwen/dev_tools/tune/optimizer/7.1 TextualParameter包裹 LLMCall 的调优参数TextualParameter.java 将LLMCall包装为一个可调优参数内部维护MapString, String gradients按system_prompt/user_prompt分别记录文本梯度并提供getLlmCall()访问底层调用器。7.2 BaseOptimizer回调绑定与梯度采集BaseOptimizer.java 在enter()/aenter()时通过batchSetOptimizerCallback(this::traceCallback)为所有绑定参数的LLMCall统一注入回调traceCallback(...)会把每次调用的llmCallId 输入 输出写入OptimizeHistory供 backward 阶段使用。bindParameter(MapString, LLMCall)负责把命名参数注册进来——这正是LLMCall与调优框架的衔接点。7.3 优化器如何使用 freeze / updateInstructionOptimizer.javadoUpdate()中依据getFreezeSystemPrompt()/getFreezeUserPrompt()三态组合选择只优化 system、只优化 user或通过PROMPT_INSTRUCTION_OPTIMIZE_BOTH_TEMPLATE同时优化两者最终调用llmCall.updateSystemPrompt(...)/llmCall.updateUserPrompt(...)落回模板ExampleOptimizer.javafew-shot 示例优化器同样先读取冻结状态再把精选示例追加到未被冻结的 prompt 上。这解释了 freeze 开关的工程意义被冻结的 prompt 不会进入梯度更新范围从而保护关键指令不被自动改写。7.4 最小接入示意// 构建旧版兼容调用器默认 freezeUserPrompttruellmCallIdllm_call LLMCall llmCall new LLMCall(gpt-4, model, 你是助手, {{query}}); // 注册完成回调也可由 BaseOptimizer.enter() 批量注入 llmCall.setOptimizerCallback((llmCallId, inputs, response, session) - { // invoke 场景response 为 AssistantMessagestream 场景response 为聚合字符串 }); // 触发调用 llmCall.invoke(Map.of(query, hello), session) .toCompletableFuture() .join();八、与新版 LLMCallOperator 的差异对比新版算子位于com.openjiuwen.core.operator.llm_callLLMCallOperator.java 继承自 Operator.java两者核心差异如下维度旧版LLMCalllegacy新版LLMCallOperator继承关系普通类不继承Operator继承Operator是自演化参数句柄算子 ID仅作为llmCallId透传回调不写入 SessiongetOperatorId()参与 Session 当前算子 ID 记录参数暴露通过 freeze 开关 update*Prompt()手动控制getTunables()返回TunableSpecsystem_prompt/user_promptsetParameter()/loadState()支持结构化更新与回滚状态管理无getState()/loadState()支持 checkpoint 快照模型调用内置invoke/stream并触发回调不直接持有模型聚焦参数管理默认值freezeSystemPromptfalse, freezeUserPrompttrue, llmCallIdllm_call同名默认值且默认operatorIdllm_call另外新版包中还提供 LLMCall.java 作为LLMCallOperator的向后兼容别名。旧版LLMCall的价值在于在尚未迁移到算子体系的代码路径上以最小的改动获得提示词封装 完成回调能力。九、测试验证LegacyLLMCallTest仓库测试 LegacyLLMCallTest.java 覆盖了两个关键行为invokeCallsOptimizerCallbackWithoutOperatorContextmock 底层Model返回AssistantMessage(legacy-response)后断言回调收到的response与invoke返回值是同一个AssistantMessage对象会话的getOperatorHistory()为空、getCurrentOperatorId()为null——从测试层面证实该兼容类不写入 Session 算子 IDstreamAggregatesChunksForOptimizerCallbackmock 流返回Hel、lo两个 chunk消费完整迭代后断言回调收到聚合结果Hello——验证了流式场景的 chunk 拼接机制。这两条测试用例可以直接作为使用兼容层时的行为契约参考。十、使用建议与总结何时选用LLMCall当业务代码仍处于 pre-operator 兼容路径、需要快速获得systemhistoryuser 消息组装 LLM 调用 完成回调能力且不需要算子 ID 归因与 checkpoint 时LLMCall是最轻量的选择注意默认冻结差异4 参数便捷构造默认冻结 user prompt若希望调优用户提示词请显式传入freezeUserPromptfalse回调入参形态不同invoke回调收到AssistantMessagestream回调收到聚合字符串消费方需按调用方式区分处理流式异常语义流关闭时回调抛出的异常会被包装抛出兼容路径上的消费方可自行捕获避免影响主流程迁移方向如需接入新版自演化算子的TunableSpec、setParameter、loadState能力应迁移到LLMCallOperator两者共享{{query}}默认模板与同名 freeze 默认值迁移成本较低。总体而言LLMCall是理解 openJiuwen agent-core-java 从裸调用走向算子化自演化的关键过渡组件它保留了旧版回调协议又与新版算子共享一致的默认语义开发者可以据此平稳迁移提示词调优链路。赞分享人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习【免费下载链接】agent-core-javaopenJiuwen agent core Java是 openJiuwen Core的 Java版本提供AI Agent开发、运行、调优与演进相关的全套SDK能力。项目地址https://gitcode.com/openJiuwen/agent-core-java点击查看免费下载相关推荐agent-core-java 旧版 LLM 调用兼容层 llm_call 全解析LLMCall 包装器与 LegacyOptimizerCallback 回调契约agent core java 旧版 LLM 调用兼容层 llm_call 全解析LLMCall 包装器与 LegacyOptimizerCallback 回人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习openJiuwen agent-core-java 旧版算子兼容层解析LLMCall 与 LegacyOptimizerCallback 的定位、原理与实战openJiuwen agent core java 旧版算子兼容层解析LLMCall 与 LegacyOptimizerCallback 的定位、原理与实战人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习openJiuwen agent-core-java 旧版 LLM 调用完成回调接口 LegacyOptimizerCallback 使用与原理详解openJiuwen agent core java 旧版 LLM 调用完成回调接口 LegacyOptimizerCallback 使用与原理详解 Legac人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习上一篇安全审计日报 - 2024-01-15下一篇Qiskit量子计算终极指南如何成为开源量子项目的核心贡献者创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑