修改bom接口的提示词
This commit is contained in:
@@ -116,16 +116,19 @@ public class ImageRecognitionServiceImpl implements IImageRecognitionService {
|
||||
|
||||
// 解析识别结果
|
||||
try {
|
||||
Map<String, Object> structuredResult = parseBomResponse(aiResponse);
|
||||
// 直接解析属性数组
|
||||
List<ImageRecognitionVo.AttributeVo> attributes = parseAttributesResponse(aiResponse);
|
||||
result.setAttributes(attributes);
|
||||
|
||||
// 构建结构化结果
|
||||
Map<String, Object> structuredResult = new HashMap<>();
|
||||
structuredResult.put("attributes", attributes);
|
||||
structuredResult.put("summary", "材料质保单识别结果");
|
||||
structuredResult.put("totalItems", attributes.size());
|
||||
result.setStructuredResult(structuredResult);
|
||||
|
||||
// 提取BOM项目列表
|
||||
List<ImageRecognitionVo.BomItemVo> bomItems = extractBomItems(structuredResult);
|
||||
result.setBomItems(bomItems);
|
||||
|
||||
// 提取属性列表
|
||||
List<ImageRecognitionVo.AttributeVo> attributes = extractAttributes(structuredResult);
|
||||
result.setAttributes(attributes);
|
||||
// BOM项目为空,因为这是质保单识别
|
||||
result.setBomItems(new ArrayList<>());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.warn("解析识别响应失败: {}", e.getMessage());
|
||||
@@ -345,13 +348,19 @@ public class ImageRecognitionServiceImpl implements IImageRecognitionService {
|
||||
*/
|
||||
private String buildBomPrompt(ImageRecognitionBo bo) {
|
||||
StringBuilder prompt = new StringBuilder();
|
||||
prompt.append("请仔细分析这张图片中的内容,并提取所有相关信息:\n\n");
|
||||
prompt.append("【识别要求】\n");
|
||||
prompt.append("1. 如果图片包含BOM(物料清单)信息,请提取原材料ID、名称、数量、单位等\n");
|
||||
prompt.append("2. 如果图片包含其他类型的信息(如检验报告、产品信息等),请提取所有相关属性\n");
|
||||
prompt.append("3. 识别图片中的所有文字信息,包括标题、内容、表格数据等\n");
|
||||
prompt.append("4. 提取关键信息点,如产品名称、规格参数、检验结果等\n");
|
||||
prompt.append("5. 确保信息的准确性和完整性\n\n");
|
||||
prompt.append("这是一张材料质保单的图片。请从表格、文字排布中提取有用的信息,返回其中所有可以被识别为字段名 + 字段值的键值对。\n\n");
|
||||
prompt.append("要求如下:\n\n");
|
||||
prompt.append("1. 忽略标题、编号、日期等通用信息,不要作为键值对输出;\n");
|
||||
prompt.append("2. 仅提取\"字段名 + 字段值\"形式的内容,且字段名可以是如\"钢卷号\"、\"规格\"、\"净重\"、\"材质\"、\"下工序\"、\"生产班组\"、\"生产日期\"等;\n");
|
||||
prompt.append("3. 字段不固定,根据图像内容自行判断,但要尽量提取所有;\n");
|
||||
prompt.append("4. 返回格式统一为 JSON 数组,格式如下:\n");
|
||||
prompt.append("[\n");
|
||||
prompt.append(" { \"attrKey\": \"字段名\", \"attrValue\": \"字段值\" },\n");
|
||||
prompt.append(" ...\n");
|
||||
prompt.append("]\n");
|
||||
prompt.append("5. 如有值缺失或为空的字段,仍保留字段,value 留空字符串;\n");
|
||||
prompt.append("6. 严格按照图像中文字布局顺序返回;\n");
|
||||
prompt.append("7. 只输出 JSON 结果,不需要解释或说明;\n\n");
|
||||
|
||||
if (bo.getProductId() != null) {
|
||||
prompt.append("【产品信息】\n");
|
||||
@@ -362,30 +371,6 @@ public class ImageRecognitionServiceImpl implements IImageRecognitionService {
|
||||
prompt.append("【自定义要求】\n");
|
||||
prompt.append(bo.getCustomPrompt()).append("\n\n");
|
||||
}
|
||||
|
||||
prompt.append("【输出格式】\n");
|
||||
prompt.append("请按以下JSON格式输出识别结果:\n");
|
||||
prompt.append("{\n");
|
||||
prompt.append(" \"bomItems\": [\n");
|
||||
prompt.append(" {\n");
|
||||
prompt.append(" \"rawMaterialId\": \"原材料ID\",\n");
|
||||
prompt.append(" \"rawMaterialName\": \"原材料名称\",\n");
|
||||
prompt.append(" \"quantity\": 数量,\n");
|
||||
prompt.append(" \"unit\": \"单位\",\n");
|
||||
prompt.append(" \"specification\": \"规格\",\n");
|
||||
prompt.append(" \"remark\": \"备注\"\n");
|
||||
prompt.append(" }\n");
|
||||
prompt.append(" ],\n");
|
||||
prompt.append(" \"attributes\": [\n");
|
||||
prompt.append(" {\n");
|
||||
prompt.append(" \"attrKey\": \"属性名称\",\n");
|
||||
prompt.append(" \"attrValue\": \"属性值\"\n");
|
||||
prompt.append(" }\n");
|
||||
prompt.append(" ],\n");
|
||||
prompt.append(" \"summary\": \"内容总结\",\n");
|
||||
prompt.append(" \"totalItems\": 总项目数\n");
|
||||
prompt.append("}\n\n");
|
||||
prompt.append("请将识别到的所有信息整理成属性数组,每个属性包含attrKey(属性名称)和attrValue(属性值)。");
|
||||
|
||||
return prompt.toString();
|
||||
}
|
||||
@@ -439,7 +424,53 @@ public class ImageRecognitionServiceImpl implements IImageRecognitionService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析BOM响应
|
||||
* 解析属性数组响应
|
||||
*/
|
||||
private List<ImageRecognitionVo.AttributeVo> parseAttributesResponse(String response) {
|
||||
try {
|
||||
// 尝试直接解析JSON数组
|
||||
List<Map<String, Object>> attrList = objectMapper.readValue(response,
|
||||
objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class));
|
||||
|
||||
List<ImageRecognitionVo.AttributeVo> attributes = new ArrayList<>();
|
||||
for (Map<String, Object> attr : attrList) {
|
||||
ImageRecognitionVo.AttributeVo attribute = new ImageRecognitionVo.AttributeVo();
|
||||
attribute.setAttrKey((String) attr.get("attrKey"));
|
||||
attribute.setAttrValue((String) attr.get("attrValue"));
|
||||
attributes.add(attribute);
|
||||
}
|
||||
return attributes;
|
||||
|
||||
} catch (JsonProcessingException e) {
|
||||
// 如果直接解析失败,尝试提取JSON数组部分
|
||||
Pattern jsonArrayPattern = Pattern.compile("\\[[\\s\\S]*\\]");
|
||||
Matcher matcher = jsonArrayPattern.matcher(response);
|
||||
if (matcher.find()) {
|
||||
try {
|
||||
List<Map<String, Object>> attrList = objectMapper.readValue(matcher.group(),
|
||||
objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class));
|
||||
|
||||
List<ImageRecognitionVo.AttributeVo> attributes = new ArrayList<>();
|
||||
for (Map<String, Object> attr : attrList) {
|
||||
ImageRecognitionVo.AttributeVo attribute = new ImageRecognitionVo.AttributeVo();
|
||||
attribute.setAttrKey((String) attr.get("attrKey"));
|
||||
attribute.setAttrValue((String) attr.get("attrValue"));
|
||||
attributes.add(attribute);
|
||||
}
|
||||
return attributes;
|
||||
|
||||
} catch (JsonProcessingException ex) {
|
||||
log.warn("无法解析属性响应为JSON数组: {}", response);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
log.warn("无法解析属性响应: {}", response);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析BOM响应(保留用于兼容性)
|
||||
*/
|
||||
private Map<String, Object> parseBomResponse(String response) {
|
||||
try {
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
package com.klp.test;
|
||||
|
||||
import com.klp.domain.bo.ImageRecognitionBo;
|
||||
import com.klp.domain.vo.ImageRecognitionVo;
|
||||
import com.klp.service.IImageRecognitionService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 图片识别功能测试类
|
||||
*
|
||||
* @author klp
|
||||
* @date 2025-01-27
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ImageRecognitionTest implements CommandLineRunner {
|
||||
|
||||
private final IImageRecognitionService imageRecognitionService;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
log.info("开始测试图片识别功能...");
|
||||
|
||||
// 测试AI连接
|
||||
testAiConnection();
|
||||
|
||||
// 测试文字识别
|
||||
testTextRecognition();
|
||||
|
||||
// 测试BOM识别
|
||||
testBomRecognition();
|
||||
|
||||
log.info("图片识别功能测试完成");
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试AI连接
|
||||
*/
|
||||
private void testAiConnection() {
|
||||
log.info("测试AI连接...");
|
||||
try {
|
||||
Map<String, Object> result = imageRecognitionService.testAiConnection();
|
||||
if (Boolean.TRUE.equals(result.get("success"))) {
|
||||
log.info("AI连接测试成功: {}", result.get("message"));
|
||||
} else {
|
||||
log.error("AI连接测试失败: {}", result.get("message"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("AI连接测试异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试文字识别
|
||||
*/
|
||||
private void testTextRecognition() {
|
||||
log.info("测试文字识别...");
|
||||
try {
|
||||
ImageRecognitionBo bo = new ImageRecognitionBo();
|
||||
bo.setImageUrl("https://via.placeholder.com/400x300/000000/FFFFFF?text=Test+Text");
|
||||
bo.setRecognitionType("text");
|
||||
bo.setEnableVoting(false);
|
||||
|
||||
ImageRecognitionVo result = imageRecognitionService.recognizeText(bo);
|
||||
log.info("文字识别结果: {}", result.getRecognizedText());
|
||||
log.info("识别状态: {}", result.getStatus());
|
||||
log.info("处理时间: {}ms", result.getProcessingTime());
|
||||
} catch (Exception e) {
|
||||
log.error("文字识别测试异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试BOM识别
|
||||
*/
|
||||
private void testBomRecognition() {
|
||||
log.info("测试BOM识别...");
|
||||
try {
|
||||
ImageRecognitionBo bo = new ImageRecognitionBo();
|
||||
bo.setImageUrl("https://via.placeholder.com/400x300/000000/FFFFFF?text=BOM+Test");
|
||||
bo.setRecognitionType("bom");
|
||||
bo.setEnableVoting(false);
|
||||
bo.setProductId(1L);
|
||||
|
||||
ImageRecognitionVo result = imageRecognitionService.recognizeBom(bo);
|
||||
log.info("BOM识别结果: {}", result.getRecognizedText());
|
||||
log.info("识别状态: {}", result.getStatus());
|
||||
log.info("处理时间: {}ms", result.getProcessingTime());
|
||||
|
||||
if (result.getBomItems() != null) {
|
||||
log.info("BOM项目数量: {}", result.getBomItems().size());
|
||||
for (ImageRecognitionVo.BomItemVo item : result.getBomItems()) {
|
||||
log.info("BOM项目: {} - {} {} {}",
|
||||
item.getRawMaterialName(),
|
||||
item.getQuantity(),
|
||||
item.getUnit(),
|
||||
item.getSpecification());
|
||||
}
|
||||
}
|
||||
|
||||
if (result.getAttributes() != null) {
|
||||
log.info("属性数量: {}", result.getAttributes().size());
|
||||
for (ImageRecognitionVo.AttributeVo attr : result.getAttributes()) {
|
||||
log.info("属性: {} = {}", attr.getAttrKey(), attr.getAttrValue());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("BOM识别测试异常", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user