Ostrakon-VL-8B项目实战从零开发一个外卖订单图像审核系统你有没有想过每天点外卖时如果对餐品有疑问上传一张照片后平台是怎么快速判断“这张图里到底有没有问题”的是人工一张张看吗那得需要多少人效率得多低今天我们就来动手解决这个实际问题。我们将从零开始搭建一个智能的外卖订单图像审核系统。它的核心任务很简单当用户因为食品安全问题比如吃出异物、包装破损上传举证图片时系统能自动、快速地分析图片内容判断是否存在问题并给出审核结果。整个过程我们会用一个叫Ostrakon-VL-8B的视觉语言大模型作为“大脑”让它来理解图片用Django这个流行的Python框架来搭建整个系统的“骨架”和“界面”最后把所有环节串起来形成一个能实际跑起来的Web应用。这篇文章不会只讲理论我们会一步步写代码把想法变成现实。如果你对AI应用落地、全栈开发或者单纯想做个有意思的项目感兴趣那就跟着一起做吧。1. 项目蓝图我们要做一个什么样的系统在动手写代码之前我们先得把要做的事情想清楚。这个系统最终会长什么样谁来用解决什么痛点想象一下你是一个外卖平台的后台运营人员。每天客服系统里会涌入大量用户投诉其中很多都附带了照片声称餐品里有头发、虫子或者包装洒了。你的工作是审核这些照片判断投诉是否成立。这工作枯燥、费眼还容易因为主观判断产生纠纷。我们的智能审核系统就是要当这位运营人员的AI助手。它的工作流程大致是这样的用户上传用户在订单投诉页面上传问题图片和文字描述。系统接收我们的Web后端Django接收到图片和相关信息。AI分析后端调用集成的Ostrakon-VL-8B模型让AI“看”这张图并根据我们设定的问题比如“图片中是否有异物”进行分析。结果处理AI返回分析结果例如“存在疑似毛发类异物”。系统将这个结果、图片信息、时间戳等一起存入数据库。界面展示运营人员可以在一个专门的审核后台清晰地看到所有待审核和已审核的记录每条记录都包含图片、AI分析结果、用户描述方便最终人工复核或快速处理。这样一来大量简单、明确的图片审核工作比如明显的包装破损可以由AI快速完成运营人员只需要处理AI不确定的或复杂的案例效率能提升一大截而且审核标准也更统一。我们这个项目就会按照这个逻辑把各个模块搭建起来。2. 搭建地基用Django创建项目骨架首先我们得把Web应用的基础框架搭好。这里我们选择Django因为它功能全面自带管理后台非常适合快速构建这类数据驱动的应用。确保你的电脑已经安装了Python建议3.8以上版本。然后打开终端开始我们的第一步。2.1 创建Django项目和核心应用我们给项目起个名字比如food_audit_system。# 创建项目目录并进入 mkdir food_audit_system cd food_audit_system # 创建Python虚拟环境推荐避免包冲突 python -m venv venv # 激活虚拟环境 # Windows: venv\Scripts\activate # Linux/Mac: source venv/bin/activate # 安装Django pip install django # 创建Django项目 django-admin startproject audit_project . # 创建一个专门处理审核逻辑的应用叫 audit python manage.py startapp audit执行完这些命令你的目录结构应该大致如下food_audit_system/ ├── audit/ # 我们刚创建的审核应用 ├── audit_project/ # Django项目配置目录 ├── venv/ # 虚拟环境 ├── manage.py # Django项目管理脚本 └── db.sqlite3 # 运行后生成数据库文件2.2 设计数据模型审核记录长什么样系统需要存储审核记录所以在audit/models.py文件里我们来定义核心的数据模型。# audit/models.py from django.db import models class AuditRecord(models.Model): 存储每一条图片审核记录 # 订单和用户信息简化版 order_id models.CharField(max_length100, verbose_name订单号) user_description models.TextField(verbose_name用户问题描述) # 图片信息 image models.ImageField(upload_toaudit_images/%Y/%m/%d/, verbose_name举证图片) uploaded_at models.DateTimeField(auto_now_addTrue, verbose_name上传时间) # AI分析结果 # 我们用JSON字段来存储灵活的AI输出比如多个问题的答案 ai_analysis_raw models.JSONField(defaultdict, verbose_nameAI原始分析结果) # 也可以单独提取关键结论字段方便查询和展示 ai_summary models.CharField(max_length500, blankTrue, verbose_nameAI审核摘要) ai_confidence models.FloatField(default0.0, verbose_nameAI置信度) # 审核状态 STATUS_CHOICES ( (pending, 待审核), (ai_processed, AI已处理), (human_confirmed, 人工确认), (rejected, 已驳回), ) status models.CharField(max_length20, choicesSTATUS_CHOICES, defaultpending, verbose_name审核状态) # 最终人工操作可选 final_decision models.CharField(max_length20, choices((valid, 有效), (invalid, 无效)), blankTrue, verbose_name最终判定) operator_notes models.TextField(blankTrue, verbose_name运营备注) processed_at models.DateTimeField(nullTrue, blankTrue, verbose_name处理时间) def __str__(self): return f订单{self.order_id} - {self.get_status_display()} class Meta: verbose_name 审核记录 verbose_name_plural 审核记录这个模型涵盖了从用户上传到最终处理的全流程信息。定义好后需要让Django知道它。# 告诉Django模型有变化生成迁移文件 python manage.py makemigrations audit # 执行迁移在数据库中创建对应的表 python manage.py migrate2.3 让管理后台能管理我们的数据Django自带一个强大的管理后台我们稍微配置一下就能用它来查看和管理审核记录。编辑audit/admin.py# audit/admin.py from django.contrib import admin from .models import AuditRecord admin.register(AuditRecord) class AuditRecordAdmin(admin.ModelAdmin): list_display (order_id, status, ai_summary, uploaded_at) # 列表页显示字段 list_filter (status, uploaded_at) # 右侧过滤器 search_fields (order_id, user_description) # 搜索框 readonly_fields (uploaded_at, ai_analysis_raw) # 某些字段只读 # 定义一个方法在后台显示图片缩略图需要安装Pillow库 def image_preview(self, obj): if obj.image: return mark_safe(fimg src{obj.image.url} stylemax-height: 100px; /) return 无图片 image_preview.short_description 图片预览 # 将图片预览加入到字段显示中 fieldsets ( (基本信息, { fields: (order_id, user_description, image, image_preview, uploaded_at) }), (AI分析结果, { fields: (ai_analysis_raw, ai_summary, ai_confidence) }), (审核流程, { fields: (status, final_decision, operator_notes, processed_at) }), )记得在文件顶部导入from django.utils.safestring import mark_safe。同时安装处理图片的库pip install Pillow。最后创建一个超级用户来登录后台python manage.py createsuperuser按照提示输入用户名、邮箱和密码。现在运行开发服务器看看我们的地基打得怎么样python manage.py runserver打开浏览器访问http://127.0.0.1:8000/admin/用刚才创建的账号登录你应该能看到“审核记录”这个模块可以尝试添加几条记录暂时手动上传图片。3. 注入智能集成Ostrakon-VL-8B模型地基打好了现在要请出我们的“AI大脑”——Ostrakon-VL-8B。这是一个视觉语言模型简单说就是既能看懂图片又能理解文字指令。我们将用它来分析用户上传的图片。3.1 准备模型环境首先安装必要的深度学习库。Ostrakon-VL-8B基于Transformers架构我们可以用Hugging Face的库来加载。pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu # 如果你没有GPU用CPU版本 # 或者根据你的CUDA版本安装GPU版本例如 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install transformers accelerate pillow接下来我们在audit应用下创建一个新的文件比如ai_processor.py专门负责处理AI相关的逻辑。# audit/ai_processor.py import torch from PIL import Image from transformers import AutoProcessor, AutoModelForVision2Seq import logging import json logger logging.getLogger(__name__) class OstrakonAuditor: Ostrakon-VL-8B 审核器 def __init__(self, model_name_or_pathOpenGVLab/Ostrakon-VL-8B): 初始化模型和处理器。 注意首次运行会下载模型约16GB请确保网络通畅和磁盘空间。 logger.info(f正在加载模型: {model_name_or_path}) try: # 加载处理器和模型 self.processor AutoProcessor.from_pretrained(model_name_or_path, trust_remote_codeTrue) self.model AutoModelForVision2Seq.from_pretrained( model_name_or_path, torch_dtypetorch.float16, # 使用半精度减少内存占用 device_mapauto, # 自动分配设备GPU/CPU trust_remote_codeTrue ) self.model.eval() # 设置为评估模式 logger.info(模型加载成功) except Exception as e: logger.error(f模型加载失败: {e}) raise def analyze_image(self, image_path, questions): 核心方法分析一张图片。 参数: image_path: 图片文件路径str或PIL.Image对象。 questions: 一个字典键是问题标识值是要问AI的具体问题。 例如{ foreign_object: 图片中是否有不属于食物的异物如头发、虫子、塑料等, package_damage: 食品包装是否破损、开封或泄露, food_quality: 食物本身是否看起来有变质、发霉等异常 } 返回: 一个字典包含每个问题的答案和模型原始输出。 results {} raw_outputs [] try: # 1. 准备图片 if isinstance(image_path, str): image Image.open(image_path).convert(RGB) else: image image_path # 2. 遍历所有问题让模型逐一回答 for q_key, question_text in questions.items(): # 构建提示词。Ostrakon-VL-8B的对话格式可能需要特定模板。 # 这里是一个简单的指令格式实际使用时可能需要根据模型文档调整。 prompt fimage\n用户提问{question_text}\n请仔细查看图片并回答。 # 3. 处理输入 inputs self.processor( textprompt, imagesimage, return_tensorspt, paddingTrue ).to(self.model.device) # 4. 模型生成回答 with torch.no_grad(): # 不计算梯度加快推理速度 generated_ids self.model.generate( **inputs, max_new_tokens100, # 限制生成长度 do_sampleFalse, # 贪婪解码结果更确定 ) # 5. 解码输出 generated_text self.processor.batch_decode(generated_ids, skip_special_tokensTrue)[0] # 清理输出提取我们关心的答案部分 answer generated_text.strip() # 简单解析如果回答以“是”、“有”、“存在”等开头可以认为是正向判断 positive_keywords [是, 有, 存在, 发现, 可见] is_positive any(answer.startswith(kw) for kw in positive_keywords) results[q_key] { question: question_text, answer: answer, is_issue: is_positive, # 简化为布尔值表示是否发现问题 } raw_outputs.append({q_key: answer}) logger.info(f图片分析完成: {image_path}) return { question_results: results, raw_outputs: raw_outputs, summary: self._generate_summary(results) } except Exception as e: logger.error(f图片分析过程中出错: {e}) return { error: str(e), question_results: {}, raw_outputs: [], summary: 分析失败 } def _generate_summary(self, results): 根据各个问题的结果生成一个简短的文本摘要 issues_found [] for q_key, info in results.items(): if info.get(is_issue): # 根据问题键名映射到中文描述 issue_map { foreign_object: 异物, package_damage: 包装破损, food_quality: 食物变质 } issues_found.append(issue_map.get(q_key, q_key)) if issues_found: return fAI识别到疑似问题{, .join(issues_found)}。 else: return AI未识别到明显问题。这个类封装了加载模型和分析图片的核心功能。注意模型很大第一次运行会下载很长时间。在实际生产环境中模型应该被预先下载并部署在性能足够的服务器上。3.2 创建全局模型实例为了不在每次请求时都重新加载模型那太慢了我们可以在Django项目启动时加载一次然后全局使用。在audit_project/目录下创建或修改__init__.py和settings.py可能有点复杂一个更清晰的做法是使用Django的AppConfig和缓存。我们在audit/apps.py中初始化# audit/apps.py from django.apps import AppConfig import sys class AuditConfig(AppConfig): default_auto_field django.db.models.BigAutoField name audit def ready(self): 当Django启动应用准备就绪时运行。 在这里初始化我们的AI审核器。 # 只在运行runserver等命令时初始化避免在migrate等管理命令中也加载 if runserver in sys.argv or uwsgi in sys.argv or gunicorn in sys.argv: try: from .ai_processor import OstrakonAuditor # 将实例存储在AppConfig中方便其他地方获取 self.auditor OstrakonAuditor() print(AI审核器初始化成功) except Exception as e: print(fAI审核器初始化失败: {e}) self.auditor None然后在其他地方我们可以通过apps.get_app_config(audit).auditor来获取这个全局实例。4. 连接前后端创建视图、API和界面现在数据模型有了AI大脑也有了我们需要创建桥梁接收用户上传的视图、处理AI分析的逻辑以及一个给运营人员看的展示页面。4.1 创建处理上传和审核的视图首先在audit/views.py中创建视图。# audit/views.py import json from django.shortcuts import render, get_object_or_404 from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from django.core.files.storage import default_storage from django.conf import settings from .models import AuditRecord from django.apps import apps import logging from datetime import datetime logger logging.getLogger(__name__) # 我们预设的审核问题 AUDIT_QUESTIONS { foreign_object: 图片中是否有不属于食物的异物如头发、虫子、塑料、钢丝球等, package_damage: 食品包装是否破损、开封、撕裂、压扁或泄露, food_quality: 食物本身是否看起来有变质、发霉、变色、干瘪等异常, } def audit_dashboard(request): 审核流水总览页面 # 获取所有记录按上传时间倒序排列 records AuditRecord.objects.all().order_by(-uploaded_at) context { records: records, status_choices: dict(AuditRecord.STATUS_CHOICES), } return render(request, audit/dashboard.html, context) csrf_exempt # 为了方便测试暂时禁用CSRF。生产环境务必使用更安全的方式。 def upload_and_audit_api(request): 接收上传图片并进行AI审核的API接口模拟用户端调用 if request.method ! POST: return JsonResponse({error: 只支持POST请求}, status405) try: # 1. 获取数据这里简化实际应从request.POST和request.FILES获取 order_id request.POST.get(order_id, TEST_ORDER_001) user_desc request.POST.get(description, 测试描述) image_file request.FILES.get(image) if not image_file: return JsonResponse({error: 未提供图片文件}, status400) # 2. 保存图片到本地/media/目录 file_path default_storage.save(faudit_images/{image_file.name}, image_file) full_path default_storage.path(file_path) # 获取绝对路径 # 3. 创建审核记录初始状态 record AuditRecord.objects.create( order_idorder_id, user_descriptionuser_desc, imagefile_path, # 保存相对路径 statuspending ) # 4. 调用AI进行分析异步处理更好这里为简化用同步 auditor apps.get_app_config(audit).auditor if auditor is None: record.ai_summary AI模型未就绪 record.status pending record.save() return JsonResponse({ record_id: record.id, status: pending, message: 系统正在初始化请稍后查看结果。 }) analysis_result auditor.analyze_image(full_path, AUDIT_QUESTIONS) # 5. 更新审核记录 record.ai_analysis_raw analysis_result.get(raw_outputs, []) record.ai_summary analysis_result.get(summary, ) # 简单计算一个置信度有问题的问题占比 issue_count sum(1 for r in analysis_result.get(question_results, {}).values() if r.get(is_issue)) record.ai_confidence issue_count / len(AUDIT_QUESTIONS) if AUDIT_QUESTIONS else 0.0 record.status ai_processed record.save() # 6. 返回结果 return JsonResponse({ record_id: record.id, status: success, ai_summary: record.ai_summary, analysis: analysis_result.get(question_results), image_url: record.image.url if record.image else }) except Exception as e: logger.exception(上传审核API处理失败) return JsonResponse({error: f服务器内部错误: {str(e)}}, status500) def record_detail(request, record_id): 查看单条审核记录的详情 record get_object_or_404(AuditRecord, idrecord_id) # 尝试美化显示原始JSON数据 try: pretty_analysis json.dumps(record.ai_analysis_raw, indent2, ensure_asciiFalse) except: pretty_analysis str(record.ai_analysis_raw) context { record: record, pretty_analysis: pretty_analysis, } return render(request, audit/record_detail.html, context)4.2 配置URL路由创建了视图需要告诉Django什么网址访问什么视图。在audit目录下创建urls.py# audit/urls.py from django.urls import path from . import views urlpatterns [ path(, views.audit_dashboard, nameaudit_dashboard), path(api/upload/, views.upload_and_audit_api, nameupload_audit_api), path(record/int:record_id/, views.record_detail, namerecord_detail), ]然后在项目的总路由audit_project/urls.py中包含这个应用的路由# audit_project/urls.py from django.contrib import admin from django.urls import path, include from django.conf import settings from django.conf.urls.static import static urlpatterns [ path(admin/, admin.site.urls), path(audit/, include(audit.urls)), # 包含审核应用的路由 ] # 开发环境下提供媒体文件上传的图片访问服务 if settings.DEBUG: urlpatterns static(settings.MEDIA_URL, document_rootsettings.MEDIA_ROOT)别忘了在settings.py中配置媒体文件路径# audit_project/settings.py import os # ... 其他设置 ... MEDIA_URL /media/ MEDIA_ROOT os.path.join(BASE_DIR, media) # 将 audit 应用加入到 INSTALLED_APPS INSTALLED_APPS [ django.contrib.admin, django.contrib.auth, django.contrib.contenttypes, django.contrib.sessions, django.contrib.messages, django.contrib.staticfiles, audit, # 我们的审核应用 ]4.3 制作一个简单的展示页面我们需要一个模板来展示审核流水。首先在audit应用下创建templates/audit/目录然后创建dashboard.html!-- audit/templates/audit/dashboard.html -- !DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title外卖订单图像审核流水/title link hrefhttps://cdn.jsdelivr.net/npm/bootstrap5.1.3/dist/css/bootstrap.min.css relstylesheet style .status-badge { font-size: 0.8em; } .table-hover tbody tr:hover { background-color: rgba(0,0,0,.075); } .img-thumbnail { max-height: 80px; } .summary-cell { max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /style /head body div classcontainer-fluid mt-4 h1 classmb-4 外卖订单图像审核流水/h1 p classlead系统自动分析用户上传的食品安全举证图片并给出初步审核意见。/p div classtable-responsive table classtable table-hover table-striped align-middle thead classtable-light tr th scopecol#ID/th th scopecol订单号/th th scopecol用户描述/th th scopecol举证图片/th th scopecolAI审核摘要/th th scopecol置信度/th th scopecol状态/th th scopecol上传时间/th th scopecol操作/th /tr /thead tbody {% for record in records %} tr th scoperow{{ record.id }}/th tdstrong{{ record.order_id }}/strong/td tdsmall{{ record.user_description|truncatechars:50 }}/small/td td {% if record.image %} img src{{ record.image.url }} alt举证图片 classimg-thumbnail {% else %} span classtext-muted无图片/span {% endif %} /td td classsummary-cell title{{ record.ai_summary }} {{ record.ai_summary|default:待分析 }} /td td {% if record.ai_confidence %} div classprogress styleheight: 20px; width: 80px; div classprogress-bar {% if record.ai_confidence 0.6 %}bg-warning{% else %}bg-success{% endif %} roleprogressbar stylewidth: {{ record.ai_confidence|floatformat:2 }}% aria-valuenow{{ record.ai_confidence }} aria-valuemin0 aria-valuemax100 {{ record.ai_confidence|floatformat:2 }}% /div /div {% else %} span classtext-muted-/span {% endif %} /td td {% with statusrecord.status %} {% if status pending %} span classbadge bg-secondary status-badge待审核/span {% elif status ai_processed %} span classbadge bg-info status-badgeAI已处理/span {% elif status human_confirmed %} span classbadge bg-success status-badge人工确认/span {% elif status rejected %} span classbadge bg-danger status-badge已驳回/span {% endif %} {% endwith %} /td tdsmall{{ record.uploaded_at|date:Y-m-d H:i }}/small/td td a href{% url record_detail record.id %} classbtn btn-sm btn-outline-primary详情/a a href/admin/audit/auditrecord/{{ record.id }}/change/ classbtn btn-sm btn-outline-secondary target_blank管理/a /td /tr {% empty %} tr td colspan9 classtext-center text-muted py-4暂无审核记录。/td /tr {% endfor %} /tbody /table /div div classmt-5 p-3 bg-light rounded h5 模拟用户上传测试/h5 form iduploadForm enctypemultipart/form-data classrow g-3 {% csrf_token %} div classcol-md-3 label fororderId classform-label订单号/label input typetext classform-control idorderId valueTEST_{{ random_order_id }} readonly /div div classcol-md-4 label fordescription classform-label问题描述/label input typetext classform-control iddescription value餐品中发现不明黑色异物 /div div classcol-md-3 label forimageFile classform-label上传图片/label input typefile classform-control idimageFile acceptimage/* required /div div classcol-md-2 d-flex align-items-end button typesubmit classbtn btn-primary w-100提交审核/button /div /form div iduploadResult classmt-3/div /div footer classmt-5 pt-3 text-muted border-top p系统基于 Django Ostrakon-VL-8B 构建。AI分析结果仅供参考需人工最终复核。/p /footer /div script srchttps://cdn.jsdelivr.net/npm/bootstrap5.1.3/dist/js/bootstrap.bundle.min.js/script script // 生成随机订单号 document.getElementById(orderId).value TEST_ Math.floor(Math.random() * 10000); document.getElementById(uploadForm).addEventListener(submit, async function(e) { e.preventDefault(); const resultDiv document.getElementById(uploadResult); resultDiv.innerHTML div classalert alert-info正在上传并分析图片请稍候.../div; const formData new FormData(); formData.append(order_id, document.getElementById(orderId).value); formData.append(description, document.getElementById(description).value); formData.append(image, document.getElementById(imageFile).files[0]); try { const response await fetch(/audit/api/upload/, { method: POST, body: formData, // 注意在生产环境中需要处理CSRF token }); const data await response.json(); if (response.ok) { resultDiv.innerHTML div classalert alert-success strong提交成功/strongbr/ 记录ID: ${data.record_id}br/ AI摘要: ${data.ai_summary}br/ a href/audit/record/${data.record_id}/ classalert-link查看详情/a | a href# onclicklocation.reload() classalert-link刷新列表/a /div; // 3秒后自动刷新列表 setTimeout(() location.reload(), 3000); } else { resultDiv.innerHTML div classalert alert-danger提交失败: ${data.error || 未知错误}/div; } } catch (error) { resultDiv.innerHTML div classalert alert-danger网络请求失败: ${error}/div; } }); /script /body /html再创建一个详情页模板record_detail.html!-- audit/templates/audit/record_detail.html -- !DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title审核记录详情 #{{ record.id }}/title link hrefhttps://cdn.jsdelivr.net/npm/bootstrap5.1.3/dist/css/bootstrap.min.css relstylesheet /head body div classcontainer mt-4 a href{% url audit_dashboard %} classbtn btn-outline-secondary mb-3← 返回流水页/a h2审核记录详情 #{{ record.id }}/h2 div classrow mt-4 div classcol-md-6 div classcard div classcard-headerstrong订单与图片信息/strong/div div classcard-body pstrong订单号:/strong {{ record.order_id }}/p pstrong用户描述:/strong {{ record.user_description }}/p pstrong上传时间:/strong {{ record.uploaded_at }}/p {% if record.image %} pstrong举证图片:/strong/p img src{{ record.image.url }} classimg-fluid rounded alt举证图片 {% endif %} /div /div /div div classcol-md-6 div classcard div classcard-headerstrongAI分析与审核状态/strong/div div classcard-body pstrongAI审核摘要:/strong span classbadge bg-info{{ record.ai_summary|default:未分析 }}/span/p pstrongAI置信度:/strong {% if record.ai_confidence %} {{ record.ai_confidence|floatformat:2 }} {% else %} span classtext-muted-/span {% endif %} /p pstrong当前状态:/strong span classbadge {% if record.status pending %}bg-secondary {% elif record.status ai_processed %}bg-info {% elif record.status human_confirmed %}bg-success {% elif record.status rejected %}bg-danger {% endif %} {{ record.get_status_display }} /span /p hr h6AI原始分析结果:/h6 pre stylebackground-color: #f8f9fa; padding: 10px; border-radius: 5px; font-size: 0.9em; max-height: 300px; overflow-y: auto;{{ pretty_analysis }}/pre /div /div /div /div div classcard mt-4 div classcard-headerstrong人工处理/strong/div div classcard-body p classtext-muted此区域供运营人员填写最终判定和备注。实际开发中此处应连接后台处理逻辑。/p pstrong最终判定:/strong {{ record.get_final_decision_display|default:待处理 }}/p pstrong运营备注:/strong {{ record.operator_notes|default:无 }}/p pstrong处理时间:/strong {{ record.processed_at|default:- }}/p a href/admin/audit/auditrecord/{{ record.id }}/change/ classbtn btn-primary target_blank前往管理后台处理/a /div /div /div /body /html5. 跑起来看看系统演示与效果好了所有代码都写完了现在让我们把整个系统跑起来看看效果。启动开发服务器python manage.py runserver访问审核流水页 打开浏览器访问http://127.0.0.1:8000/audit/。你会看到一个空的表格。模拟用户上传 在页面底部的测试区域选择一张你准备好的“问题食品”图片比如一张有异物的网络图片填写描述点击“提交审核”。观察过程 提交后前端会调用我们的/audit/api/upload/API。后端会保存图片。创建一条pending状态的记录。调用OstrakonAuditor.analyze_image方法。AI模型开始分析图片第一次调用会较慢因为要加载模型。分析完成后更新记录状态为ai_processed并填入AI分析摘要和置信度。前端收到成功响应页面刷新新的记录出现在表格最上方。查看结果 在流水页你可以看到新记录的“AI审核摘要”例如“AI识别到疑似问题异物。”和置信度进度条。点击“详情”可以查看更完整的AI原始输出。管理后台 你还可以访问http://127.0.0.1:8000/admin/用超级管理员账号登录在“审核记录”模块里看到所有数据并进行人工复核和最终判定。效果如何对于明显的异物如头发、塑料片Ostrakon-VL-8B通常能给出比较准确的描述比如“图片中有一根黑色丝状物”。对于包装破损如洒漏、盒子压扁识别效果也不错。对于更主观的“变质”判断效果可能不稳定这正体现了AI作为助手、需要人工复核的价值。整个流程跑通后一个具备基本功能的智能外卖订单图像审核系统就搭建完成了。运营人员有了一个集中查看AI预审结果的平台效率得到了提升。6. 总结与展望跟着做下来我们从零搭建了一个集成视觉大模型Ostrakon-VL-8B的Web应用。这个项目虽然是个示例但串联起了几个非常实用的技术点Django全栈开发、大模型本地集成、前后端交互、文件上传处理以及简单的任务流水线设计。实际用起来你会发现这个基础版本还有很大的优化空间。比如AI推理是同步的如果图片多或者模型慢用户就得等着体验不好。更好的做法是把分析任务丢到消息队列比如Celery里异步执行完成后通过WebSocket或轮询通知前端。再比如现在的审核问题比较固定未来可以做成可配置的让运营人员能根据不同食品类型动态设置要问AI的问题。另外模型的准确性永远是核心。Ostrakon-VL-8B是个通用模型要让它在外卖审核这个垂直领域表现更好可能还需要用一些相关的图片数据对它进行微调Fine-tuning教它更精准地识别“小强”和“花椒”的区别。不过最重要的是我们通过这个项目看到了AI落地的一种典型模式不是替代人而是增强人。AI负责处理海量、重复、初级的判断把有疑问的、复杂的案例筛选出来交给人来做最终决策。这种“人机协同”的思路在很多行业都有用武之地。如果你对其中某个环节特别感兴趣比如如何优化Django性能、如何用Docker部署整个应用、如何对视觉模型进行微调都可以以此为起点继续深入探索。技术的乐趣就在于把想法一点点变成现实。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。