使用 Elasticsearch 进行实体解析,第 3 部分:通过函数调用优化 LLM 集成

0 阅读7分钟

作者:来自 Elastic Jessica Moszkowicz  系列内容之一:使用 Elasticsearch 进行实体解析

使用 Elasticsearch 进行实体解析

了解函数调用如何增强 LLM 集成,使你能够在 Elasticsearch 中构建一个可靠且具成本效益的实体解析管道。

Elasticsearch 与行业领先的 Gen AI 工具和提供商具有原生集成。欢迎查看我们关于 “超越 RAG 基础” 的网络研讨会,或了解如何使用 Elastic 向量数据库构建可投入生产的应用

要为你的使用场景构建最佳搜索解决方案,现在即可开始免费的云试用,或在本地机器上体验 Elastic。


在本系列的第 1 部分第 2 部分《使用 Elasticsearch 进行实体解析》中,我们构建了一个完整的实体解析管道,包括:为实体添加上下文并为语义搜索建立索引、使用混合命名实体识别(NER)从文章中提取实体,以及通过语义搜索和大型语言模型(LLM)判断进行匹配。结果令人鼓舞,但 JSON 解析错误显著降低了测量准确率,因为本来有效的判断被丢弃了。系统的问题并不在于判断错误,而在于无法可靠地表达这些判断结果。

问题的根源在于我们采用了一种相对简单的基于提示词的 JSON 生成方式,即让 LLM 以文本格式生成 JSON 响应。如果我们一次让 LLM 判断多个匹配结果,生成的 JSON 往往格式不正确。为缓解这一问题,我们不得不减少处理批次大小,但这在生产系统中无法扩展。

因此,基于提示词的 JSON 生成帮助我们验证了实体解析的方法,但我们需要一种更系统、更可靠的方法。OpenAI 的函数调用(function calling)提供了更优路径,通过保证结构和类型安全来减少错误并降低成本。我们在教学原型中选择了 OpenAI 的函数,但其他 LLM 提供商通常也提供类似功能(例如 Claude 的 tools)。

注意:虽然这里讨论了生产环境中的挑战,但这仍然是一个展示优化技术的教学原型。真正的生产系统还需要额外考虑,例如监控、告警、回退策略和全面的错误处理。

关键概念:函数调用、模式设计与成本优势

什么是函数调用?

函数调用是 OpenAI 的结构化输出 API。通过它,我们可以为 LLM 的响应定义模式(schema),从而始终清楚将获得什么结果。通过强制 JSON 结构,而不是在提示词中尝试定义它,我们可以消除解析错误。

为什么它优于基于提示词的 JSON?

LLM 生成的输出具有非确定性。我们希望它至少包含正确内容,但其呈现方式是不可预测的。对于聊天机器人来说,这通常不是问题,但我们的原型需要以编程方式处理输出。计算机程序要求一致性,当 LLM 按预期生成内容时一切正常,但只要稍有偏离,代码就会报错。我们可以尝试覆盖各种可能情况,但几乎不可能完全捕获。我们也尝试在提示词中加入 “始终返回可解析的 JSON” 等指令,但实践表明,基于提示词的 JSON 很快就会出问题,尤其是在批量处理匹配时。

函数调用让 LLM 的生成过程变得可控且可预测,这正是实体解析所需要的。为了更好地定义函数,我们还遵循最小化模式设计原则。

什么是最小化模式设计原则?

最小化模式设计意味着仅定义必要字段、使用简单类型,并尽量避免嵌套结构。这可以减少 token 使用量(模式越小,token 越少)、提高可靠性(简单模式更易于 LLM 遵循),并降低成本(token 越少,API 成本越低)。

成本与可靠性优势是什么?

由于错误减少,即使批量较大,匹配处理也更可能成功,因此无需重试判断。减少重试可降低 token 使用,从而降低成本;同时,最小化模式本身也进一步压缩 token 数量。这种方法成本更低、可靠性更高,更适合生产环境。

不过,我们还需要检查一点:虽然匹配处理不再报错,但这些无错误的结果是否真正正确?这种新方法与基于提示词方法中那些令人鼓舞的结果相比如何?

真实世界结果:并列对比

正如我们在上一篇博客中所做的那样,我们使用第 4 级数据集对函数调用方法进行了测试。该数据集包含 69 篇文章中的 206 个预期匹配。结果显示出显著提升:

指标对比如下:

指标基于提示的生成函数调用提升效果
错误率30.2%0.0%100% 消除
准确率(Precision)83.8%90.3%+6.5 百分点
召回率(Recall)62.6%90.8%+28.2 百分点
F1 分数71.7%90.6%+18.9 百分点
接受率44.8%60.2%+15.4 百分点
真阳性(True Positives)129187+45.0%
假阴性(False Negatives)7719-75.3%

这些结果显示,函数调用不仅显著提高了实体匹配的准确性和召回率,而且完全消除了 JSON 解析错误,使整个流程更加稳定且适用于生产环境。

错误消除:关键差异

最显著的差异是 JSON 解析错误被完全消除。这带来了适度的准确率提升,以及更为显著的召回率提升。准确率(Precision)衡量的是系统接受的匹配中,有多少是在黄金标准文档中预期出现的。因此,在基于提示的方案中,原型在判断匹配是否正确方面表现尚可,而函数调用进一步提升了这一能力。

相反,召回率(Recall)衡量的是预期匹配中有多少被成功找回。当一批匹配结果返回格式错误的 JSON 时,系统会丢失整批匹配。很可能 Elasticsearch 已经将这些匹配发送进行判断,但一旦判断失败,这些匹配就全部丢失。显著提升的召回率证明了这一假设是正确的:Elasticsearch 负责识别潜在匹配,而函数调用负责验证哪些匹配是正确的。

注意:Elasticsearch 找到一些错误匹配是预期中的,因为我们会查看混合搜索返回的前两到三个结果。大多数情况下,混合搜索会将正确匹配作为首个结果返回,但让 LLM 判断前几个候选可以帮助我们观察 LLM 如何处理错误匹配。如果从教学原型过渡到生产系统,我们可能会更精细地调整 Elasticsearch 查询,只将最有希望的匹配发送给 LLM,从而进一步优化 LLM 成本。

接下来:终极挑战

现在,我们已经通过函数调用优化了 LLM 集成,构建了一个可靠性和成本效率都更高的完整实体解析管道。但它是否能够应对终极挑战?在下一篇文章中,我们将探讨该系统如何在 50 种不同挑战类型下处理多样化的实体解析场景,包括文化命名惯例、商业关系、头衔以及多语言变体。

亲自尝试

想亲眼看看函数调用优化的实际效果吗?欢迎查看 “Function Calling Optimization” 笔记本,其中包含完整的实现演示、详细说明以及可动手实践的示例。该笔记本将向你展示如何使用函数调用实现结构化输出,与基于提示的 JSON 方法进行对比,并分析成本与可靠性优势。

请记住:这是一个用于讲解优化概念的教学原型。在构建生产系统时,还需考虑多供应商支持、高级缓存策略、监控与告警、全面的错误处理,以及本学习型原型未涵盖的合规要求等额外因素。

原文:www.elastic.co/search-labs…