当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > OpenAI Embeddings 怎样按批量输入组织请求

OpenAI Embeddings 怎样按批量输入组织请求

来源:17golang原创 2026-10-26 02:35:58 0浏览 收藏

当待向量化的文本从几十条增长到几千条时,最稳妥的做法不是把它们拼成一段超长字符串,而是把多条字符串作为同一个 Embeddings 请求的 input 数组,并在本地控制每批的数量和 token 预算。这样每个向量仍然对应一条原始记录,某一批失败时也只需要处理这一批。

官方地址:https://developers.openai.com/api/docs/guides/embeddings

要点速览
  • 批量输入使用字符串数组;批次大小是工程策略,不等于服务端固定值。
  • 每条输入要控制在模型上限内,单次请求还要关注所有输入合计 token。
  • 用返回项的 index 绑定原始记录,向量维度固定后再写入下游存储。

多条文本应该怎样进入同一个 Embeddings 请求

OpenAI Embeddings 的 input 可以是一个字符串,也可以是字符串数组。数组中的每个元素代表一条独立文本,返回结果会在 data 中给出对应的 embedding 项。这个模型更适合“多条记录分别向量化”,而不是把标题、正文和其他记录拼在一起后失去记录边界。

官方 API reference 给出了两个需要同时考虑的输入边界:所有 embedding 模型单条输入最多 8192 tokens;单次请求中所有输入合计最多 300000 tokens。下面的 64 条只是一个便于控制失败范围的起始批次,不是硬性规定。短文本可以适当增大,长文本或限流敏感的任务则应该减小。

OpenAI Embeddings 原始文本、批次切片、input 数组与输入 token 边界的静态关系说明图
图1:批量输入边界说明图,展示文本数组、请求边界和输入额度的关系。

先按可控数量切出批次

先把空字符串过滤掉,再用固定的 max_items 切片。这里不在示例中假装用字符数精确代替 token 数;如果文本长度差异很大,应在切批前接入与模型匹配的 tokenizer,或者降低单批数量,给合计 token 留出余量。

from openai import OpenAI

client = OpenAI()


def split_batches(texts: list[str], max_items: int = 64):
    """把非空文本切成小批次,控制一次失败影响的记录范围。"""
    # 过滤空白输入,避免把无意义文本发送到接口。
    cleaned = [text.strip() for text in texts if text and text.strip()]
    for start in range(0, len(cleaned), max_items):
        # max_items 是本地工程策略,不代表接口的固定批量上限。
        yield cleaned[start:start + max_items]


def embed_texts(texts: list[str]) -> list[list[float]]:
    """按批次提交文本,并按返回 index 放回连续结果列表。"""
    results: list[list[float] | None] = [None] * len(
        [text for text in texts if text and text.strip()]
    )
    offset = 0

    for batch in split_batches(texts):
        try:
            response = client.embeddings.create(
                model="text-embedding-3-small",
                input=batch,
                encoding_format="float",
            )
            # 返回 index 是批次内位置,必须加上本批在全量结果中的偏移量。
            for item in response.data:
                results[offset + item.index] = item.embedding
            offset += len(batch)
        except Exception:
            # 真实任务中记录 batch 起点并重试当前批次,不要悄悄跳过。
            raise

    # 让调用方尽早发现批次回填不完整,而不是把 None 写入向量库。
    if any(vector is None for vector in results):
        raise RuntimeError("embedding result is incomplete")
    return [vector for vector in results if vector is not None]

这段代码有两个容易忽略的点。第一,空文本过滤后,结果数组的长度必须以清洗后的文本为准。第二,item.index 是当前批次内的索引,所以要加上 offset 才能定位到全量结果中的位置。生产环境可以把当前批次的起点、请求参数和异常类型写入任务日志,重试时只重试该批次。

为什么要用返回的 index 还原记录顺序

向量不是脱离业务记录独立存在的。写入数据库或向量存储时,通常还需要保留文章 ID、商品 ID或文档版本。最简单的安全做法是为每条输入保留一个业务主键,并用批次内位置建立临时映射;收到响应后,以 data.index 找回原记录,而不是直接假定返回数组永远按照你的输入顺序排列。

OpenAI Embeddings 返回 data.index 将 embedding 绑定回 record_id 的静态关系图
图2:索引回填结构图,展示返回 index 如何把向量绑定回原始记录。
字段用途处理建议
record_id业务记录身份始终和向量一起保存
batch index当前批次内位置只作为临时回填键
data.index响应中的位置映射回本批输入
dimensions向量长度写入下游前固定并记录

失败批次和 dimensions 怎么处理

批量请求的好处是减少请求次数,代价是单次失败会影响一组记录。因此建议把每批当成独立任务:保存批次起止位置,成功后再提交下游;失败时只重试当前批次,并设置有限次数与退避。不要在异常分支里继续把未知长度的结果写入向量存储。

text-embedding-3-small 默认返回 1536 维,text-embedding-3-large 默认返回 3072 维;官方指南说明,dimensions 可以用于 text-embedding-3 及更新模型,以换取更小的存储与计算开销。这个参数一旦用于生产索引,就应该和向量库的 schema、相似度计算及后续查询保持一致,不能只在写入时临时改变。

def build_request(batch: list[str], dimensions: int | None = None) -> dict:
    """构造一个可记录、可重试的请求参数。"""
    # 请求前再次检查空批次,避免把无效任务交给远端接口。
    if not batch:
        raise ValueError("batch must not be empty")

    payload = {
        "model": "text-embedding-3-small",
        "input": batch,
        "encoding_format": "float",
    }
    if dimensions is not None:
        # dimensions 只应在选定模型和下游 schema 都支持时设置。
        payload["dimensions"] = dimensions
    return payload

常见问题

把多条文本拼成一个字符串和传入字符串数组有什么区别?

拼成一个字符串只会得到一个输入对应的向量;传入字符串数组则让每个元素保持独立记录边界,并在响应中得到多个 embedding 项。

批次越大越省请求吗?

通常会减少请求次数,但会增加单次失败影响范围,也更容易触碰总 token、限流或超时边界。应按文本长度和重试成本选择,而不是只追求更大的数组。

能不能只按字符串长度判断 token?

不能把字符数当成精确 token 数。文本差异明显时应使用匹配模型的 tokenizer,或降低批次并为合计 token 预留余量。

dimensions 设小后还能和旧向量混用吗?

不要默认可以。向量长度和模型配置应作为索引契约的一部分;切换维度前先规划重建、分区或版本化策略。

批量 Embeddings 的核心不是把数组做大,而是保持三条边界:输入记录不混淆、每批额度可控、返回索引能回到业务主键。沿着这三条边界组织代码,后续无论接入检索、聚类还是推荐,都更容易定位失败和迁移模型。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Hugging Face Hub 怎样固定模型修订版本Hugging Face Hub 怎样固定模型修订版本
上一篇
Hugging Face Hub 怎样固定模型修订版本
OpenAI API 怎样为结构化输出定义 JSON Schema
下一篇
OpenAI API 怎样为结构化输出定义 JSON Schema
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    694次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    706次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    775次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    734次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    568次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码