- 人工智能
- AI Agent
- Agent 框架
- 工具调用
- Agent 工作流
- RAG
- MCP Clients
- 强化学习
【免费下载链接】agent-core-java
openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。
AddScalarFieldOperation是 openJiuwen agent-core-java(openJiuwen Core 的 Java 实现)中com.openjiuwen.memory.migration.operation包下的核心迁移操作类,用于在向量数据库(如 Milvus、Chroma 等)的集合(Collection)中为向量数据类型新增一个标量字段(Scalar Field)。本文将从类定义、字段语义、构造方法、类型映射、迁移执行链路到实战示例与测试验证,完整剖析这一操作对象的设计与用法,帮助你在长期记忆(Long-Term Memory)的向量存储演进场景中正确使用它。
一、AddScalarFieldOperation 在迁移体系中的定位
openJiuwen 的记忆模块(memory)通过“迁移操作(Operation)+ 迁移器(Migrator)+ 注册表(Registry)”三层结构实现存储 Schema 的平滑演进。AddScalarFieldOperation属于迁移操作层中的向量库专用操作,与它同层级的还有RenameScalarFieldOperation(重命名标量字段)、UpdateScalarFieldTypeOperation(更新标量字段类型)、UpdateEmbeddingDimensionOperation(更新向量维度)等,详见 operation.README.md。
从源码看,该包还包含面向 SQL 与 KV 后端的操作(如AddColumnOperation、UpdateKVOperation),整体覆盖“SQL、向量库、KV”三类后端,而本文主角面向的是其中的向量库后端。其类声明位于 AddScalarFieldOperation.java:
public class AddScalarFieldOperation extends BaseOperation注释明确说明它镜像了 Python 版本openjiuwen/core/memory/migration/operation/operations.py中同名类,属于 DTO(纯数据传输对象),自身不含任何执行逻辑,真正“怎么做”由 VectorMigrator 与 VectorStoreUtils 负责。这种“操作定义与执行分离”的设计,让迁移计划可以先声明、后执行,且天然可序列化、可审计。
二、字段详解:四个属性决定“加什么字段”
类中定义的全部字段如下(与文档表格一致,并补充源码中的语义):
| 字段 | 类型 | 说明 |
|---|---|---|
dataType | String | 目标向量数据类型,即要修改的实体对应的向量集合类型名(如summary、user_profile)。 |
fieldName | String | 新增字段名,即标量字段在集合 Schema 中的名称。 |
fieldType | String | 新增字段的数据类型字符串,会被映射为VectorDataType枚举(详见下文第四节)。 |
defaultValue | Object | 字段默认值;可为null。 |
在源码实现中,这四个字段均被声明为private final,通过构造方法一次性注入,之后不可变:
private final String dataType; private final String fieldName; private final String fieldType; private final Object defaultValue;这种不可变设计保证了操作对象可以在注册表、迁移计划中安全共享,不会在多次执行中被意外篡改。
三、构造方法与公开方法
3.1 构造方法
类提供两个重载构造方法:
public AddScalarFieldOperation( OperationMetadata metadata, String dataType, String fieldName, String fieldType ) // 等价于 defaultValue 为 null 的完整构造 public AddScalarFieldOperation( OperationMetadata metadata, String dataType, String fieldName, String fieldType, Object defaultValue )参数说明:
| 参数 | 说明 |
|---|---|
metadata | 迁移元数据,封装schemaVersion(Schema 版本号)与描述文本,对应 OperationMetadata,可简写为new OperationMetadata(1)或new OperationMetadata(1, "add field")。 |
dataType | 目标向量数据类型名,例如summary、user_profile。 |
fieldName | 要新增的标量字段名。 |
fieldType | 标量字段类型字符串,如"string"、"int"、"double"、"bool"。 |
defaultValue | 默认值对象;不传时为null,表示新增字段无默认值。 |
值得注意:版本号(schemaVersion)保存在OperationMetadata中而非操作类本身。BaseOperation基类通过metadata.getSchemaVersion()暴露版本号,通过getDescription()暴露描述(描述为空时回退为类名AddScalarFieldOperation),参见 BaseOperation.java。
3.2 公开方法
| 方法 | 返回值 | 说明 |
|---|---|---|
getDataType() | String | 返回目标向量数据类型名。 |
getFieldName() | String | 返回要新增的字段名。 |
getFieldType() | String | 返回字段类型字符串。 |
getDefaultValue() | Object | 返回默认值对象(可能为null)。 |
此外,由于继承了BaseOperation,实例还具备getSchemaVersion()与getDescription()两个方法,供注册与执行阶段读取。
四、字段类型映射:fieldType 如何变成 VectorDataType
fieldType传入的是字符串(如"string"、"int32"),在执行时会通过VectorStoreUtils.mapStringToVectorDataType归一化映射为VectorDataType枚举,映射表定义在 VectorStoreUtils.java,目标枚举见 VectorDataType.java。
VectorDataType枚举支持的类型包括:
| 枚举值 | 典型用途 |
|---|---|
VARCHAR | 变长字符串(默认,fromValue(null)时返回VARCHAR) |
FLOAT_VECTOR | 浮点向量(注意:向量字段本身,非标量字段) |
INT64/INT32/INT16/INT8 | 各类整数标量 |
FLOAT/DOUBLE | 浮点标量 |
BOOL | 布尔标量 |
JSON | JSON 对象标量 |
ARRAY | 数组标量 |
映射过程做了两项容错:大小写不敏感(toLowerCase)且忽略首尾空白(strip),因此" string "、"INT64"都能正确映射。若传入无法识别的类型字符串,会抛出BaseError,状态码为STORE_VECTOR_SCHEMA_INVALID(该行为由测试 VectorStoreUtilsTest.java 覆盖)。
五、迁移执行原理:从注册到 Schema 落库
5.1 注册:版本必须严格递增
操作先被注册到MigrationPlan提供的按实体隔离的注册表中。向量实体使用MigrationPlan.getVectorRegistry(),注册要求同一实体下 schemaVersion 严格递增,否则抛出BaseError(StatusCode.MEMORY_REGISTER_OPERATION_VALIDATION_INVALID)。核心逻辑在 OperationRegistry.java:
int lastVersion = entityOperations.get(entityOperations.size() - 1).getSchemaVersion(); if (operation.getSchemaVersion() <= lastVersion) { throw ErrorHelper.buildError( StatusCode.MEMORY_REGISTER_OPERATION_VALIDATION_INVALID, ...); }OperationRegistry还提供getOperations(entityKey, fromVersion, toVersion)区间查询与getCurrentVersion(entityKey),供迁移器按版本增量执行。
5.2 执行:VectorMigrator 的增量迁移
VectorMigrator.tryMigrate 是执行入口,工作流程如下:
- 根据
entityKey(如vector_user_profile)归一化并校验记忆类型,找出所有名称以对应后缀结尾的集合; - 对每个集合读取当前
schema_version(来自集合元数据,缺省为 0); - 只筛选出版本号大于当前版本的操作(
operation.getSchemaVersion() > currentVersion),实现真正的增量迁移; - 调用
vectorStore.updateSchema(collectionName, operationsToApply)更新集合 Schema; - 成功后把集合元数据中的
schema_version更新为本次应用的最大版本号。
若底层向量存储不支持 Schema 变更(抛出UnsupportedOperationException),tryMigrate会返回Boolean.FALSE而非直接失败,调用方可以据此决定是否降级处理。
5.3 Schema 计算与文档回填:VectorStoreUtils
AddScalarFieldOperation的具体落地逻辑在 VectorStoreUtils 中,它通过反射按操作类名("AddScalarFieldOperation")分派到computeSchemaAddField:
newSchema.addField(new FieldSchema( fieldName, mapStringToVectorDataType(fieldType), false, false, null, null, null, null, null, defaultValue ));新字段以“非主键、可空、带默认值”的方式加入 Schema。与此同时,applyOperationToDoc(VectorStoreUtils.java)负责存量文档回填:当文档中尚不存在该字段且defaultValue != null时,自动把默认值写入文档:
if (!doc.containsKey(fieldName) && defaultValue != null) { doc.put(fieldName, defaultValue); }也就是说:提供默认值后,历史数据也会自动补齐新字段;若默认值为null,则存量文档不强制填充,仅 Schema 层面新增字段。
六、实战示例:为用户画像集合新增分类字段
下面是一个完整的、可复制的使用范式,包含“注册操作 → 执行迁移 → 验证结果”三步。测试用例 RunMigrationsTest.java 给出了完整参考实现:
import com.openjiuwen.memory.migration.MigrationPlan; import com.openjiuwen.memory.migration.RunMigrations; import com.openjiuwen.memory.migration.operation.AddScalarFieldOperation; import com.openjiuwen.memory.migration.operation.OperationMetadata; // 1. 注册迁移操作:为 vector_user_profile 实体新增 nickname 字段 MigrationPlan.getVectorRegistry().register("vector_user_profile", new AddScalarFieldOperation( new OperationMetadata(2, "add nickname field"), "user_profile", "nickname", "string", "unknown")); // 默认值 "unknown",存量数据自动回填 // 2. 执行向量迁移(底层基于 CompletableFuture) RunMigrations.runVectorMigrations(vectorStore).join();执行后可以断言(与 VectorMigratorTest.java 一致):
// 集合元数据中的 schema_version 已推进到 2 assertEquals(2, vectorStore.getCollectionMetadata(collectionName).join().get("schema_version")); // 旧文档被自动补齐默认值,可被过滤器检索到 assertEquals("unknown", vectorStore.withCollection(collectionName) .queryByFilters(Map.of("nickname", "unknown"), 10) .get(0) .getMetadata() .get("nickname"));在真实向量后端(如 Milvus)上的端到端行为,可参考 MilvusMigrationSystemTest.java:它把AddScalarFieldOperation与RenameScalarFieldOperation组合成一条版本 1→2 的迁移链,验证迁移后新字段可写入、旧字段被重命名、schema_version正确更新,且迁移前后的数据均可正常检索。
七、使用注意事项与边界行为
- 版本号语义:
schemaVersion是迁移顺序的唯一依据,注册时必须严格递增;执行时只应用高于当前版本的增量操作,重复执行是幂等安全的。 - 默认值与存量数据:只有
defaultValue != null时存量文档才会被自动补齐;若想“只加字段、不填数据”,请使用省略defaultValue的构造重载。 - 字段类型合法性:
fieldType必须是VectorDataType支持的类型字符串,否则抛出STORE_VECTOR_SCHEMA_INVALID错误;dataType则必须是SupportMemoryType中已支持的记忆类型,否则VectorMigrator会抛出MEMORY_MIGRATE_MEMORY_EXECUTION_ERROR。 - 后端能力依赖:底层向量存储必须支持 Schema 变更(实现
updateSchema),否则tryMigrate返回FALSE,调用方需自行处理降级。 - 操作顺序:多条操作按列表顺序依次应用到 Schema 与文档,例如“先
AddScalarFieldOperation再UpdateScalarFieldTypeOperation”会按声明顺序生效,参见 VectorStoreUtilsTest.java 的computeNewSchemaAppliesOperationsInOrderWithoutMutatingOriginal测试。
八、相关资源索引
- 操作类源码:AddScalarFieldOperation.java
- 基类与元数据:BaseOperation.java、OperationMetadata.java
- 注册容器:OperationRegistry.java
- 迁移执行器:VectorMigrator.java、RunMigrations.java
- Schema 计算工具:VectorStoreUtils.java
- 类型枚举:VectorDataType.java
- 测试验证:VectorMigratorTest.java、RunMigrationsTest.java、MilvusMigrationSystemTest.java
- 包级说明:operation.README.md
- 人工智能
- AI Agent
- Agent 框架
- 工具调用
- Agent 工作流
- RAG
- MCP Clients
- 强化学习
【免费下载链接】agent-core-java
openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。
相关推荐
openJiuwen agent-core 向量字段配置体系:VectorField 基类与 ANN 索引的阶段化参数设计
openJiuwen agent core 向量字段配置体系:VectorField 基类与 ANN 索引的阶段化参数设计 导读 本文是 openJiuwen
人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习openJiuwen agent-core-java 向量索引配置指南:vector_fields 包的类体系与双阶段参数导出机制
openJiuwen agent core java 向量索引配置指南:vector_fields 包的类体系与双阶段参数导出机制 com.openjiuwen
人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习openJiuwen Agent Core Java 向量存储工具类 VectorStoreUtils:分值归一化、Schema 迁移与文档变换实战指南
openJiuwen Agent Core Java 向量存储工具类 VectorStoreUtils:分值归一化、Schema 迁移与文档变换实战指南 导读
人工智能AI AgentAgent 框架工具调用Agent 工作流RAGMCP Clients强化学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考