- 人工智能
- AI Agent
- Agent 框架
- 工具调用
- Agent 工作流
- RAG
- MCP Clients
- 强化学习
【免费下载链接】agent-core-java
openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。
导读
com.openjiuwen.core.retrieval.embedding.Embedding是 openJiuwen agent-core-java 检索模块(retrieval)中所有 embedding 模型能力的统一抽象。它以一套稳定接口覆盖"查询向量化、批量文档向量化、维度查询、批次上限"四类核心能力,并向下支撑通用 HTTP 客户端APIEmbedding、OpenAI 兼容客户端OpenAIEmbedding、vLLM 多模态客户端VLLMEmbedding、DashScope 客户端DashscopeEmbedding以及本地确定性实现HashEmbedding。阅读本文后,你将掌握 Embedding 接口的完整方法语义、默认行为与约束,理解各实现类如何复用这套抽象,并能在知识检索、RAG 工作流等场景中正确选用与配置 embedding 模型。
1. Embedding 接口定位:检索模块的统一向量化入口
在 openJiuwen 的代码结构中,embedding 抽象分两层存在:
- 通用层:
com.openjiuwen.core.foundation.store.Embedding,定义在所有存储与向量化场景下共用的基础抽象; - 检索层:
com.openjiuwen.core.retrieval.embedding.Embedding,继承通用层抽象,是检索子模块(retrieval)对外暴露的 embedding 统一入口。
从源码看,检索层 Embedding 本身是一个空继承类,其全部能力来自通用基类 foundation.store.Embedding:
package com.openjiuwen.core.retrieval.embedding; public abstract class Embedding extends com.openjiuwen.core.foundation.store.Embedding { }这种"通用抽象 + 检索子包继承"的分层设计与 Python 侧openjiuwen/core/retrieval/embedding/base.py、openjiuwen/core/foundation/store/base_embedding.py一一对应,保证了 Java 版本与 Python 版本能力面的对齐。Embedding还实现了AutoCloseable,所有持有线程池或连接资源的子类都应通过close()释放资源。
2. 接口方法全景:四类核心能力
文档定义了Embedding的 6 个方法,可归纳为四类能力:查询向量化、批量文档向量化、维度查询、批次上限查询。为便于对照阅读,先给出接口层面的完整方法表:
| 方法签名 | 能力分类 | 说明 |
|---|---|---|
List<Float> embedQuery(String text) | 查询向量化 | 对单条查询文本生成向量 |
default List<Float> embedQuery(String text, Map<String, Object> options) | 查询向量化 | 带选项的查询向量化,默认复用单参实现 |
List<List<Float>> embedDocuments(List<String> texts, Integer batchSize) | 批量向量化 | 批量生成文档向量 |
default List<List<Float>> embedDocuments(List<String> texts, Integer batchSize, Map<String, Object> options) | 批量向量化 | 带选项的批量向量化,默认复用基础实现 |
int getDimension() | 维度查询 | 返回向量维度 |
default int getMaxBatchSize() | 批次上限 | 返回最大批次,默认值为256 |
注意:文档中的接口方法表是从检索层 API 视角归纳的逻辑签名(以List<Float>承载向量);而 foundation.store.Embedding 的实际 Java 方法签名以CompletableFuture<List<Double>>异步返回向量,并提供了多个便捷重载:
embedQuery(String text, Map<String, Object> kwargs)与无选项重载embedQuery(String text);embedDocuments(List<String> texts, Integer batchSize, Map<String, Object> kwargs)及其省略kwargs、省略batchSize两个重载。
这正是"统一抽象、多种形态"的体现:上层业务统一面对同一套能力语义,底层实现可自由选择同步或异步风格。
2.1 查询向量化:embedQuery
embedQuery用于把单条查询(query)文本转换为向量。在 RAG 检索链路中,查询向量用于与文档库中的预计算向量做相似度匹配。接口层面的语义要点:
- 输入为一条字符串,输出为
List<Float>向量; - 带
options的重载允许透传模型相关参数(如dimensions、instruction等),默认实现直接复用单参版本,即不带任何选项。
2.2 批量文档向量化:embedDocuments
embedDocuments用于把一批文档文本转换为向量列表,是知识库索引(indexing)阶段的核心调用。语义要点:
- 输入为
List<String>与可选batchSize,输出为List<List<Float>>,顺序与输入文本一一对应; - 带
options的重载默认复用基础实现; batchSize为可选参数,传入null时由实现类按自身默认批次处理。
2.3 维度查询:getDimension
getDimension()返回当前 embedding 模型的向量维度,即每个文本向量包含的元素个数。该值在向量存储(vector store)建表、相似度计算与索引校验中都会用到。
2.4 批次上限:getMaxBatchSize
getMaxBatchSize()返回单次批量调用允许的最大文本条数,接口默认值为256。各实现类可以根据底层服务的吞吐限制覆盖此值(例如APIEmbedding的默认最大批次是8)。
3. 源码级实现:抽象基类的默认行为与约束
通用基类 foundation.store.Embedding 的默认实现值得关注:
embedQuery(text)/embedDocuments(texts, batchSize)重载默认使用空kwargs,与带选项版本等价:public CompletableFuture<List<Double>> embedQuery(String text) { return embedQuery(text, Map.of()); } public CompletableFuture<List<List<Double>>> embedDocuments(List<String> texts, Integer batchSize) { return embedDocuments(texts, batchSize, Map.of()); }getDimension()与getMaxBatchSize()均未在基类提供默认实现,维度由子类负责提供,批次上限则有接口级默认值256;close()默认为空操作,持有线程池等资源的子类应重写以释放资源;- 基类还提供
limiter(Semaphore)信号量用于并发限流,并通过getLimiter()/setLimiter()暴露,APIEmbedding等远程实现正是利用它控制最大并发数。
在 core 模块的单元测试 中,RecordingEmbedding直接继承该抽象类并只实现三个抽象方法,随后断言:
embedQuery("hello")调用时kwargs为空Map;embedDocuments(List.of("a","b"))调用时batchSize为null、kwargs为空;- 配置类
EmbeddingConfig能正确保留modelName、baseUrl、apiKey三个字段。
这组测试从行为层面印证了"重载默认传空参数、可选参数可省略"的接口契约。
4. 配置载体:EmbeddingConfig 与检索层扩展
embedding 模型的远程调用参数由配置类承载。通用配置定义在 foundation.store.EmbeddingConfig,三个核心字段为:
| 字段 | 类型 | 说明 | 约束 |
|---|---|---|---|
modelName | String | 模型名称,随请求体model字段发送 | 必填,为null时抛IllegalArgumentException("model_name is required") |
baseUrl | String | 服务基础地址 | 必填,为null时抛IllegalArgumentException("base_url is required") |
apiKey | String | 可选 API 密钥 | 可选;非空时自动附加Authorization: Bearer <key>请求头 |
该配置类标注了@Builder、@Data、@JsonInclude(NON_NULL),支持链式构造与 JSON 反序列化:
EmbeddingConfig config = EmbeddingConfig.builder() .modelName("text-embedding-v3") .baseUrl("https://api.example.com/v1") .apiKey("sk-xxx") .build();检索子模块还提供了 retrieval.common.EmbeddingConfig 作为兼容外观(facade),在通用三字段之上扩展了 SSL 校验开关:
| 字段 | JSON 键 | 说明 | 默认值 |
|---|---|---|---|
verifySsl | verify_ssl/verifySsl | 是否校验服务端 SSL 证书 | true |
sslCert | ssl_cert/sslCert | 自定义 CA 证书路径 | null |
从代码结构可以推断,该外观类主要为工作流组件(如知识检索组件)的 JSON 配置反序列化提供更完整的 SSL 控制能力。
5. 四种远程/本地实现:从通用 HTTP 到多模态
Embedding抽象之下共有四条主实现路径,按适用场景可划分为:
| 实现类 | 父类 | 适用场景 |
|---|---|---|
HashEmbedding | Embedding(直接) | 本地确定性向量,测试、开发、无远程模型时使用 |
APIEmbedding | Embedding(直接) | 任意通用 HTTP embedding 服务,支持重试与并发 |
OpenAIEmbedding | APIEmbedding | OpenAI 兼容接口,支持 base64 float32 向量响应 |
VLLMEmbedding | OpenAIEmbedding | vLLM 多模态输入(通过extra_body.messages) |
DashscopeEmbedding | APIEmbedding | DashScope 文本/多模态 embedding 服务 |
下面逐一展开各实现的关键机制。
5.1 HashEmbedding:不依赖网络的确定性实现
HashEmbedding 基于 SHA-256 摘要把文本映射为固定维度向量,是测试与离线开发场景的实用工具:
- 默认维度为
32、默认最大批次为256;构造时可指定dimension与maxBatchSize,两者最小值都被钳制为1; - 确定性:同一文本始终得到相同向量,便于断言测试结果;
- 容错:
null文本按空字符串处理; - 值域:每个向量元素由
digest[i] & 0xff映射到[-1, 1]区间((unsigned / 255.0) * 2.0 - 1.0)。
其embedQuery/embedDocuments均返回CompletableFuture.completedFuture(...),即不触发任何网络 IO。
5.2 APIEmbedding:通用 HTTP embedding 客户端
APIEmbedding 是最核心的通用实现,文档明确列出其默认参数:
| 参数 | 默认值 | 含义 |
|---|---|---|
timeout | 60秒 | HTTP 请求与连接超时 |
maxRetries | 3 | 失败重试次数 |
maxBatchSize | 8 | 单批次最大文本数 |
maxConcurrent | 50 | 并发上限(信号量许可数) |
其关键机制包括:
- 请求头:默认总是携带
Content-Type: application/json;apiKey非空时附加Authorization: Bearer <apiKey>;构造时可通过extraHeaders追加自定义头; - 请求体:
{"model": ..., "input": ..., ...kwargs},kwargs中除callback/callback_cls外的键会透传为请求参数; - 批量分片与并发:
embedDocuments会按有效批次大小将文本列表切分为多个批次,每个批次由独立CompletableFuture提交到线程池并行执行,并发上限由Semaphore limiter控制;每个批次完成后触发回调通知(BaseCallback); - 批次钳制:实际批次大小
resolveBatchSize会落在[1, maxBatchSize]区间,传入null时使用maxBatchSize; - 输入校验:空列表、全空白文本、
callback_cls不是BaseCallback子类,都会抛出对应检索异常(RETRIEVAL_EMBEDDING_INPUT_INVALID/RETRIEVAL_EMBEDDING_CALLBACK_INVALID); - 响应解析:支持
embedding、embeddings、data[].embedding三类响应结构,解析不出向量时抛RETRIEVAL_EMBEDDING_RESPONSE_INVALID; - 重试:
getEmbeddingsSync在IOException/InterruptedException时按maxRetries次重试,最终失败抛RETRIEVAL_EMBEDDING_REQUEST_CALL_FAILED; - 维度懒加载:
getDimension()首次调用会用"test"作为查询文本实测返回向量长度并缓存(volatile Integer dimension),后续请求也会顺带更新维度缓存; - SSL 控制:可通过环境变量
EMBEDDING_SSL_VERIFY=false关闭 HTTPS 证书校验,或用EMBEDDING_SSL_CERT指定自定义 CA 证书; - 资源管理:
close()关闭内部线程池;线程池由OpenJiuwenExecutors创建,线程名以openjiuwen_embed-前缀标识(JDK 21+ 下为虚拟线程执行器,并发上限由信号量保证)。
5.3 OpenAIEmbedding:OpenAI 兼容客户端
OpenAIEmbedding 继承APIEmbedding,主要增强两点:
- 端点规范化:初始化时会把
baseUrl尾部多余的/去掉;若基础地址不以/embeddings结尾,则自动拼接/embeddings,保证请求始终打到单层 embeddings 端点; - base64 向量解析:
parseEmbeddings优先解析 OpenAI 风格data[].embedding数组,且按index字段排序保证结果顺序;若embedding字段是字符串(base64 编码的 little-endian float32),则调用EmbeddingUtils.parseBase64Embedding解码为浮点向量; - 维度直通:构造时若显式提供
dimension,getDimension()直接返回该值,否则复用父类懒加载逻辑;并且会在请求kwargs中自动补入dimensions参数(putIfAbsent)。
此外,构造时若apiKey为空,会直接抛IllegalArgumentException("OpenAI API key is required")。
5.4 VLLMEmbedding:多模态 embedding
VLLMEmbedding 继承OpenAIEmbedding,针对 vLLM 的多模态 embedding 服务做了协议适配:
parseMultimodalInput(MultimodalDocument, options)把多模态文档转换为extra_body.messages结构:默认插入一条 system 消息"Represent the user's input.",再追加 user 消息(内容为document.getContent());- 若
options中显式提供instruction键则使用其值,且显式传入instruction = null时不会写入 system message(该行为已被测试确认); - 提供
embedMultimodal(异步)与embedMultimodalSync(同步)两组重载,输入必须是MultimodalDocument,否则抛RETRIEVAL_EMBEDDING_INPUT_INVALID。
MultimodalDocument支持text、image、audio、video四类字段,音频以input_audiodata URI 形式承载,其实现位于 retrieval.common.MultimodalDocument。
5.5 DashscopeEmbedding:DashScope 服务适配
在retrieval模块中还提供了面向阿里云 DashScope 的 DashscopeEmbedding:
- 请求发往
baseUrl + "/services/embeddings/text-embedding/text-embedding"端点,携带model、api_key、base_address、timeout等请求参数; - 支持 DashScope 特有响应结构(
output.embeddings[],按index排序); - 支持 Matryoshka 维度(构造时提供
dimension会启用该能力并透传); - 同样支持多模态输入(
MultimodalDocument.getDashscopeInput()转换为 DashScope 格式)。
6. 实战接线:embedding 在知识检索组件中的落地
embedding 抽象不是孤立存在的,它被 KnowledgeRetrievalExecutable 这类工作流组件直接消费。以该组件为例,其createEmbeddingModel方法展示了标准接线模式:
private Embedding createEmbeddingModel(ComponentKBConfig componentKbConfig) { EmbeddingConfig embedConfig = componentKbConfig.getEmbedConfig(); KnowledgeBaseConfig kbConfig = componentKbConfig.getKbConfig(); String indexType = kbConfig == null ? null : kbConfig.getIndexType(); if (embedConfig == null) { if ("vector".equals(indexType) || "hybrid".equals(indexType)) { throw ...; // vector/hybrid 索引必须配置 embedding } return null; } if (additional == null || additional.isEmpty()) { return new OpenAIEmbedding(embedConfig); } return new OpenAIEmbedding(embedConfig, intOption(additional, "timeout", 60), intOption(additional, "max_retries", 3), stringMapOption(additional, "extra_headers"), intOption(additional, "max_batch_size", 8), intOption(additional, "max_concurrent", 50), integerOption(additional, "dimension"), null); }这段实现透露出两个实战要点:
- 索引类型驱动 embedding 必需性:当知识库索引类型为
vector或hybrid时,embedding 配置是必需的,缺失会直接报初始化错误;而纯关键词索引(如keyword)可以没有 embedding 模型; - 可调参数全映射:工作流配置的
timeout、max_retries、extra_headers、max_batch_size、max_concurrent、dimension会逐一映射到OpenAIEmbedding构造参数,默认值与 5.2 节表格完全一致——这意味着在知识检索工作流中,你可以直接通过配置覆盖这些行为,而不必改动代码。
7. 测试验证与行为保障
检索模块的测试是理解各实现行为契约的最佳参考资料,相关用例包括:
| 测试文件 | 验证要点 |
|---|---|
| EmbeddingTest | 重载默认空 kwargs、可选 batchSize、配置字段保留 |
APIEmbeddingTest(retrieval/src/test) | 默认参数生效、请求头合并、embedding/embeddings/data[]三种响应解析、重试后成功、维度缓存、空白输入拒绝 |
OpenAIEmbeddingTest | OpenAI 数组结果与 base64 向量结果解析 |
VLLMEmbeddingTest | instruction默认插入与显式null时不写 system message |
HashEmbeddingTest | 向量值域位于[-1, 1] |
EmbeddingUtilsTest | base64 float32 解析 |
其中 APIEmbeddingTest 的若干断言可以当作接口契约的"行为级文档":
- 默认构造时
maxConcurrent = 50,信号量许可数即为并发上限; - 自定义参数(
timeout=120、maxRetries=5、maxBatchSize=16)被正确应用; - 未配置
apiKey时不设置Authorization头,配置后为Bearer <key>; - 空白查询文本抛
RETRIEVAL_EMBEDDING_INPUT_INVALID,响应无向量字段抛RETRIEVAL_EMBEDDING_RESPONSE_INVALID; {"embedding":[0.1,0.2,0.3]}响应解析后维度被缓存为3。
8. 选型建议与注意事项
综合文档与源码,在实际项目中可按以下原则选择 embedding 实现:
- 开发与单测阶段:优先
HashEmbedding,零依赖、确定性输出,可避免外部服务不稳定导致的测试波动; - 接入通用 HTTP embedding 服务:使用
APIEmbedding,通过构造参数显式配置timeout、maxRetries、maxConcurrent,并利用callback_cls机制观察批量进度; - 接入 OpenAI 兼容服务(含各类网关):使用
OpenAIEmbedding,注意baseUrl既可以给基础地址也可以给完整/embeddings地址,客户端会自动规范化;若服务返回 base64 向量,客户端可直接解码; - 多模态向量化(vLLM):使用
VLLMEmbedding,输入统一封装为MultimodalDocument; - DashScope 服务:使用
DashscopeEmbedding。
使用注意事项:
EmbeddingConfig.modelName与baseUrl为必填,缺失会抛IllegalArgumentException;- 远程客户端务必在不再使用时调用
close()释放线程池资源; - 批量向量化时传入文本不能为空或全空白,
batchSize会被钳制在[1, maxBatchSize]; - 未显式配置维度时,
APIEmbedding会以"test"文本实测一次来推断维度,首次调用存在一次额外的网络请求; - 生产环境默认开启 SSL 校验,仅在可控的内网/测试环境才建议通过
EMBEDDING_SSL_VERIFY=false关闭。
9. 延伸阅读
- 检索模块 embedding 总览文档:
Embedding、APIEmbedding、OpenAIEmbedding、VLLMEmbedding、HashEmbedding、EmbeddingUtils的类型级说明; - EmbeddingUtils 工具文档:base64 float32 向量解析工具;
- 通用基类实现 与 配置类;
- APIEmbedding 实现 与 HashEmbedding 实现;
- OpenAIEmbedding、VLLMEmbedding、DashscopeEmbedding 实现;
- 知识检索组件接线示例。
- 人工智能
- AI Agent
- Agent 框架
- 工具调用
- Agent 工作流
- RAG
- MCP Clients
- 强化学习
【免费下载链接】agent-core-java
openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。
相关推荐
openJiuwen agent-core 文本向量化:Embedding 抽象基类接口设计与多后端实现深度解析
openJiuwen agent core 文本向量化:Embedding 抽象基类接口设计与多后端实现深度解析 导读 本文以 openJiuwen agent
人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习openJiuwen agent-core-java 提示词模板管理:PromptMgr 注册、查询与批量管理实战解析
openJiuwen agent core java 提示词模板管理:PromptMgr 注册、查询与批量管理实战解析 本文以 com.openjiuwen.c
人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习如何调用 PrivateGPT 的 /v1/embeddings 接口批量生成文档与查询向量
如何调用 PrivateGPT 的 /v1/embeddings 接口批量生成文档与查询向量 PrivateGPT 提供 POST /v1/embeddings
人工智能大模型RAG本地部署LLM 网关后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考