You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Search自定义OCR技能merged_content文本合并顺序异常问题

问题根因

偏移插入失效核心是两个配置/逻辑错误:

  1. 技能执行顺序配置错误
  2. 自定义WebApi技能输出逻辑不符合自定义技能的1:1映射规则,导致MergeSkill无法匹配图片文本和对应偏移量,最终把所有OCR文本统一追加到原生文本末尾。

1. 技能执行顺序错误

Azure Cognitive Search的技能严格按照skills数组的从上到下顺序执行,你当前配置把MergeSkill放在自定义OCR技能前面:执行MergeSkill时,自定义OCR技能还未运行,/document/normalized_images/*/text路径下没有任何值,等后续OCR技能跑完生成text字段,MergeSkill早已执行完成,自然不会触发按偏移插入的逻辑。

官方示例中内置OCR技能始终放在MergeSkill之前,你参考配置时遗漏了顺序调整。

2. 自定义技能输出绑定错误

你的自定义技能context设置为/document/normalized_images/*,意味着Search会把文档拆分出的每一张内嵌图片作为独立请求记录发送给WebApi,每条请求的RecordId和单个图片节点一一绑定。而contentOffset根本不是内置OCR输出的特殊字段,是Search在PDF解析、拆分内嵌图片阶段,自动给每个normalized_images节点生成的原生属性,标记当前图片在原文档文本流中的位置。
你当前的C#代码逻辑存在明显问题:拿到单张图片的请求后,循环Read API返回的所有页识别结果,给同一个RecordId追加了多条输出值,直接破坏了自定义技能单条输入对应单条输出的规则,最终导致扩充树中/document/normalized_images/*/text集合的顺序,和同路径下contentOffset集合的顺序完全错位,MergeSkill匹配不到正确的(文本、偏移量)对,就会触发兜底逻辑,把所有待插入文本统一追加到原生文本末尾。


修复步骤

第一步:调整技能集执行顺序

把自定义WebApi OCR技能挪到MergeSkill之前,保证先生成图片OCR文本,再执行合并逻辑,调整后的技能数组参考:

"skills": [
  {
    "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
    "name": "#2",
    "context": "/document/normalized_images/*",
    "inputs": [
      {
        "name": "image",
        "source": "/document/normalized_images/*"
      }
    ],
    "outputs": [
      {
        "name": "text",
        "targetName": "text"
      }
    ]
  },
  {
    "@odata.type": "#Microsoft.Skills.Text.MergeSkill",
    "name": "#1",
    "context": "/document",
    "insertPreTag": " ",
    "insertPostTag": " ",
    "inputs": [
      {
        "name": "text",
        "source": "/document/content"
      },
      {
        "name": "itemsToInsert",
        "source": "/document/normalized_images/*/text"
      },
      {
        "name": "offsets",
        "source": "/document/normalized_images/*/contentOffset"
      }
    ],
    "outputs": [
      {
        "name": "mergedText",
        "targetName": "merged_content"
      }
    ]
  }
]

第二步:修正自定义WebApi的返回逻辑

不需要循环Read API返回的所有页结果,单条请求只对应单张图片,你只需要返回当前请求对应单张图片的OCR结果,和传入的RecordId一一对应即可,禁止给同一个RecordId返回多条输出值。修正后的返回逻辑参考:

// 单条请求对应单张图片,仅处理当前传入的单张图
var ocrResult = await CallReadApiForSingleImage(value.Data.image); // 替换为你的单图Read API调用逻辑
var responseValue = new
{
    RecordId = value.RecordId,
    Data = new
    {
        text = string.Join(" ", ocrResult.Lines?.Select(x => x.Text))
    }
};
output.Values.Add(responseValue);

return new OkObjectResult(output);

结果验证

修改完成后可通过搜索服务的技能调试工具查看文档扩充树,确认两个状态:

  • 每个/document/normalized_images/*节点下有且仅有一个text字段,值为当前图片的OCR结果
  • 每个节点下的contentOffset数值和图片在文档中的位置顺序匹配(文档中越靠前的图片,offset值越小)
    满足以上两个条件,MergeSkill就会自动按照偏移量把OCR文本插入到原生文本的对应位置,不会出现所有图片文本堆在末尾的问题。

内容的提问来源于stack exchange,提问作者michasaucer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 20:48:28