Skip to content

fix: UniversalAPIEmbedder silently ignores embedding_dims and never passes dimensions to the OpenAI API #2177

Description

@Evenss

Pre-submission checklist | 提交前检查

  • I have searched existing issues and this hasn't been mentioned before | 我已搜索现有问题,确认此问题尚未被提及
  • I have read the project documentation and confirmed this issue doesn't already exist | 我已阅读项目文档并确认此问题尚未存在
  • This issue is specific to MemOS and not a general software issue | 该问题是针对 MemOS 的,而不是一般软件问题

Bug Description | 问题描述

UniversalAPIEmbedderConfig accepts an embedding_dims field, but UniversalAPIEmbedder.embed() never forwards it: client.embeddings.create() is called with only model and input (src/memos/embedders/universal_api.py, both primary and backup calls), with no warning — even though the OpenAI embeddings API natively supports the dimensions parameter.

Consequence: if the vector DB collection is created with vector_dimension: 1536 and embedding_dims: 1536 is set, but the model's default output is 1024 (e.g. Qwen text-embedding-v4), every insert fails with an obscure dimension-mismatch error from the vector DB, with no hint that embedding_dims was silently dropped.

Expected behavior: when embedding_dims is set, pass it as dimensions to the API (omit when None for backward compatibility).

How to Reproduce | 如何重现

Minimal reproduction without any real API key (mock proves the parameter is never forwarded):

from unittest.mock import MagicMock, patch

from memos.configs.embedder import EmbedderConfigFactory
from memos.embedders.factory import EmbedderFactory

config = EmbedderConfigFactory.model_validate({
    "backend": "universal_api",
    "config": {
        "provider": "openai",
        "api_key": "sk-dummy",
        "base_url": "https://api.openai.com/v1",
        "model_name_or_path": "text-embedding-3-large",
        "embedding_dims": 1536,   # <-- user explicitly requests 1536 dims
    },
})
embedder = EmbedderFactory.from_config(config)
print("config.embedding_dims =", embedder.config.embedding_dims)

fake_response = MagicMock()
fake_response.data = [MagicMock(embedding=[0.0] * 3072)]
with patch.object(embedder.client.embeddings, "create", return_value=fake_response) as mock_create:
    embedder.embed(["hello"])
    print("kwargs actually sent to OpenAI API:", mock_create.call_args.kwargs.keys())
    print("'dimensions' passed?", "dimensions" in mock_create.call_args.kwargs)

Actual output:

config.embedding_dims = 1536
kwargs actually sent to OpenAI API: dict_keys(['model', 'input'])
'dimensions' passed? False

Live-API confirmation (OpenAI-compatible endpoint, model text-embedding-v4, embedding_dims: 1536 configured):

requested embedding_dims = 1536
actual vector dimension  = 1024

End-to-end symptom: configure general_text memory with a 1536-dim vector DB collection + universal_api embedder (text-embedding-v4, default 1024 dims) → m.add() fails with a dimension-mismatch error from the vector DB.

Environment | 环境信息

  • Python version: 3.13.0
  • Operating System: Linux (kernel 5.10)
  • MemOS version: 2.0.25

Additional Context | 其他信息

Suggested fix in UniversalAPIEmbedder.embed() (both primary and backup calls):

kwargs = {}
if self.config.embedding_dims is not None:
    kwargs["dimensions"] = self.config.embedding_dims
response = self.client.embeddings.create(model=..., input=texts, **kwargs)

Willingness to Implement | 实现意愿

  • I'm willing to implement this myself | 我愿意自己解决
  • I would like someone else to implement this | 我希望其他人来解决

Metadata

Metadata

Labels

area:coreMOS 编排层 / 框架底座 / 跨模块问题status:needs-triageNeeds initial triage | 需要初步判断 & 问题复现

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions