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核心模块,提供AiClient、AiClientOptions、ChatRequest、ChatMessage、ChatResponse、TokenUsage、AiException和OpenAiCompatibleAiClient。 - 第一阶段只实现同步文本对话,协议目标为 OpenAI-compatible Chat Completions。
- 复用
under-utils-http的HttpRequest、HttpConfig和HttpResponse,但 AI 模块对外不暴露 HTTP 内部请求/响应模型。 - 已用
MockWebServer覆盖成功响应、认证失败、限流、服务端错误、超时、响应解析失败和敏感信息不进入toString()。 - 已新增独立
under-utils-ai-starter,在under.utils.ai.enabled=true时按配置创建默认AiClient;它不加入under-utils-starter聚合入口,避免普通 Spring/Redis 用户被动引入 AI 依赖。 - 已在
under-utils-samples增加aiprofile 和/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。
- 保持同步
AiClientAPI 稳定,不把第二阶段能力强行塞进第一阶段入口。 - 明确取消、超时、连接中断和半截响应的失败语义。
非目标
- 不做完整 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.md、docs/API_REVIEW.md和模块 README。已同步到 API Review 和模块 README。
第二阶段实现记录
- 新增
StreamingAiClient、ChatStream和ChatStreamEvent,流式能力与同步AiClient分离,避免同步入口膨胀。 OpenAiCompatibleAiClient实现StreamingAiClient,请求体自动加入stream=true并消费 SSEdata:分片。ChatStream只能消费一次并实现AutoCloseable,调用方可通过 try-with-resources 主动取消和释放 HTTP 连接。- 新增
AiResponseMetadata,同步响应和流式事件均可暴露 provider、调用方 request id、模型服务 response id、模型指纹和耗时。 - 新增
AiClientProvider和OpenAiCompatibleAiClientProvider,业务侧可以扩展 provider,不引入默认厂商 SDK。 under-utils-ai-starter支持按under.utils.ai.provider匹配自定义AiClientProviderBean;用户自定义AiClientBean 时继续退让。under-utils-samples增加/samples/ai/chat/streamSSE 示例。
第二阶段结论
- 先做 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用户迁移成本。 - 默认客户端仍作为
AiClientBean 暴露,普通单模型应用不需要理解 registry。 - 命名客户端可以继承顶层通用配置,并覆盖自己的 base URL、API key、model、headers 和 provider。
非目标
- 不做模型自动路由、成本优化、灰度调度或健康检查。
- 不新增厂商 SDK;命名客户端仍优先走 OpenAI-compatible 协议。
- 不把 AI starter 放入
under-utils-starter聚合入口。
实现记录
- 新增
AiClientRegistry和DefaultAiClientRegistry,支持getDefaultClient()、get(name)、find(name)、names()和流式客户端获取。 under-utils-ai-starter新增default-client与clients配置;未配置clients时继续创建名为default的兼容客户端。AiClientRegistry自动装配后,默认客户端继续以AiClientBean 暴露;用户自定义AiClientBean 时自动装配退让。under-utils-samplesAI profile 增加secondary命名客户端示例和按名称调用的同步/流式接口。
验收结果
- 已通过 core registry 单元测试覆盖默认客户端、命名查找、缺失客户端和流式能力边界。
- 已通过 starter 测试覆盖旧单客户端配置、多命名客户端配置、默认客户端选择、headers 继承、自定义 provider 和用户自定义
AiClient退让。 - 默认测试仍使用 MockWebServer,不访问外网。
新功能记录模板
## F-XXX 功能名称
状态:`想法`
### 背景
说明重复场景和当前痛点。
### 目标
- 目标 1
- 目标 2
### 非目标
- 不做什么
### 候选模块
说明模块归属和依赖边界。
### 候选 API 草案
给出最小可读示例。
### 第一阶段验收标准
- 可测试标准
- 文档标准
- 兼容性标准
### 待确认问题
- 尚未决定的问题