Implementing HunYuan Embedding Vector Support in Spring AI

This article continues exploring the Spring AI ecosystem by extending the HunYuan model support to include embedding vector capabilities. After establishing chat functionality in the previous implementation, we now add vector embedding support to enable semantic search and similarity matching features.

API Interface Integration

Tencent's HunYuan API uses a unified domain across all services, with request differentiation handled through the X-TC-Action header rather than separate URL paths. This design allows multiple operations to share the same endpoint while remaining distinct through header configuration.

To support embedding operations, the existing API client requires modification to route requests appropriately. The updated implementation specifies the action header for embedding calls:

ResponseEntity<EmbeddingResponse> vectorResponse = this.restClient.post()
    .uri("/")
    .header("X-TC-Action", HunYuanConstants.DEFAULT_EMBED_ACTION)
    .body(embeddingRequest)
    .retrieve()
    .toEntity(EmbeddingResponse.class);

The interceptor pattern in the REST client captures each request, enabling dynamic header processing based on the specific action being executed:

@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, 
        ClientHttpRequestExecution execution) throws IOException {
    String actionHeader = request.getHeaders().getFirst("X-TC-Action");
    MultiValueMap<String, String> headers = authProvider.buildHeaders(actionHeader, body);
    // Process and apply headers
}

Input Parameter Handling

The embedding API accepts text input in array format. This aligns well with Spring AI's internal processing, which converts input to array representation automatically:

default float[] embed(String text) {
    Assert.notNull(text, "Text must not be null");
    List<float[]> results = this.embed(List.of(text));
    return results.iterator().next();
}

Using array-based input provides direct data mapping and simplifies integration with the framework's processing pipeline.

Output Parameter Processing

The Tencent API wraps all responses within a Response container, requiring additional unwrapping to extract the actual embedding data:

ResponseEntity<EmbeddingResponse> vectorResponse = this.restClient.post()
    .uri("/")
    .header("X-TC-Action", HunYuanConstants.DEFAULT_EMBED_ACTION)
    .body(embeddingRequest)
    .retrieve()
    .toEntity(EmbeddingResponse.class);

return vectorResponse.getBody().response();

The response structure uses nested records to handle the API's JSON hierarchy:

@JsonInclude(Include.NON_NULL)
public record EmbeddingResponse(
    @JsonProperty("Response") EmbeddingList response
) {}

@JsonInclude(Include.NON_NULL)
public record EmbeddingList(
    @JsonProperty("RequestId") String requestId,
    @JsonProperty("Data") List<Embedding> data,
    @JsonProperty("Usage") Usage usage
) {}

Spring Boot Auto-Configuration

Configuration Properties

A properties class binds configuration values from application.yml to the embedding model:

@ConfigurationProperties(HunYuanEmbeddingProperties.CONFIG_PREFIX)
public class HunYuanEmbeddingProperties extends HunYuanParentProperties {
  
    public static final String CONFIG_PREFIX = "spring.ai.hunyuan.embedding";
    public static final String DEFAULT_EMBEDDING_MODEL = "hunyuan-embedding";
    // Additional configuration fields
}

Auto Configuration Class

The auto-configuration registers the embedding model bean with appropriate conditional checks:

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = HunYuanEmbeddingProperties.CONFIG_PREFIX, 
        name = "enabled", havingValue = "true", matchIfMissing = true)
public HunYuanEmbeddingModel hunYuanEmbeddingModel(
        HunYuanCommonProperties commonProperties,
        HunYuanEmbeddingProperties embeddingProperties, 
        ObjectProvider<RestClient.Builder> restClientBuilderProvider,
        ObjectProvider<WebClient.Builder> webClientBuilderProvider, 
        RetryTemplate retryTemplate,
        ResponseErrorHandler responseErrorHandler, 
        ObjectProvider<ObservationRegistry> observationRegistry,
        ObjectProvider<EmbeddingModelObservationConvention> convention) {

    var apiClient = hunyuanApi(
            embeddingProperties.getSecretId(), 
            commonProperties.getSecretId(),
            embeddingProperties.getSecretKey(), 
            commonProperties.getSecretKey(), 
            embeddingProperties.getBaseUrl(),
            commonProperties.getBaseUrl(),
            restClientBuilderProvider.getIfAvailable(RestClient::builder),
            responseErrorHandler);

    var embeddingModel = new HunYuanEmbeddingModel(
            embeddingProperties.getOptions(), 
            retryTemplate,
            apiClient, 
            embeddingProperties.getMetadataMode(),
            observationRegistry.getIfUnique(() -> ObservationRegistry.NOOP));

    convention.ifAvailable(embeddingModel::setObservationConvention);

    return embeddingModel;
}

This configuration enables embedding functionality through standard Spring Boot property management, allowing users to configure the HunYuan embedding model via application.yml without manual bean registration.

Tags: spring-ai Hunyuan embedding Vector-Database spring-boot

Posted on Mon, 19 Oct 2026 16:33:22 +0000 by beginneratphp