Embeddings¶
EmbeddingModel calls record and replay too, independently of chat — enable with
spring.ai.test.vcr.embedding.enabled=true (separate from, and off unless enabled
alongside, the top-level spring.ai.test.vcr.enabled):
spring:
ai:
test:
vcr:
embedding:
enabled: true
mode: RECORD_OR_REPLAY
cache-directory: src/test/resources/llm-cache-embedding
EmbeddingModel has no advisor chain the way ChatClient does, so interception wraps the
EmbeddingModel bean itself, transparently — @Autowired EmbeddingModel in your own code
is unchanged, and every entry point (embed(String), embed(List<String>),
embedForResponse(List<String>)) is covered, since they all route through the same
underlying call.
@Autowired
private EmbeddingModel embeddingModel;
@Test
void replaysTheExactRecordedVector() {
float[] first = this.embeddingModel.embed("Istanbul is the largest city in Turkey.");
float[] second = this.embeddingModel.embed("Istanbul is the largest city in Turkey.");
assertThat(second).isEqualTo(first); // exactly, not "same length"
}
A replayed vector is exactly — not "the same length as" — what was recorded.
Why this exists on its own¶
This is the foundation Assertions' semantic similarity check depends on: an assertion that computes cosine similarity against a reference answer needs its own embedding call to be exactly this deterministic, or every CI run would make a live, non-reproducible embedding call to check a "deterministic" test.