Under-Utils
stable 1.0.2 1.0.3-SNAPSHOT
docs/FUTURE_FEATURES.md

后续功能孵化

本文件用于记录尚未进入实现的新功能想法。它的目标是先把“为什么做、做到什么边界、什么不做”说清楚,再决定是否进入代码实现。

本文件用于记录尚未进入实现的新功能想法。它的目标是先把“为什么做、做到什么边界、什么不做”说清楚,再决定是否进入代码实现。

使用方式

  • 新想法先进入本文件,不直接新增模块或 public API。
  • 进入实现前,必须明确模块归属、依赖边界、配置项、失败语义、测试计划和兼容性影响。
  • 已进入工程成熟度推进的事项,放到 ENGINEERING_MATURITY.md,不要在两个文件重复维护。

状态定义

状态 含义
想法 只有场景和方向,尚未确定是否适合进入项目。
候选 已确认与项目边界基本匹配,等待设计。
设计中 正在明确 API、依赖、配置、失败语义和验收标准。
实现中 已开始代码实现。
已实现 已进入 main,完成代码、测试和文档,等待正式版本发布。
已发布 已进入正式版本并完成文档、测试和变更记录。
拒绝 不符合项目边界,或已有成熟库更适合承载。

功能准入标准

新功能进入实现前,应同时满足:

  • 解决跨项目重复出现的工程问题,而不是单个业务应用的流程。
  • 不只是对 JDK、Spring、Hutool、Apache Commons、Guava 或成熟生态库的低价值转包。
  • 有明确的 public API、配置 key、失败语义和资源释放边界。
  • 单元测试可以离线运行;涉及外部系统的测试必须可通过 mock server、Testcontainers 或独立 profile 复现。
  • 依赖重量与模块定位匹配,不让轻量模块被动引入大依赖。
  • 可以在 1.x 版本内保持源码兼容,或者明确作为 minor/major 能力规划。

F-001 AI 大模型基础调用封装

状态:已实现

背景

后续可能需要提供一个面向 Java/Spring 项目的 AI 大模型基础封装:调用方只配置模型服务的基本参数,就能完成最常见的文本对话调用。

这个能力的重点不是做完整 Agent 框架,而是收敛不同业务项目重复编写的模型调用基础代码,例如 base URL、API key、model、timeout、retry、错误处理和日志脱敏。

目标

  • 通过最少配置创建可用的 AI client。
  • 支持 OpenAI-compatible HTTP API 作为第一阶段协议目标。
  • 提供同步文本对话调用,优先覆盖最常见的 user/system/assistant message 场景。
  • 统一超时、重试、错误响应解析、trace header 和敏感信息脱敏。
  • core API 不强依赖 Spring;Spring Boot 自动装配放入独立 starter 或配置层。

非目标

  • 不做模型训练、微调、数据标注或计费系统。
  • 不做完整 Agent、工作流编排、工具调用市场或多步骤推理框架。
  • 不内置向量数据库、RAG 检索链路或知识库管理。
  • 不承诺覆盖所有模型厂商的全部私有参数。
  • 不在日志、异常或 debug 输出中暴露 API key、Authorization header 或完整敏感 prompt。

候选模块

模块 说明
under-utils-ai 模型调用抽象、请求响应模型、错误类型、OpenAI-compatible 执行器。
under-utils-ai-starter Spring Boot 自动装配、配置属性和默认 AiClient Bean。

候选 API 草案

AiClient aiClient = AiClient.builder()
        .baseUrl("https://api.example.com/v1")
        .apiKey(apiKey)
        .model("your-model-name")
        .timeout(Duration.ofSeconds(30))
        .build();

ChatResponse response = aiClient.chat(ChatRequest.user("请总结这段文本"));
String text = response.text();

Spring Boot 配置草案:

under:
  utils:
    ai:
      enabled: true
      provider: openai-compatible
      base-url: https://api.example.com/v1
      api-key: ${AI_API_KEY}
      model: your-model-name
      timeout: 30s
      retry:
        max-attempts: 2
        backoff: 500ms

候选核心类型

类型 说明
AiClient 对外调用入口,提供 chat 等基础方法。
AiClientOptions base URL、API key、model、timeout、retry、headers 等配置。
ChatRequest message、temperature、max tokens、request id 等请求参数。
ChatMessage system/user/assistant 等角色消息。
ChatResponse 文本、模型名、token 用量、原始 request id 等响应信息。
AiException 统一模型调用异常,区分认证失败、限流、超时、服务端错误和响应解析失败。

第一阶段验收标准

  • 只配置 base URL、API key 和 model 就能完成一次文本对话调用。
  • API key 不会出现在日志、异常消息或 toString() 输出中。
  • 单元测试通过 mock HTTP server 覆盖成功响应、401/429/5xx、超时和响应解析失败。
  • 默认测试不访问外网。
  • 文档提供 Java builder 和 Spring Boot YAML 两种用法。
  • 依赖边界经过评估,不能让现有轻量模块被动引入 AI 或 HTTP 大依赖。
  • under-utils-http 的复用关系明确:可以复用执行器能力,但不能让 AI API 被 HTTP 内部模型绑死。

第一阶段实现记录

  • 已新增 under-utils-ai 核心模块,提供 AiClientAiClientOptionsChatRequestChatMessageChatResponseTokenUsageAiExceptionOpenAiCompatibleAiClient
  • 第一阶段只实现同步文本对话,协议目标为 OpenAI-compatible Chat Completions。
  • 复用 under-utils-httpHttpRequestHttpConfigHttpResponse,但 AI 模块对外不暴露 HTTP 内部请求/响应模型。
  • 已用 MockWebServer 覆盖成功响应、认证失败、限流、服务端错误、超时、响应解析失败和敏感信息不进入 toString()
  • 已新增独立 under-utils-ai-starter,在 under.utils.ai.enabled=true 时按配置创建默认 AiClient;它不加入 under-utils-starter 聚合入口,避免普通 Spring/Redis 用户被动引入 AI 依赖。
  • 已在 under-utils-samples 增加 ai profile 和 /samples/ai/* 示例接口,默认 profile 只暴露状态,不会在未配置模型服务时访问外部网络。

第一阶段结论

  • 第一阶段只支持 OpenAI-compatible 协议,先不封装国内厂商原生私有 API。
  • 第一阶段只提供同步文本对话,不引入流式响应、工具调用、RAG 或 Agent 编排。
  • 第一阶段继续复用 under-utils-http 执行能力,AI 模块不把 HTTP 内部请求/响应模型暴露为 public API。
  • 已暴露 token 用量、模型名和 finish reason;模型指纹等元数据暂不进入第一阶段 public API。
  • starter 默认不创建 AiClient,必须显式设置 under.utils.ai.enabled=true

F-002 AI 流式响应与厂商扩展

状态:已实现

背景

F-001 已覆盖最小可用的同步文本对话。后续如果真实项目需要更低首 token 延迟、SSE 输出或国内模型厂商原生协议,可以进入第二阶段。

目标

  • 提供 OpenAI-compatible SSE 流式响应 API。
  • 提供 provider 扩展边界:优先通过 OpenAI-compatible 参数透传解决,只有协议差异无法兼容时才新增 provider。
  • 保持同步 AiClient API 稳定,不把第二阶段能力强行塞进第一阶段入口。
  • 明确取消、超时、连接中断和半截响应的失败语义。

非目标

  • 不做完整 Agent 编排、工具调用市场、RAG 知识库或模型路由平台。
  • 不引入具体厂商 SDK 作为默认依赖。
  • 不让 under-utils-ai-starter 进入 under-utils-starter 聚合入口。

候选模块

模块 说明
under-utils-ai 增加流式响应抽象和 provider 扩展点。
under-utils-ai-starter 只在配置明确启用时装配第二阶段能力。

第二阶段验收标准

  • 默认测试仍不访问外网。已通过 MockWebServer 覆盖。
  • 流式 API 能通过 MockWebServer 覆盖正常分片、服务端错误、连接中断和取消。已覆盖。
  • provider 扩展不能要求普通用户引入额外厂商 SDK。已通过 AiClientProvider 实现。
  • 新增配置 key 和 public API 必须记录在 CHANGELOG.mddocs/API_REVIEW.md 和模块 README。已同步到 API Review 和模块 README。

第二阶段实现记录

  • 新增 StreamingAiClientChatStreamChatStreamEvent,流式能力与同步 AiClient 分离,避免同步入口膨胀。
  • OpenAiCompatibleAiClient 实现 StreamingAiClient,请求体自动加入 stream=true 并消费 SSE data: 分片。
  • ChatStream 只能消费一次并实现 AutoCloseable,调用方可通过 try-with-resources 主动取消和释放 HTTP 连接。
  • 新增 AiResponseMetadata,同步响应和流式事件均可暴露 provider、调用方 request id、模型服务 response id、模型指纹和耗时。
  • 新增 AiClientProviderOpenAiCompatibleAiClientProvider,业务侧可以扩展 provider,不引入默认厂商 SDK。
  • under-utils-ai-starter 支持按 under.utils.ai.provider 匹配自定义 AiClientProvider Bean;用户自定义 AiClient Bean 时继续退让。
  • under-utils-samples 增加 /samples/ai/chat/stream SSE 示例。

第二阶段结论

  • 先做 OpenAI-compatible SSE 流式响应,不做 WebSocket 或厂商私有流式协议。
  • 使用独立 StreamingAiClient 承载流式能力,保持 AiClient.chat(...) 同步 API 简洁。
  • provider 扩展只定义接口和 starter 路由,不内置国内厂商 SDK。
  • 元数据模型进入 public API,但仍避免暴露完整 prompt、API key、Authorization header 或完整模型回复。

F-003 AI 多模型客户端配置与命名路由

状态:已实现

背景

F-001 和 F-002 已经覆盖单个 OpenAI-compatible 客户端的同步与流式调用。真实业务项目常见需求是同一应用内同时接入多个模型服务,例如默认模型、低成本模型、长文本模型或不同供应商兼容端点。

目标

  • 在 core 层提供按名称管理多个 AiClient 的注册表。
  • 在 starter 层支持 under.utils.ai.clients.<name>.* 多客户端配置。
  • 继续保留旧的单客户端顶层配置,避免已有 under.utils.ai.base-url / model 用户迁移成本。
  • 默认客户端仍作为 AiClient Bean 暴露,普通单模型应用不需要理解 registry。
  • 命名客户端可以继承顶层通用配置,并覆盖自己的 base URL、API key、model、headers 和 provider。

非目标

  • 不做模型自动路由、成本优化、灰度调度或健康检查。
  • 不新增厂商 SDK;命名客户端仍优先走 OpenAI-compatible 协议。
  • 不把 AI starter 放入 under-utils-starter 聚合入口。

实现记录

  • 新增 AiClientRegistryDefaultAiClientRegistry,支持 getDefaultClient()get(name)find(name)names() 和流式客户端获取。
  • under-utils-ai-starter 新增 default-clientclients 配置;未配置 clients 时继续创建名为 default 的兼容客户端。
  • AiClientRegistry 自动装配后,默认客户端继续以 AiClient Bean 暴露;用户自定义 AiClient Bean 时自动装配退让。
  • under-utils-samples AI profile 增加 secondary 命名客户端示例和按名称调用的同步/流式接口。

验收结果

  • 已通过 core registry 单元测试覆盖默认客户端、命名查找、缺失客户端和流式能力边界。
  • 已通过 starter 测试覆盖旧单客户端配置、多命名客户端配置、默认客户端选择、headers 继承、自定义 provider 和用户自定义 AiClient 退让。
  • 默认测试仍使用 MockWebServer,不访问外网。

新功能记录模板

## F-XXX 功能名称

状态:`想法`

### 背景

说明重复场景和当前痛点。

### 目标

- 目标 1
- 目标 2

### 非目标

- 不做什么

### 候选模块

说明模块归属和依赖边界。

### 候选 API 草案

给出最小可读示例。

### 第一阶段验收标准

- 可测试标准
- 文档标准
- 兼容性标准

### 待确认问题

- 尚未决定的问题