当前位置: 首页 > news >正文

深入解析 SmartPrintAI:基于 MAF + DeepSeek + MCP 的智能物流打印平台

一、项目概述

SmartPrintAI(Devn.AxiomSmartAI)是一个面向制造业的智能物流打印平台,对接鼎捷 TopGP 5.3 ERP 系统,覆盖 **7 个工厂*的装车单打印全生命周期管理。

核心场景:仓库装车完成后,ERP 过账操作自动触发打印工作流 → 数据提取 → 标签渲染打印 → OA 审批提交 → 结果通知。整个过程由AI Agent 自动编排,支持流式实时反馈(SSE/AG-UI 协议),以及断点续跑(Durable Workflow)。

三大子系统

  • PrintAgent— 全自动打印工作流编排
  • QueryAgent— 自然语言查询与故障诊断
  • PrintTaskStore— 内存任务状态机 + SSE 实时推送

关键指标

  • 7 工厂 Oracle 多库直连
  • 20 个 MCP 工具(Oracle ×11 / Printer ×5 / OA ×4)
  • SSE 流式对话 + 打字机效果
  • 防幻觉 — 无效单号代码拦截

二、系统架构全景图

┌──────────────────────────────────────────────────────────────────┐ │ SmartPrintAI 整体架构 │ ├──────────────────────────────────────────────────────────────────┤ │ │ │ ┌─ Vue 3 + Element Plus ──────────────────────────────────┐ │ │ │ Agent 工作台 │ AI 对话面板 │ 任务看板 │ 打印监控 │ │ │ └──────────────────────┬──────────────────────────────────┘ │ │ │ HTTP REST + SSE │ │ ┌──────────────────────▼──────────────────────────────────┐ │ │ │ ASP.NET Core 10 Minimal API │ │ │ │ ┌──────────┬──────────┬──────────┬─────────────────┐ │ │ │ │ │ Agent │ SSE │ Print │ Config │ │ │ │ │ │ Endpoints│ Endpoints│ Task API │ Admin API │ │ │ │ │ └──────────┴──────────┴──────────┴─────────────────┘ │ │ │ └──────────────────────┬──────────────────────────────────┘ │ │ │ │ │ ┌──────────────────────▼──────────────────────────────────┐ │ │ │ 服务层 (Services) │ │ │ │ AiPipeline │ PromptBuilder │ SkillLoader │ Memory │ │ │ │ PrintTask │ ChatHistory │ DurableWF │ McpClient │ │ │ └──────────────────────┬──────────────────────────────────┘ │ │ │ │ │ ┌──────────────────────▼──────────────────────────────────┐ │ │ │ 3 个 MCP Server(工具协议层) │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ │ │ Oracle (11T) │ │ Printer (5T) │ │ OA (4T) │ │ │ │ │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ │ │ └─────────┼──────────────────┼──────────────────┼──────────┘ │ │ ┌────▼────┐ ┌─────▼──────┐ ┌────▼────┐ │ │ │ Oracle │ │ ZT410 / │ │ OA │ │ │ │ ERP │ │ TTP-244 │ │ 审批流 │ │ │ └─────────┘ └────────────┘ └─────────┘ │ └──────────────────────────────────────────────────────────────────┘

三、技术栈详解

层级技术选型说明
前端Vue 3 + Element Plus + TypeScript + PiniaSPA 工作台,SSE 实时流式渲染
后端.NET 10 ASP.NET Core Minimal API轻量路由,原生 AOT 就绪
AI 框架Microsoft Agent Framework (MAF) v1.6.1Agent 编排 + Workflow + Durable
大模型DeepSeek V4 Pro (OpenAI 兼容 API)中文优化,成本可控
工具协议MCP (Model Context Protocol) v1.3.0标准化工具接入,3 Server 20 Tools
缓存IMemoryCache (50MB) + Redis (可选)分布式缓存加速 AI 响应
记忆MemoryService (关键词匹配)三层知识注入:静态 + 动态 + 实时

四、核心工作流:从 ERP 过账到打印完成

整个打印流程由 AI Agent 自动编排,分为 6 个步骤:

  1. ERP 过账触发— 鼎捷 TopGP 过账后,Oracle 触发器写入tc_pct_file
  2. 数据提取— Agent 调用 Oracle MCP 工具查询订单、出库单、客户信息
  3. 标签渲染— 根据模板生成 ZPL/EPL 打印指令
  4. 打印执行— 调用 Printer MCP 工具发送指令到 ZT410 / TTP-244 打印机
  5. OA 审批— 调用 OA MCP 工具提交审批流
  6. 结果通知— SSE 推送打印结果到前端,更新任务状态

五、核心代码实现

5.1 Agent 定义与工作流编排

使用 MAF v1.6.1 的ChatAgentWorkflow构建打印 Agent:

// PrintAgent.cs — Agent 定义publicstaticChatAgentCreatePrintAgent(McpClientManagermcp){vartools=mcp.GetAllTools();// 20 个 MCP 工具varagent=newChatAgent("PrintAgent",tools){SystemMessage=""" 你是 SmartPrintAI 打印助手,负责处理装车单打印全流程。 工作流步骤:1.查询 Oracle 获取装车单数据2.检查打印条件是否满足3.调用打印机渲染标签4.提交 OA 审批5.返回打印结果 请严格按照以上步骤执行,每一步完成后确认结果再进入下一步。"""};returnagent;}

5.2 SSE 流式响应与打字机效果

后端通过 SSE 协议将 AI 响应实时推送到前端:

// AgentEndpoints.cs — SSE 流式端点app.MapGet("/api/v1/agent/chat/stream",async(HttpContextcontext,stringmessage,string?sessionId)=>{context.Response.ContentType="text/event-stream";context.Response.Headers["Cache-Control"]="no-cache";context.Response.Headers["Connection"]="keep-alive";varwriter=context.Response.BodyWriter;varagent=context.RequestServices.GetRequiredService<ChatAgent>();awaitforeach(varchunkinagent.InvokeStreamingAsync(message)){varjson=JsonSerializer.Serialize(new{content=chunk});awaitwriter.WriteAsync(Encoding.UTF8.GetBytes($"event: message\ndata:{json}\n\n"));awaitwriter.FlushAsync();}awaitwriter.WriteAsync(Encoding.UTF8.GetBytes("event: done\ndata: {}\n\n"));awaitwriter.FlushAsync();});

5.3 打印工作流编排

使用 MAF 的Workflow实现多步骤编排:

// PrintWorkflow.cs — 工作流编排publicclassPrintWorkflow{privatereadonlyMcpClientManager_mcp;privatereadonlyPrintTaskStore_store;privatereadonlyDurableWorkflowService_durable;publicasyncTaskExecuteAsync(stringshipmentNo,stringplantCode){varsessionId=Guid.NewGuid().ToString();await_store.CreateAsync(sessionId,shipmentNo);// Step 1: 查询 Oracle 数据await_durable.SaveCheckpointAsync(sessionId,"OracleQuery");varorderData=await_mcp.InvokeOracleQueryAsync(shipmentNo,plantCode);// Step 2: 检查打印条件await_durable.SaveCheckpointAsync(sessionId,"PrintConditionCheck");varcanPrint=await_mcp.InvokePrintConditionCheckAsync(orderData);// Step 3: 渲染并打印标签await_durable.SaveCheckpointAsync(sessionId,"PrintExecutor");varprintResult=await_mcp.InvokePrinterAsync(orderData);// Step 4: 提交 OA 审批await_durable.SaveCheckpointAsync(sessionId,"OASubmit");varoaResult=await_mcp.InvokeOaSubmitAsync(shipmentNo,printResult);// Step 5: 更新任务状态await_store.CompleteAsync(sessionId,oaResult);}}

5.4 MCP 工具管理层:20 个工具的注册与调用

McpClientManager负责管理 3 个 MCP Server 的连接生命周期,包含指数退避重试、健康检查和超时控制:

// McpClientManager.cs — Oracle 工具示例privatestaticList<AIFunction>CreateOracleTools()=>new(){CreateTool("oracle_query_oga","查询订单主表(oga)",...),CreateTool("oracle_query_ogb","查询订单明细(ogb)",...),CreateTool("oracle_query_oea","查询出库单(oea)",...),CreateTool("oracle_query_tqm","查询客户信息(tqm)",...),CreateTool("oracle_query_tc_pct","查询提示任务(tc_pct)",...),CreateTool("oracle_insert_tc_pct","插入提示任务",...),CreateTool("oracle_query_print_task","查询打印任务完整信息",...),CreateTool("oracle_check_print_condition","检查打印条件",...),CreateTool("oracle_get_plant_info","获取工厂信息",...),CreateTool("oracle_get_related_plants","获取关联工厂(多角贸易)",...),CreateTool("oracle_cross_plant_query","跨工厂查询",...),};// 连接重试:指数退避,最多 3 次,单次超时 10sprivatestaticasyncTask<McpConnection>ConnectWithRetryAsync(stringname,Func<List<AIFunction>>toolFactory,intmaxRetries=3){for(inti=0;i<maxRetries;i++){try{vartools=toolFactory();varconn=awaitMcpConnection.ConnectStdioAsync(name,tools);returnconn;}catch{awaitTask.Delay(TimeSpan.FromSeconds(Math.Pow(2,i)));}}thrownewInvalidOperationException($"MCP{name}failed after{maxRetries}retries");}

5.5 Durable Workflow:文件系统 Checkpoint 断点续跑

当工作流执行到第 3 步 OA 审批时若系统崩溃,重启后可以从最近的 Checkpoint 恢复:

// DurableWorkflowService.cs — Checkpoint 核心publicasyncTaskSaveCheckpointAsync(stringsessionId,stringstepName,object?state){varentry=newCheckpointEntry{SessionId=sessionId,StepName=stepName,StateJson=stateisnull?null:JsonSerializer.Serialize(state),CreatedAt=DateTimeOffset.UtcNow,Version=CheckpointCount+1};varjson=JsonSerializer.Serialize(entry);awaitFile.WriteAllTextAsync($"%LocalAppData%/SmartPrintAI/checkpoints/{sessionId}.json",json);}publicasyncTask<CheckpointEntry?>LoadCheckpointAsync(stringsessionId){varfilePath=Path.Combine(_checkpointDir.FullName,$"{sessionId}.json");if(!File.Exists(filePath))returnnull;returnJsonSerializer.Deserialize<CheckpointEntry>(awaitFile.ReadAllTextAsync(filePath));}

5.6 记忆系统:三层知识注入架构

每次 AI 对话前,系统会构建三层上下文注入到 System Prompt:

// AgentEndpoints.cs — BuildSystemContextprivatestaticasyncTask<string>BuildSystemContext(stringmessage,...){varsb=newStringBuilder();// L1: SKILL.md 静态知识varskills=skillLoader.LoadAllSkills();sb.AppendLine(skills);// L2: MemoryService 动态经验varmemories=awaitmemoryService.SearchAsync(message,limit:3);foreach(varmeminmemories)sb.AppendLine($"- [{mem.Category}]{mem.Content}→ 解决:{mem.Solution}");// L3: 实时数据(Oracle + PrintTaskStore)foreach(varcodeincandidates){vartask=awaitstore.GetAsync(code);if(task!=null)sb.AppendLine($"任务{task.TaskId}: 送货单={task.ShipmentNo}状态={task.Status}");}returnsb.ToString();}

5.7 前端 Vue 3 SSE 流式消费

前端使用原生EventSource消费 SSE 事件流:

// composables/useAiChat.tsexportfunctionuseAiChat(){constmessages=ref<ChatMessage[]>([]);constisStreaming=ref(false);asyncfunctionsendMessage(text:string,sessionId?:string){consturl=`/api/v1/agent/chat/stream?message=${encodeURIComponent(text)}&sessionId=${sessionId}`;consteventSource=newEventSource(url);eventSource.addEventListener('message',(e)=>{const{content}=JSON.parse(e.data);messages.value[messages.value.length-1].content+=content;});eventSource.addEventListener('agent/tool_call',(e)=>{const{tool,args}=JSON.parse(e.data);// 渲染工具调用指示器});eventSource.addEventListener('agent/tool_result',(e)=>{const{tool,result}=JSON.parse(e.data);// 渲染工具结果});eventSource.addEventListener('done',()=>{eventSource.close();isStreaming.value=false;});}}

六、防幻觉机制:从数据源头消除 AI 幻觉

在物流打印场景中,AI 幻觉可能导致错误的打印任务被触发,造成严重的业务事故。我们设计了三层防线

第一道:单号格式校验

正则提取单号后,立即查询 Oracletc_pct_file表。若查不到数据,直接返回 “未找到”,不让 AI 模型参与回答— 从源头切断幻觉产生。

第二道:数据标记

所有注入 System Prompt 的数据都带有明确标记"=== 查询结果(已核实,数据真实)===",并追加指令"请基于以上真实数据回答"

第三道:工具调用闭环

Agent 的工具调用结果不经过模型 “理解”,而是以ChatRole.User身份直接注入对话历史,强制模型基于工具返回的原始数据作答。

// 防幻觉核心逻辑// ① 无效单号 → 直接拦截,AI 不参与if(shipmentNo!=null&&queryResultis{Found:false}){awaitwriter.WriteAsync($"未找到单号{shipmentNo}的相关数据。\n请核实单号是否正确。");return;}// ② 历史对话中剔除旧工具调用标记varcleanContent=Regex.Replace(h.Content,@"\[调用工具:\s*\w+\]\n?","");// ③ 工具结果注入为 User 消息chatMessages.Add(new(ChatRole.User,$"以下是系统查询到的真实数据,请直接回答用户:\n{string.Join("\n---\n",toolResults)}"));

七、项目结构与依赖关系

Devn.AxiomSmartAI.slnx ├── src/ │ ├── Devn.AxiomSmartAI.Backend/ ← ASP.NET Core 10 主程序 │ │ ├── Agents/ AgentDefinitions, PrintWorkflow, WorkflowCallbacks │ │ ├── Endpoints/ AgentEndpoints, SseEndpoints, ConfigAdminEndpoints │ │ ├── Services/ AiPipelineSetup, PromptBuilder, SkillLoader, │ │ │ MemoryService, DurableWorkflowService, │ │ │ McpClientManager, PrintTaskQueryTools, │ │ │ PrintTaskStore, ChatHistoryStore, ResiliencePipeline │ │ └── Config/ AgentSettings, McpServerSettings, SpeechSettings │ │ │ ├── Devn.AxiomSmartAI.Shared/ ← 共享 DTO / 模型 │ │ │ └── Devn.AxiomSmartAI.McpServers/ ← 3 个 MCP 工具服务器 │ ├── McpOracleServer/ 11 tools: oga, ogb, oea, tqm, tc_pct, ... │ ├── McpPrinterServer/ 5 tools: print, status, list, cancel, defau
http://www.jsqmd.com/news/907362/

相关文章:

  • 免费服务器指南:GitHub Pages搭建静态网站全攻略
  • Bootstrap方法避坑指南:什么时候用?什么时候千万别用?(附R代码验证)
  • 从安装到第一个视觉项目:Halcon20.11环境搭建与‘Hello World’实战
  • Conan C++ 包管理工具深度解析
  • 26HVV护网行动 初 中 高 级人员招聘
  • 7nm工艺下,我为什么从ICC2换到了Innovus?聊聊真实项目里的那些坑
  • 测试左移 + 右移 + 自动化,三位一体构建质量护城河
  • 别再只仿真了!用100个三极管在面包板上还原4位加法器,我总结了这些避坑指南
  • CocosCreator 2.4.4 长列表性能翻倍:手把手教你实现带缓存池的无尽循环列表(告别图片闪烁)
  • 华为BGP选路实战:用这3个属性(PrefVal、Local_Pref、MED)轻松搞定网络流量调度
  • AMD电脑装VMware报错?手把手教你进BIOS开启SVM Mode(附华硕/微星/技嘉主板截图)
  • EasyOCR模型下载太慢?手把手教你离线部署与自定义训练,打造专属OCR识别引擎
  • 有机化学真的在指数增长吗?数据告诉你另一个故事
  • 告别‘丑地图’!用ArcGIS Pro的视觉效果和后处理,轻松打造高级感分析图
  • RAG 04:向量数据库与索引算法
  • Shader - 水体(保姆级)
  • CentOS环境下手动升级openssl、openssh
  • MacType字体渲染引擎深度解析:Windows字体美化的核心技术方案
  • AVL Cruise 2023 保姆级教程:手把手教你用自带实例模型搞定纯电动车续航仿真
  • RTX51 Tiny在SiLABS SFR分页机制下的移植优化
  • RTX51 Tiny调试技巧与C源代码显示问题解析
  • 在mac上安装hermes
  • 鼎捷Tiptop ERP 5.3版本下,手把手教你用SoapUI测试一个用户登录WebService接口
  • RAG 技术体系:从向量检索到生产级 Pipeline
  • 保姆级教程:用PyTorch Geometric搭建GCN,实战DEAP脑电情绪分类(附完整代码)
  • 深入UGUI底层:手把手教你用OnPopulateMesh和顶点偏移,实现Image的任意变形(不只是倾斜)
  • 大数据处理:Spark与分布式计算
  • 用 Nerfstudio 和手机照片,5分钟快速生成你的第一个 3D 数字手办(Nerfacto 模型实战)
  • 告别双系统安装噩梦:Intel RST模式下无损切换AHCI,保住Windows再装Ubuntu
  • 论文降AI率工具怎么选?2026年4款降AI软件实测一次选对