algonotes_rag/issues/IJVLRZ.md

5.6 KiB
Raw Permalink Blame History

Gitee.AI Embedding API 单次请求 input 数组元素数量限制

Issue: https://gitee.com/moark/feedback/issues/IJVLRZ

关联上游 Issue#IJUQ06

背景

上游 Issue IJUQ06 描述了 LangChain OpenAIEmbeddings 使用 tiktoken 将文本编码为 token ID 列表后发送到 Gitee.AI /v1/embeddings 时返回 400 错误的问题。Gitee.AI 已对此进行了修复。

但我们在实际使用时发现,即使关闭了 tiktokentiktoken_enabled=False),某些大文件仍然返回同样的 400 错误。经过排查,发现了一个更深层的 schema 限制。

排查过程

第一阶段6/19误判为 tiktoken 格式问题

使用边界测试脚本验证:

import tiktoken
from openai import OpenAI

client = OpenAI(api_key="...", base_url="https://ai.gitee.com/v1")
enc = tiktoken.get_encoding("cl100k_base")
tokens = enc.encode("树状数组是一种支持单点修改和区间查询的数据结构。")

for n in [25, 26]:
    payload = [tokens for _ in range(n)]
    try:
        client.embeddings.create(model="Qwen/Qwen3-Embedding-4B", input=payload)
        print(f"  {n} 批: ✅")
    except Exception as e:
        print(f"  {n} 批: ❌ {e.response.status_code}")

结果:

--- Gitee.AI ---
  25 批: ✅ dim=1024, 返回 25 个向量
  26 批: ❌ 400 {"error":{"code":"400","message":"[Bad Request] Validation error for body application/json: No schema matches, </input>","type":"server_error"}}

--- SiliconFlow ---
  25 批: ✅ dim=2560, 返回 25 个向量
  26 批: ✅ dim=2560, 返回 26 个向量

修复:加 tiktoken_enabled=False 让 LangChain 发送字符串格式。

第二阶段6/21发现字符串格式同样受限

加了 tiktoken_enabled=False 后 30 个 chunks 仍然 400。深入排查发现

即使是 30 个纯字符串 发送给 Gitee.AI同样返回 400。

这说明限制不是 tiktoken 格式的问题,而是 Gitee.AI 的 /v1/embeddingsinput 数组的元素数量有硬性上限。

最终验证8 组对比实验

使用 test/test_provider_comparison.py 进行 2×2×2 对比:

"""
test_provider_comparison.py — 8 组实验对比 Gitee.AI vs SiliconFlow

测试两种 input 格式(字符串 / token ID× 两种数量25 / 26× 两个平台。

用法uv run python -m test.test_provider_comparison
"""python
import os
from dotenv import load_dotenv
load_dotenv()

import tiktoken
from openai import OpenAI

enc = tiktoken.get_encoding("cl100k_base")
tokens = enc.encode("树状数组是一种支持单点修改和区间查询的数据结构。")
model = "Qwen/Qwen3-Embedding-4B"

providers = [
    ("Gitee.AI",    "https://ai.gitee.com/v1",       os.getenv("GITEE_API_KEY", "")),
    ("SiliconFlow", "https://api.siliconflow.cn/v1",  os.getenv("SiliFlow_API_KEY", "")),
]

for name, base_url, api_key in providers:
    client = OpenAI(api_key=api_key, base_url=base_url)
    for n in [25, 26]:
        texts = [f"测试文本_{i}" for i in range(n)]
        try:
            r = client.embeddings.create(model=model, input=texts)
            print(f"{name} str ×{n}: ✅ dim={len(r.data[0].embedding)}")
        except Exception as e:
            print(f"{name} str ×{n}: ❌ {e.response.status_code}")

        batch = [tokens for _ in range(n)]
        try:
            r = client.embeddings.create(model=model, input=batch)
            print(f"{name} tkn ×{n}: ✅ dim={len(r.data[0].embedding)}")
        except Exception as e:
            print(f"{name} tkn ×{n}: ❌ {e.response.status_code}")

输出结果

平台             格式               结果         维度
───────────────────────────────────────────────────────
Gitee.AI       str ×25          ✅          dim=1024
Gitee.AI       str ×26          ❌  400
Gitee.AI       tkn ×25          ✅          dim=1024
Gitee.AI       tkn ×26          ❌  400
SiliconFlow    str ×25          ✅          dim=2560
SiliconFlow    str ×26          ✅          dim=2560
SiliconFlow    tkn ×25          ✅          dim=2560
SiliconFlow    tkn ×26          ✅          dim=2560

结论

单次请求中 input 元素数 Gitee.AI SiliconFlow
125字符串或 token IDs
≥26(字符串或 token IDs 400
  • Gitee.AI 的限制与 input 元素类型无关纯数组长度限制≤25
  • SiliconFlow 无此限制
  • 同一模型在两家平台的输出维度不同Gitee.AI 1024 维SiliconFlow 2560 维

切换平台后需重建 Chroma 索引,但是不影响复现 API 错误。

当前修复(客户端侧)

核心修复是 chunk_size=25,同时保留 tiktoken_enabled=False 作为兜底:

from langchain.embeddings import init_embeddings

embeddings = init_embeddings(
    model="Qwen/Qwen3-Embedding-4B",
    provider="openai",
    openai_api_key="...",
    base_url="https://ai.gitee.com/v1",
    tiktoken_enabled=False,              # 禁用 tiktoken 编码(兜底)
    check_embedding_ctx_length=False,    # 跳过上下文长度检查
    chunk_size=25,                       # ★ 关键修复:每批最多 25 条
)

chunk_size=25 让 LangChain 的 embed_documents 将 30 个文本分成 25+5 两批发,每批都在 Gitee.AI 的限制范围内。

上游修复建议

Gitee.AI 需要在 /v1/embeddings 的 schema 定义中放宽对 input 数组元素数量的限制,至少达到与 OpenAI 兼容的水平(单批 2048 条)。