一、场景

大模型功能需要计算向量,对数据进行向量化处理,在使用sdk接口进行批量处理向量操作时报错如下:

服务器异常syntax error, expect {, actual string, fieldName data, pos 315, line 1, column 316{"status":400,"code":400,"success":false,"data":"JSON parse error: Unexpected end-of-input in VALUE_STRING; nested exception is com.fasterxml.jackson.core.io.JsonEOFException: Unexpected end-of-input in VALUE_STRING\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 2563]","msg":"参数校验失败"}

二、问题分析

    初看这个问题,以为是json 数据格式有问题,然后就投入到具体的json 数据分析中,只是这种事批量入库的,每次1000条,怎么定位到哪一条?然后就开始尝试减少每次插入的数量,试了几次最终才找到了一条记录,然后就开发分析这个数据。这种数据都是文档分段后的内容,各种回车换行转义的,但是将数据拿到JSON 格式数据校验工具中格式化,直接返回 老铁,没毛病,格式正确。

然后就有点开始傻眼了,于是就问AI 了。刚开始AI 看这个数据,就说是被截断,不完整,我理解是以为文档分段造成的语义不完整截断,然后就告诉AI 这个分段造成的,于是AI 又给了其他思路,反正从spring nginx 传统的http 传输大小限制开始,一路排查,最终都不对。

  最终还是老老实实断点调试,发现问题点:

这里面传入过来的body 已经正常日志输出, 只是这个result调用返回的结果报错,所以这个json 数据原始的应该是没问题的,基于这个问AI , 就判断是请求中被filter 过滤了,然后给出了查看过滤器的方式:

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.Filter;
import java.util.Map;

@Component
@Slf4j
public class FilterOrderPrinter {

    @Autowired
    private ApplicationContext context;

    @PostConstruct
    public void printFilters() {
        Map<String, FilterRegistrationBean> beans =
                context.getBeansOfType(FilterRegistrationBean.class);

        beans.values().forEach(bean -> {
            Filter filter = bean.getFilter();
            int order = bean.getOrder();
            log.info("Filter: {} , order={}",
                    filter.getClass().getName(), order);
        });
    }
}

最终定位到有三个过滤器, 其中有一个是封装了xss 过滤的, 联想到这些内容中确实有 <> 这种符号,于是将xss 过滤对于这个接口进行配置禁用,果然就正常了。


由于通过了xss 过滤,原始数据被截掉了,所以在接口通过json 结构转Map过程中就报错了:

@PostMapping("/v1/embeddings")
@ApiOperation(value = "向量计算")
@ApiOperationSupport(order = 1)
public Map<String,Object> embeddings(@RequestBody JSONObject body) {
    String collectionName = body.getString("collectionName");
    List<String> input = body.getJSONArray("input").toJavaList(String.class);
    String embeddingSignage = body.getString("embeddingSignage");
    return emBeddingService.embeddings(collectionName, input, embeddingSignage);
}

所以问题日志看到的都是后续副产品结果,真正的原因还是因为filter 在请求中对数据进行了过滤处理。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐