调用Embedding模型失败

Spring AI项目使用的Embedding模型是公司平台部署的,请求模型服务的时候报错,返回了HTTP 400 - Invalid HTTP request received错误。然后换成云厂商在线Embedding模型地址,正常调通。我用Apifox直接调用公司的模型服务,能正常调通。当时真的百思不得其解。
在这里插入图片描述

Spring AI客户端排查

Spring AI项目中我用的Http客户端是apachehttpclient5(后面切成netty的也报同样的错误),代码调试没发现有什么异常的地方,然后把httpclient5的日志级别调成debugorg.apache.hc: debug),再次发送请求,有个请求头引起来我的注意。

org.apache.hc.client5.http.wire          : http-outgoing-0 >> "Transfer-Encoding: chunked[\r][\n]"

问了一下AI,这个请求头的意思

Transfer-Encoding: chunked 是一种HTTP分块传输编码。当发送方无法预先知道消息体总长度时(如动态生成内容),可将其分割为多个带大小标记的“块”流式发送。每个块先发十六进制长度,再发数据,以长度为0的块结束。它与Content-Length互斥,不能共存

于是我在Apifox那边也加上这个请求头,调用直接返回同样的错误,去掉就能正常返回向量信息。直接通过Apifox调用在线的Embedding模型地址,并且加上这个请求头,也能成功调通。所以问题大概率出现在公司部署的服务上。因为我找了一圈,也没找到Spring AI有配置相关请求头的地方,所以这种请求方式无法改变(有可能有设置不分块传输的,只是我没发现,我感觉概率应该很低)。

部署的模型服务排查

由于模型是其他部门部署的,所以就去要了一个项目代码,这里称为ProxyA,当时同事告诉我说,这个ProxyA主要是做的代理服务,适配了一下OpenAI的接口格式,项目调用的都是这个服务(说langchain4j是能正常调通的,排除这个服务的问题),再由此服务转发至对应的模型服务(过了两天又拿到了这个服务的代码),模型服务这里称为ModelB

调用过程就是项目—>ProxyA—>ModelB

ProxyA排查

ProxyA使用的是Flask框架,处理/embeddings地址的方法是emb()

@api_blueprint.route('/embeddings', methods=['POST'])
def emb():

拿到ProxyA代码之后,项目请求我本地的ProxyA地址,再次发送请求,成功的进入到了emb()里面。也就是说,调用ProxyA是没有问题的,是ProxyA调用ModelB出了问题。
后面debug到了一段关键的代码,这个代码就是把项目的请求转发到ModelB服务,关键是这个请求头,没做什么处理,就直接转发给了ModelB服务

def emb():# 省略......# 调用具体的模型服务地址,并且把接收到的请求头放进去resp = requests.post(ModelB_url, headers=headers, json=data, timeout=10)return .....

后面在转发请求代码之前处理了一下,代码如下:

def emb():# 省略......# 如果存在Transfer-Encoding: chunked,就去掉,然后加上Content-Length头if 'Transfer-Encoding' in headers and headers['Transfer-Encoding'] == 'chunked':# 移除Transfer-Encoding头部del headers['Transfer-Encoding']# 添加Content-Length头部import json as json_modulecontent_length = len(json_module.dumps(data).encode('utf-8'))headers['Content-Length'] = str(content_length)# 调用具体的模型服务地址,并且把接收到的请求头放进去resp = requests.post(ModelB_url, headers=headers, json=data, timeout=10)return .....

处理之后,再次调用,发现Spring AI项目可以正常调用公司部署的Embedding模型了

ModelB排查

后面要到ModelB服务的git权限之后,拉取代码本地试了一下,项目可以直接调通ModelB服务,不再报HTTP 400 - Invalid HTTP request received错误,只是因为格式不对,报了其他的错误。所以ModelB服务也是没有问题的。就是ProxyA服务请求转发的时候出了问题。
没拿到ModelB代码之前,还一顿怀疑是ModelB出了问题,纠结要不要去掉ProxyA里面的那段处理代码(毕竟不是专业Python开发😂)。

总结

ProxyA接收到分块传输请求之后,通过requests.post转发请求的时候,由于没有对请求头进行过滤,导致转发的请求头中存在Transfer-Encoding: chunked,所以调用ModelB的时候出现无效Http请求的异常。
进到emb()方法中,实际项目对ProxyA的请求已经被完整接收了,也就是数据都传输过来了,但是requests.post转发的时候,json是一个确定的对象,可以明确大小的,也就是转发的时候压根不是分块请求,头部又设置成了分块传输,自然就有问题了。由于我不是python开发,这段话有说的不对的,还望大佬们指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/91741.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/91741.shtml
英文地址,请注明出处:http://en.pswp.cn/web/91741.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pytorch-02数据集和数据加载器的基本原理和基本操作

1. 为什么要有数据集类和数据加载器类? 一万个人会有一万种获取并处理原始数据样本的代码,这会导致对数据的操作代码标准不一,并且很难复用。为了解决这个问题,Pytorch提供了两种最基本的数据相关类: torch.utils.data…

无图形界面的CentOS 7网络如何配置

进入虚拟机输入ip addr命令:从 ip addr命令的输出可以明确看出 ​​lo和 ens33是两个不同的网络接口(网卡)lo(回环接口)​​​​作用​​:虚拟的本地回环网卡,用于本机内部通信(如 1…

机器学习之线性回归的入门学习

线性回归是一种监督学习算法,用于解决回归问题。它的目标是找到一个线性关系(一条直线或一个超平面),能够最好地描述一个或多个自变量(特征)与一个因变量(目标)之间的关系。利用回归…

2-5 Dify案例实践—利用RAG技术构建企业私有知识库

目录 一、RAG技术的定义与作用 二、RAG技术的关键组件 三、RAG技术解决的问题 四、RAG技术的核心价值与应用场景 五、如何实现利用RAG技术构建企业私有知识库 六、Dify知识库实现详解 七、创建知识库 1、创建知识库 2、上传文档 3、文本分段与清洗 4、索引方式 5、…

断路器瞬时跳闸曲线数据获取方式

断路器瞬时短路电流时,时间是在60ms内的,仿真器去直接捕获电流有效值很难。按照电流互感器的电流曲线特性,电流越大,由于互感器饱和,到达一定电流值的时候,电流会趋于平稳不再上升,ADC-I曲线由线…

技巧|SwanLab记录混淆矩阵攻略

绘制混淆矩阵(Confusion Matrix),用于评估分类模型的性能。混淆矩阵展示了模型预测结果与真实标签之间的对应关系,能够直观地显示各类别的预测准确性和错误类型。 混淆矩阵是评估分类模型性能的基础工具,特别适用于多…

HTTPS的工作原理

文章目录HTTP有什么问题?1. 明文传输,容易被窃听2. 无法验证通信方身份3. 数据完整性无法保证HTTPS是如何解决这些问题的?HTTPS的工作原理1. SSL/TLS握手2. 数据加密传输3. 完整性保护4. 连接关闭总结HTTP有什么问题? 1. 明文传输…

ECMAScript2020(ES11)新特性

概述 ECMAScript2020于2020年6月正式发布, 本文会介绍ECMAScript2020(ES11),即ECMAScript的第11个版本的新特性。 以下摘自官网:ecma-262 ECMAScript 2020, the 11th edition, introduced the matchAll method for Strings, to produce an …

机器视觉引导机器人修磨加工系统助力芯片封装

芯片制造中,劈刀同轴度精度对封装质量至关重要。传统加工在精度、效率、稳定性、良率及操作便捷性上存在不足:精度不足:劈刀同轴度需控在 0.003mm 内,传统手段难达标,致芯片封装良率低;效率良率低 &#xf…

Python编程基础与实践:Python模块与包入门实践

Python模块与包的深度探索 学习目标 通过本课程的学习,学员将掌握Python中模块和包的基本概念,了解如何导入和使用标准库中的模块,以及如何创建和组织自己的模块和包。本课程将通过实际操作,帮助学员加深对Python模块化编程的理解…

【Django】-4- 数据库存储和管理

一、关于ORM ORM 是啥呀ORM 就是用 面向对象 的方式,把数据库里的数据还有它们之间的关系映射起来~就好像给数据库和面向对象之间搭了一座小桥梁🎀对应关系大揭秘面向对象和数据库里的东西,有超有趣的对应呢👇类 → 数…

深入 Go 底层原理(四):GMP 模型深度解析

1. 引言在上一篇文章中,我们宏观地了解了 Go 的调度策略。现在,我们将深入到构成这个调度系统的三大核心组件:G、M、P。理解 GMP 模型是彻底搞懂 Go 并发调度原理的关键。本文将详细解析 G、M、P 各自的职责以及它们之间是如何协同工作的。2.…

AI赋能测试:技术变革与应用展望

AI 在测试中的应用:技术赋能与未来展望 目录 AI 在测试中的应用:技术赋能与未来展望 1. 引言 1.1 测试在软件开发中的重要性 1.2 AI 技术如何改变传统测试模式 1.3 文章结构概述 2. AI 在测试中的核心应用场景 2.1 自动化测试优化 2.1.1 智能测…

Mujoco(MuJoCo,全称Multi - Joint dynamics with Contact)一种高性能的物理引擎

Mujoco(MuJoCo,全称Multi - Joint dynamics with Contact)是一种高性能的物理引擎,主要用于模拟多体动力学系统,广泛应用于机器人仿真、运动学研究、人工智能等领域。以下是关于Mujoco仿真的一些详细介绍: …

winform-窗体应用的功能介绍(部分)

1--Point实现在窗口(Form)中一个按钮(控件)的固定位置(所在位置)一个按钮(控件)的位置一般是固定的,另一个按钮在窗口中位置是随机产生的Location属性:Location new Point(X,Y);在C#的Winform应用程序里,Button控件的鼠标悬标悬浮事件是不存在内置延迟时间的。当鼠标指针进入按…

最新Windows11系统镜像,23H2 64位ISO镜像

Windows 11 主要分为 Consumer Editions(消费者版)和 Business Editions(商业版)两大类别 。消费者版主要面向家庭和个人用户,商业版则侧重于企业和商业用户。这两大类别中存在部分重叠的版本,比如专业版和…

linux基本系统服务——DNS服务

一、DNS域名解析原理DNS&#xff0c;Domain Name System&#xff0c;域名系统&#xff1a;在互联网中由大量域名解析服务器共同提供的一整套关于“域名 <--> IP地址”信息查询的数据系统!!!! C/S架构&#xff1a;DNS服务端监听UDP 53端口&#xff08;处理客户端查询&…

数据处理和统计分析——08 apply自定义函数

1 apply()函数 1.1 apply()函数简介 Pandas提供了很多数据处理的API&#xff0c;但当提供的API不能满足需求的时候&#xff0c;需要自己编写数据处理函数, 这个时候可以使用apply()函数&#xff1b;apply()函数可以接收一个自定义函数&#xff0c;可以将DataFrame的行或列数据传…

C++冰箱管理实战代码

基于C++的冰箱管理实例 以下是一些基于C++的冰箱管理实例示例,涵盖不同功能场景,每个示例聚焦特定实现点,代码可直接扩展或整合到项目中。 示例1:基础冰箱类定义 class Refrigerator { private:int capacity;std::vector<std::string> items; public:Refrigerator(…

【Python】【数据分析】Python 数据分析与可视化:全面指南

目录1. 环境准备2. 数据处理与清洗2.1 导入数据2.2 数据清洗示例&#xff1a;处理缺失值示例&#xff1a;处理异常值2.3 数据转换3. 数据分析3.1 描述性统计3.2 分组分析示例&#xff1a;按年龄分组计算工资的平均值3.3 时间序列分析4. 数据可视化4.1 基本绘图示例&#xff1a;…