diff --git a/apps/models_provider/base_model_provider.py b/apps/models_provider/base_model_provider.py index a11a31ec49c..c8562f58aaa 100644 --- a/apps/models_provider/base_model_provider.py +++ b/apps/models_provider/base_model_provider.py @@ -134,6 +134,23 @@ def embed_images(self, images: List[str]) -> List[List[float]]: """Embed data URLs or provider-supported image URLs.""" raise AppApiException(500, _("The current embedding model does not support image embedding")) + @staticmethod + def normalize_image_input(url: str, keep_data_prefix: bool = False) -> str: + """归一化图片输入为上游接口可识别的字符串。 + + - http(s) URL:原样返回 + - data:image/...;base64,xxx:keep_data_prefix=True 保留 data URI(阿里百炼等), + False 只返回 base64 内容(腾讯 TokenHub 等) + - 其它字符串:视为已是目标格式,原样返回 + """ + if url.startswith(("http://", "https://")): + return url + if url.startswith("data:") and ";base64," in url: + if keep_data_prefix: + return url + return url.split(";base64,", 1)[1] + return url + class BaseModelCredential(ABC): @abstractmethod diff --git a/apps/models_provider/impl/aliyun_bai_lian_model_provider/model/embedding.py b/apps/models_provider/impl/aliyun_bai_lian_model_provider/model/embedding.py index c38bb790756..e9920c57668 100644 --- a/apps/models_provider/impl/aliyun_bai_lian_model_provider/model/embedding.py +++ b/apps/models_provider/impl/aliyun_bai_lian_model_provider/model/embedding.py @@ -71,7 +71,9 @@ def embed_images(self, images: List[str]) -> List[List[float]]: """对图片 URL / data URL 做独立向量化(每张图生成一个向量)。""" if not self.supports_image_embedding(): return [] - return self._call_multimodal([{"image": image} for image in images]) + return self._call_multimodal( + [{"image": self.normalize_image_input(image, keep_data_prefix=True)} for image in images] + ) def _multimodal_base_url(self) -> str: """DashScope 原生多模态接口走 /api/v1,与 OpenAI 兼容地址区分开。""" diff --git a/apps/models_provider/impl/tencent_model_provider/model/embedding.py b/apps/models_provider/impl/tencent_model_provider/model/embedding.py index 8357a30a76a..5b97568032c 100644 --- a/apps/models_provider/impl/tencent_model_provider/model/embedding.py +++ b/apps/models_provider/impl/tencent_model_provider/model/embedding.py @@ -77,7 +77,19 @@ def embed_query(self, text: str) -> List[float]: def embed_images(self, images: List[str]) -> List[List[float]]: if not self.supports_image_embedding(): return [] - return [self._embed_multimodal([{"type": "image_url", "image_url": {"url": url}}]) for url in images] + return [ + self._embed_multimodal([{"type": "image_url", "image_url": {"url": self._to_base64_content(url)}}]) + for url in images + ] + + @staticmethod + def _to_base64_content(url: str) -> str: + """TokenHub 的 image_url.url 接受 URL 或 base64 内容。 + + MaxKB 传入的图片是 data:image/...;base64,xxx 形式的 data URL, + 这里剥掉 data: 前缀,转换为纯 base64 内容再交给接口。 + """ + return MaxKBBaseEmbeddingModel.normalize_image_input(url, keep_data_prefix=False) def _embed_multimodal(self, items: list) -> List[float]: payload = {"model": self.model_name, "input": items, "encoding_format": "float", **self.params}