ARTICLE DETAIL

资讯详情

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

Qwen Code Java SDK 深度指南:基于 qwen serve daemon 传输的可靠 Java 11 编程代理客户端

Qwen Code Java SDK 深度指南:基于 qwen serve daemon 传输的可靠 Java 11 编程代理客户端 Qwen Code Java SDK 深度指南基于 qwen serve daemon 传输的可靠 Java 11 编程代理客户端【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-codeQwen Code Java SDK 是面向 Qwen Code 终端编程代理的官方 Java 客户端库其核心亮点在于 0.1.0-alpha 版本引入的 daemon 传输层通过 REST 突变mutation加可续传 SSEServer-Sent Events与qwen serve守护进程通信以失败即关闭fail closed的强可靠语义保证不会把截断的生成结果当作成功返回。本文基于仓库内 QWEN.md 与 java-daemon-sdk-alpha.md 设计文档结合 qwencode 模块源码 与测试代码完整讲解该 SDK 的版本约束、架构分工、构建安装、核心 API、传输契约、可靠性语义与已知 alpha 限制帮助你在自己的 Java 11 应用中稳定、正确地接入 Qwen Code 守护进程。一、版本与 Java 版本约束QWEN.md 明确了该 SDK 的版本发布形态该 Maven 包发布为com.alibaba:qwencode-sdk:0.1.0-alpha要求Java 11 或更高版本Java 8 用户必须继续使用0.0.3-alpha因为 0.1.0-alpha 将整个 artifact 的最低 Java 版本从 8 提升到了 11。这一约束同样写入了 RELEASE.md 与 README.md。需要注意的是0.1.0-alpha提升最低 Java 版本影响的是整个 artifact而非仅新增的 daemon API——旧的 stdio API 虽然保持源码兼容source-compatible但同样运行在 Java 11 之上。从 pom.xml 可以看到编译器配置为maven.compiler.release11构建与发布还要求 Maven 3.9.2。二、双 API 架构daemon 传输与 legacy stdio 传输SDK 在同一 artifact 内包含两套彼此隔离的实现API 包定位传输方式资源模型com.alibaba.qwen.code.daemon推荐 API0.1.0-alpha 新增通过 REST 突变 可续传 SSE 与qwen serve通信自持有界bounded的 HTTP、prompt、维护与定时器线程池com.alibaba.qwen.code.cli实验性 legacy API保持源码兼容通过子进程child process与 Qwen Code CLI 交互基于QwenCodeCli、Session、ProcessTransportQWEN.md 特别强调daemon 包在实现上有意独立于 legacy 的进程传输process transport、DTO、会话模型与全局执行器global executor。也就是说daemon API 没有复用QwenCodeCli那套全局线程池其默认配置为 30 核心 / 100 最大线程而是为每个DaemonClient实例自建一套受控资源这一点从 DaemonClient.java 的构造逻辑可以清楚看到——它按maximumConcurrentPrompts派生 worker、maintenance、future、http、stream-close 等多组独立线程池并全部使用 daemon 线程工厂创建。推荐 API 的核心特性与qwen serve通过 REST 和 SSE 通信默认创建thread 作用域thread-scoped的独立会话在没有可靠 prompt 终结事件terminal时失败即关闭绝不把部分输出当作成功当守护进程通告client_heartbeat能力时使用周期性心跳保持会话存活。依赖清单README.md 列出了完整依赖关系日志org.slf4j:slf4j-api应用自行选择 SLF4J providerLogback 仅为测试依赖工具类org.apache.commons:commons-lang3JSONFastjson2 用于编码、Jackson Core 用于严格解码测试JUnit 5org.junit.jupiter:junit-jupiter。三、安装与构建Maven 依赖在pom.xml中加入dependency groupIdcom.alibaba/groupId artifactIdqwencode-sdk/artifactId version0.1.0-alpha/version /dependencyGradle 依赖implementation com.alibaba:qwencode-sdk:0.1.0-alphaMaven 构建与校验QWEN.md 给出的标准命令mvn test # 运行单元测试 mvn checkstyle:check # 代码风格检查checkstyle.xml mvn package # 打包 JAR从 pom.xml 可以看出构建链还集成了 JaCoCo 覆盖率、source/javadoc 附属包、GPG 签名以及 Sonatype Central 发布插件产物会声明Automatic-Module-Name: qwencode.sdk。针对真实守护进程的 E2E 测试README.md 提供了从仓库源码运行真实 daemon 集成测试的步骤需先构建 workspaces 与根 CLI bundlenpm run build npm run bundle npx tsx scripts/run-java-daemon-sdk-e2e.ts注意npm run build本身不会刷新dist/cli.jsE2E 测试启动该 bundle缺失时会报出明确的前置错误。对应测试实现见 DaemonServeE2ETest.java。四、快速上手DaemonClientDaemonSessionClient最小示例promptTextREADME 给出了最简洁的用法——先启动qwen serve然后创建独立的 thread 作用域会话promptText只在收到匹配的turn_complete后返回不完整的数据流会抛PromptOutcomeIndeterminateException而不是把部分文本当成功返回import com.alibaba.qwen.code.daemon.DaemonClient; import com.alibaba.qwen.code.daemon.DaemonSessionClient; import com.alibaba.qwen.code.daemon.PromptTextResult; import java.net.URI; try (DaemonClient daemon DaemonClient.builder() .baseUri(URI.create(http://127.0.0.1:4170)) .build(); DaemonSessionClient session daemon.createSession()) { PromptTextResult result session.promptText(Explain this repository); System.out.println(result.getText()); }预置会话 ID需要在创建前分配会话身份的调用方可以传入 RFC UUID v1-v5 形式的 ID。SDK 会在发起突变前检查session_id_override能力若守护进程返回的 ID 与请求不一致会报告为SessionCreationOutcomeUnknownExceptionCreateSessionRequest request CreateSessionRequest.builder() .sessionId(550E8400-E29B-41D4-A716-446655440000) .build(); try (DaemonSessionClient session daemon.createSession(request)) { System.out.println(session.getSession().getSessionId()); }守护进程会把 ID 规范化为小写并创建一个新的 thread 会话——这不是幂等的 attach 操作当创建结果不明确时应当用已知 ID 去恢复而不是重试创建。带认证的连接如果qwen serve要求认证在DaemonClientbuilder 上追加.bearerToken(...)即可。SDK 在 REST 与 SSE 请求上都会携带 Bearer 头且绝不会把它放进 URLDaemonClient daemon DaemonClient.builder() .baseUri(URI.create(http://127.0.0.1:4170)) .bearerToken(System.getenv(QWEN_SERVER_TOKEN)) .build();五、DaemonClientBuilder 配置项源码级默认值以下默认值可直接从 DaemonClient.java 的Builder字段核实配置项默认值说明baseUri(URI)http://127.0.0.1:4170daemon 地址必须为不含凭据、query、fragment 的绝对 HTTP(S) 源bearerToken(String)无附加Authorization: Bearer ...头connectTimeout(Duration)10 秒HttpClient 建连超时requestTimeout(Duration)30 秒每个有限 JSON/错误体的请求超时收到响应头不结束该超时promptObservationTimeout(Duration)30 分钟本地 prompt 观察SSE 读取总预算sseIdleTimeout(Duration)45 秒SSE 空闲看门狗无活动则主动关闭流heartbeatInterval(Duration)1 分钟自动心跳间隔设为Duration.ZERO可关闭maximumReconnectAttempts(int)8SSE GET 的最大重连次数指数退避 全抖动maximumSseFrameBytes(int)16 MB16384 KB单帧字节上限最低 1024maximumConcurrentPrompts(int)32每个客户端最大并发 prompt 数maximumConcurrentPrompts是资源预算的核心worker 池、future 发布池、stream-close 池的容量都由它派生例如 stream-close 池容量为maximumConcurrentPrompts * 2对应每个 prompt 槽位允许一个正在排干的清理任务。当能力耗尽时后续startPrompt会抛DaemonClientCapacityException而不是无界增长线程或排队任务。六、会话与 Prompt 请求配置CreateSessionRequest见 CreateSessionRequest.javaworkspaceCwd(String)会话工作目录approvalMode(DaemonApprovalMode)/rawApprovalMode(String)审批模式wire 值sessionScope(String)thread默认或single二选一sessionId(String)可选的自定义会话 IDRFC UUID 风格。PromptRequest见 PromptRequest.javatext(String)便捷工厂构造单个文本块builder().addText(...)/addContent(Map)构造多内容块 promptdeadline(Duration)请求守护进程侧的绝对截止时间。取值范围为 1 到 2,147,483,647 毫秒对齐 daemon 的 Node 定时器范围。只有在守护进程通告prompt_absolute_deadline能力时才会被接受否则在发送前直接失败避免服务端静默忽略observationTimeout(Duration)仅约束本地 SSE 观察时间不会发出任何取消突变与deadline相互独立。七、传输契约与 Wire Flow单次 prompt 的线上流程设计文档 java-daemon-sdk-alpha.md 给出了明确的五步流程发送一次不重试的POST /session/:id/prompt要求返回202并校验响应体中的{promptId, lastEventId, eventEpoch?}admission watermark准入水位以水位作为Last-Event-ID打开GET /session/:id/events当 daemon 提供 epoch 时附带X-Qwen-Event-Epoch头只重放并观察与该 prompt 相关的事件同时将会话级失败帧如client_evicted、session_died、state_resync_required视为致命仅在匹配的turn_complete或turn_error时停止。这种按 prompt 订阅的方式天然覆盖了在202响应到达客户端之前就已发出的事件无需未知 prompt 缓存也不需要长驻的会话泵session pump。HTTP 传输细节使用 JDKHttpClient强制HTTP/1.1从不跟随重定向每个请求都发送 JSON 或 event-stream 的Accept头、配置了 Bearer 认证时的认证头以及创建会话后 daemon 下发的X-Qwen-Client-IdSSE 额外发送Accept-Encoding: identity、Cache-Control: no-cache与Last-Event-ID可用时携带X-Qwen-Event-Epoch光标有限 JSON 与错误体由有界订阅者消费并通过sendAsync与请求截止时间赛跑SSE 非成功响应体的预算取请求预算与 prompt 观察预算的较小值。SSE 解析与重连DaemonSessionClient.java 展示了严格的帧校验逻辑支持 LF/CRLF 换行、注释、多行data:UTF-8 严格解码校验帧、事件名、信封版本、数字 ID、SSE/envelope ID 一致性ID 小于等于已提交光标的事件视为重复不投递下一个数字事件必须恰好是cursor 1否则判定 ID 缺口并失败关闭无 ID 的合成事件仅接受守护进程文档化的控制帧client_evicted、slow_client_warning、stream_error、state_resync_required、replay_complete且不推进光标无 ID 的内容或终结事件直接失败关闭只重连 SSE GET采用有界指数全抖动退避上限 5 秒、流断开后的 SSEretry指令、以及可重试 HTTP 响应上的Retry-After上限 5 秒可解析 RFC 1123 时间突变请求绝不自动重试。事件纪元Event EpochSDK 会从 prompt 准入结果种子化 epoch从校验通过的 SSE 响应头学习新 epoch用于兼容在响应省略头时保留已知值并且在 prompt 观察期间检测到 epoch 变化时失败关闭——这是 #7458 重启安全事件光标纪元的核心契约。八、可靠性与失败关闭语义终结事件的唯一权威性只有匹配的turn_complete和turn_error是终结事件队列queue与prompt_cancelled事件仅是建议性advisory的。本地超时会停止观察但不会自动取消 daemon 端的 turn。当取消、截止、拆除与 agent 结算并发竞争时daemon 的 exactly-once 闩锁latch会发布第一个正式终结事件并压制后续候选——因此 SDK 始终以收到的终结事件为准绝不根据自己发出的最后一个控制突变来推断结果。结果不明确的异常分类RELEASE.md 与设计文档共同定义了完整的异常面场景异常发送后未收到有效 202、或返回 HTTP 408/5xxPromptAdmissionUnknownException绝不重发 prompt会话创建结果不明确SessionCreationOutcomeUnknownException取消结果不明确MutationOutcomeUnknownExceptiondetach 结果不明确DetachOutcomeUnknownException无可靠终结事件、观察失败、超时、重连耗尽PromptOutcomeIndeterminateException携带可用的部分文本turn_error终结promptText场景PromptTurnException文本超出 UTF-8 字节上限PromptContentLimitException权限permission、取消、心跳、detach、删除等突变都采用同样保守的分类——因为中间响应并不能证明 daemon 拒绝了该突变。每个突变每次方法调用最多尝试一次。promptText()只收集 assistant 文本强制 UTF-8 字节上限默认 4 MB见DaemonSessionClient.DEFAULT_MAXIMUM_TEXT_BYTES并且仅在匹配的turn_complete时返回PromptTextResult。幂等关闭与销毁close()本地幂等停止本地观察至多尝试一次 detach丢失的 detach 响应不重试destroySession()是唯一会发出DELETE /session/:id的 API可在 detach 之后调用结果不明确的完成是会话的终结边界outcome boundary而非可复用边界一旦准入结果未知或已准入 prompt 以不明确方式结束该DaemonSessionClient会永久拒绝后续 prompt即使本地流清理成功也必须关闭或销毁会话。九、能力协商与自动心跳创建前的能力校验DaemonClient.java 展示了会话创建前的硬性校验必须先读取GET /capabilitiesversion 必须为 1要求 daemon 通告rest传输与session_scope_override否则拒绝创建——防止旧 daemon 静默忽略请求的 thread 作用域而把客户端挂到共享会话上请求自定义 session ID 时额外要求session_id_override能力。DaemonCapabilities见 DaemonCapabilities.java暴露getVersion()、getMode()、getFeatures()、getTransports()、getWorkspaceCwd()、getQwenCodeVersion()与supports(feature)。自动心跳当 daemon 通告client_heartbeat时会话保持打开期间 SDK 会按配置间隔默认 1 分钟发送一次新的心跳突变直至 detach 或 destroy。心跳具有正常的有限请求截止时间且不重试将heartbeatInterval设为Duration.ZERO可关闭自动保活。从源码可见若心跳返回 404/405 会被视为能力不再支持而停止DaemonSessionClient.java。十、流式回调startPrompt与PromptObserver需要按序获取文本、思考、工具、用量、权限与原始事件时使用startPrompt配合PromptObserver。观察者接口PromptObserver.java提供六类默认方法onText(String, DaemonEvent)onThought(String, DaemonEvent)onTool(MapString,Object, DaemonEvent)onUsage(MapString,Object, DaemonEvent)onPermission(PermissionRequest, DaemonEvent)onEvent(DaemonEvent)回调执行语义设计文档明确回调在客户端自有 daemon 线程上串行执行事件光标只在所有适用回调成功返回后才推进回调必须快速返回不得等待同一个PromptCall不得在回调中关闭或销毁同一会话从回调中响应权限请求是被支持的当 daemon 报告该请求已解决或不再挂起时响应方法返回false。startPrompt立即返回PromptCall其acceptanceFuture()daemon 已接受该 prompt与completionFuture()turn 已可靠终结相互独立调用方可区分daemon 接受了 prompt与本轮可靠结束两个阶段。取消未来视图不会取消 daemon 端的 prompt——需要会话级取消请调用cancelActivePrompt()并且仍要等待匹配的终结事件协作式取消以stopReasoncancelled的turn_complete结束取消过程中 agent 或 provider 失败则可能产生turn_error。十一、已知 Alpha 限制QWEN.md 与 RELEASE.md 一致列出以下边界接入时务必知晓不承诺跨 daemon 重启的 exactly-once 执行不支持自动 epoch 恢复、snapshot/resync、持久化光标或真正按 prompt ID 定向取消创建时选择模型creation-time model selection故意不暴露当前 daemon 只通过 create 响应之前发出的 SSE 事件报告modelServiceId被拒而按 prompt 订阅从后续准入水位开始无法证明模型已生效模棱两可的创建可能遗留未知会话daemon 可能保留一个 ID 从未到达调用方的会话SDK 不重试创建也无法 detach恢复边界是 daemon 侧的生命周期回收reaping确认式取消握手没有仅确认超时这是刻意的——加入仅确认超时会让迟到的会话级取消可能到达后继 prompt破坏 FIFO 取消排干栅栏。因此一个无限期忽略其AbortSignal的 provider/工具/自定义集成可能让取消结果未知、会话不可用直到更强的运行时隔离出现配套 daemon 版本要求0.1.0-alpha 的生命周期保证依赖与 SDK 同一源码修订发布的 qwen-code 构建其必须包含按客户端 detach 台账#7386、按 epoch 终结保证#7400与重启安全事件光标纪元#7458以及本次发布的确认式准入取消 FIFO 取消排干栅栏。仅 #7400 一个提交是不够的。十二、验证与测试体系设计文档与 daemon 测试目录 展示了完整验证矩阵单元测试DaemonSessionClientTest、HttpSupportTest、JsonSupportTest、SseReaderTest使用进程内 HTTP 服务器注入SSE 分片、慢速单行投递、重放、重复、缺口、冲突的 prompt ID、不透明未来事件数据、水位重放、断开、压缩响应、停滞的有限响应体、事件纪元传播与不匹配、resync、观察者失败、缺失终结事件、模糊突变响应等生命周期测试覆盖单本地 prompt 准入、准入/关闭串行化、截止终结后会话复用、取消完成、拆除终结排序、有界文本、自动心跳、幂等关闭、detach 客户端身份、detach-once、显式 destroyCI在 Linux 上以 Java 11/17/21 编译测试macOS/Windows 覆盖 Java 21 smokeLinux CI 与受保护发布流程针对真实qwen serve进程临时 workspace model stub跑 E2E即DaemonServeE2ETest。十三、继续深入阅读模块总览与 API 示例README.md、QWEN.md版本历史与发布契约RELEASE.md实现设计文档java-daemon-sdk-alpha.md核心实现DaemonClient.java、DaemonSessionClient.java、PromptRequest.java构建配置pom.xml适用前提提醒本文所有行为均基于当前仓库0.1.0-alpha的 daemon 传输实现使用前请确认你的 Java 运行时为 11、daemon 为与 SDK 同源码修订的 qwen-code 构建并将 Java 8 项目锁定在0.0.3-alpha。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表