Skip to content

Make embedding model and task prefixes configurable via env#118

Closed
taehyeonglim wants to merge 1 commit into
obra:mainfrom
taehyeonglim:feat/env-configurable-embedding-model
Closed

Make embedding model and task prefixes configurable via env#118
taehyeonglim wants to merge 1 commit into
obra:mainfrom
taehyeonglim:feat/env-configurable-embedding-model

Conversation

@taehyeonglim

Copy link
Copy Markdown

Why

The default embedding model (Xenova/bge-small-en-v1.5) is English-only. On non-English corpora, retrieval quality collapses. A/B on a Korean-language corpus (3,862 real Claude Code conversations, same pre-registered queries, hit@3 against known-answer sessions):

model primary-gate hit@3
bge-small-en-v1.5 (default) 1/3 (similarity band compressed to 54–68%)
multilingual-e5-small (384-dim, q8) 3/3

What

Three env overrides, all defaulting to current behavior — no behavior change unless set:

  • EPISODIC_MEMORY_EMBEDDING_MODEL (default Xenova/bge-small-en-v1.5; must stay 384-dim)
  • EPISODIC_MEMORY_EMBEDDING_QUERY_PREFIX (default: BGE sentence prefix; e5-family wants query: )
  • EPISODIC_MEMORY_EMBEDDING_PASSAGE_PREFIX (default ""; e5-family wants passage: , applied before the 2000-char truncation)

Docs cover the 384-dim constraint and the reindex-after-switching caveat (EMBEDDING_VERSION is not bumped by env changes). Tests: test/embedding-env.test.ts — override, ?? empty-string semantics, idempotency under an overridden prefix. Subset run (embedding-env + query-prefix): 7/7.

Happily running this in production against a mixed Korean/English corpus. Thanks for the tool — the conversation-archive design saved us from Claude Code's ~30-day transcript cleanup.

🤖 Generated with Claude Code

The default embedding model (Xenova/bge-small-en-v1.5) is English-only.
On non-English corpora retrieval quality collapses: in an A/B on a
Korean-language corpus (same conversations, same pre-registered queries),
the default model placed the right conversation in the top-3 for 1/3
queries, while Xenova/multilingual-e5-small (also 384-dim) scored 3/3.

Adds three env overrides, all defaulting to current behavior:
- EPISODIC_MEMORY_EMBEDDING_MODEL
- EPISODIC_MEMORY_EMBEDDING_QUERY_PREFIX
- EPISODIC_MEMORY_EMBEDDING_PASSAGE_PREFIX

Docs cover the 384-dim constraint and the reindex-after-switching caveat.
Adds test/embedding-env.test.ts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 5, 2026 22:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes the embeddings layer configurable via environment variables so non-English corpora can use a multilingual encoder (and appropriate task prefixes) without changing code, while keeping defaults identical to today.

Changes:

  • Add env-driven overrides for embedding model id, query prefix, and passage prefix in src/embeddings.ts.
  • Add a new Vitest suite covering query-prefix env override behavior and module reload semantics.
  • Document the new configuration and caveats in README.md, and record the change in CHANGELOG.md.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/embeddings.ts Reads embedding model/prefix configuration from env and applies passage prefix during exchange embedding generation.
test/embedding-env.test.ts Adds tests for env-driven query prefix overrides and idempotency.
README.md Documents how to configure multilingual embedding models and prefixes, plus reindex caveats.
CHANGELOG.md Adds an Unreleased entry describing the new env configuration knobs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/embeddings.ts
Comment on lines +31 to +35
const MODEL_ID = process.env.EPISODIC_MEMORY_EMBEDDING_MODEL || 'Xenova/bge-small-en-v1.5';
const MODEL_DTYPE = 'q8';
export const BGE_QUERY_PREFIX = 'Represent this sentence for searching relevant passages: ';
export const BGE_QUERY_PREFIX =
process.env.EPISODIC_MEMORY_EMBEDDING_QUERY_PREFIX ??
'Represent this sentence for searching relevant passages: ';
Comment thread src/embeddings.ts
}

return generateEmbedding(combined);
return generateEmbedding(PASSAGE_PREFIX + combined);
Comment thread src/embeddings.ts
Comment on lines 99 to +101
}

return generateEmbedding(combined);
return generateEmbedding(PASSAGE_PREFIX + combined);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants