一种基于LLM的可通过图像语音控制的元件库管理工具
项目概述
库存管理在我们的生活中几乎无处不在,在许多小型的库存当中,比如实验室中的库存管理,往往没有人去专职维护,这就会导致在日积月累中逐渐实验室的库存将变得及其混乱,往往如果想实现维系一个良好的库存则需要投入大量的成本。这种问题同样出现在我们的实验室当中,故此借此次机会,尝试开发出一款由人工智能管理的智能元器件库存管理系统,以实现较低运营成本下长时间的维持运营一个良好的库存环境。本项目实现了多模态同步,在项目中联合调用了CV(OCR),ASR,LLM。
主要功能构想
1.实现用户将采购单或元器件标签或元器件(下文称输入资料)放置或倒入在元器件入库平台,使用语音控制或入库平台界面使其自动识别入库。
2.用户将EDA软件导出的bom表导入系统,在使用语音或平台确认后,自动检索出库,如有智能库位系统可向智能库位发送报文自动检索出库。
功能流程
1.入库阶段
用户将输入资料通过入库平台输入系统后,系统自动识别输入资料类型,如是图片类型,自动运行OCR并将输出结果发送到LLM,LLM处理后将识别信息返回到平台在平台确认后自动入库,如果是采购单,则省略OCR阶段,经预处理数据后直接发到LLM进行处理,LLM处理后返回平台进行确认后自动入库。
可在平台决定是否开启ASR(tts,stt)功能,开启后可不通过平台确认,在LLM阶段后直接进行播报,用户可直接进行语音确认。
2.出库阶段
在用户将bom表输入系统后,系统进行数据预处理,自动查找数据库进行出库,如用户启用了ASR则可由用户使用语言描述,ASR识别后交由LLM进行理解,后输出确认信息,待用户确认后自动进行出库。
实现记录
10.17 初步由QT实现管理平台
10.24 成功实现项目内调用qwen2:1.5b
10.31 OCR,API,LLM联合调试成功实现
11.05 项目主要得到实现
后端代码
from flask import Flask, request, jsonify
from PIL import Image
import pytesseract
import os
from datetime import datetime
import json
import subprocess
import pandas as pd
import numpy as np
tig = """
我需要你去识别发送给你的一段文字当中的元器件参数信息
需要productModel、productCode、description、packageType、quantity信息,输出json格式
其中productCode是类似于C01234
需要严格遵循示例格式
下面是json示例
{
"productModel" : " ",
"productCode" : " ",
"description" : " ",
"packageType" : " ",
"quantity" : " "
}
只能输出json,json中不要存在中文
下面是输入文字:(
"""
tig2 = ")"
app = Flask(__name__)
os.environ['TESSDATA_PREFIX'] = '/usr/local/share/tessdata/'
UPLOAD_DIR = './uploads'
os.makedirs(UPLOAD_DIR, exist_ok=True)
@app.route('/ocr', methods=['POST'])
def ocr():
print("=== Request Headers ===")
for k, v in request.headers.items():
print(f"{k}: {v}")
print("=== Form Data ===")
for k, v in request.form.items():
print(f"{k}: {v}")
print("=== Uploaded Files ===")
for k, f in request.files.items():
print(f"{k}: filename={f.filename}, content_type={f.content_type}")
if 'image' in request.files:
file = request.files['image']
file_type = 'image'
elif 'bom' in request.files:
file = request.files['bom']
file_type = 'bom'
else:
error_response = {"error": "No file provided (need 'image' or 'bom')"}
print(json.dumps(error_response, ensure_ascii=False))
return jsonify(error_response), 400
try:
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S_%f')
filename = f"{timestamp}_{file.filename}"
save_path = os.path.join(UPLOAD_DIR, filename)
file.save(save_path)
if file_type == 'image':
img = Image.open(save_path)
text = pytesseract.image_to_string(img, lang='chi_sim')
elif file_type == 'bom':
df = pd.read_excel(save_path, sheet_name='Sheet1', usecols=['Quantity','Comment','Footprint','Value','Supplier Part'])
text = df.astype(str).to_csv(sep='\\t', index=False)
print("=== Extracted Text ===")
print(text)
prompt = tig + text + tig2
output = ollama_run(prompt)
try:
if output.startswith("```
output = "\\n".join(output.split("\\n")[1:-1])
response_json = json.loads(output)
except json.JSONDecodeError:
# 如果模型输出不是严格 JSON,直接返回文本
response_json = {"data": output}
print("=== OCR Result ===")
print(json.dumps(response_json, ensure_ascii=False))
return jsonify(response_json)
except Exception as e:
error_response = {"error": str(e)}
print(json.dumps(error_response, ensure_ascii=False))
return jsonify(error_response), 500
def ollama_run(prompt: str, model: str = "qwen2:1.5b"):
result = subprocess.run(
["ollama","run", model],
input=prompt,
text=True,
capture_output=True
)
return result.stdout.strip()
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5456)