ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

无代码平台集成AI助手:从架构设计到实战案例

无代码平台集成AI助手:从架构设计到实战案例 在非标自动化项目的落地过程中工程师经常要在“机器视觉算法调试”“运动控制轴卡配置”“上位机界面开发”三块之间来回切换。很多团队并不是缺少技术能力而是被重复性配置工作拖慢了节奏。BnlAiCtrl 这类无代码平台的出现本来就是为了把视觉、运动控制、上位机开发统一到一条配置链路里而 AI 助手的集成则把这套平台的使用门槛又往下压了一截。这篇教程是 BnlAiCtrl 系列文章的第七篇重点讲 AI 助手集成。我会从整体架构开始逐步拆解 AI 助手在后端如何对接大模型、如何通过工具调用控制平台能力、如何在前端无代码界面中嵌入对话窗口最后用一个“视觉引导取料”的完整案例把全流程串起来。如果你正在做非标自动化相关的平台开发或者准备为自己的设备软件加入 AI 辅助能力这篇文章值得收藏备用。1. 背景为什么无代码平台需要 AI 助手1.1 BnlAiCtrl 平台与 AI 助手的定位BnlAiCtrl 是一套面向非标自动化场景的无代码开发平台核心能力覆盖三个方向机器视觉负责定位、测量、缺陷检测、二维码识别等视觉任务。运动控制负责轴卡、脉冲输出、插补、点位运动、IO 联动等控制任务。上位机负责 HMI 界面、数据监控、参数下发、报表展示等人机交互任务。在传统开发模式下这三个方向分别需要视觉工程师、运动控制工程师和上位机开发工程师协作完成。引入 BnlAiCtrl 之后工程师可以在平台里通过“拖拽 配置”的方式搭出整套自动化流程不需要从零编写底层驱动。不过无代码不等于没有学习成本。平台里的参数项很多比如视觉里的曝光、阈值、标定系数运动控制里的加速度、减速度、回零方式上位机里的控件绑定、变量映射对于新手来说仍然需要花时间熟悉。AI 助手的定位就是把这些参数的解释、配置建议、脚本生成、异常排查等能力以对话形式提供给用户。1.2 AI 助手能解决哪些实际痛点我在前面的系列文章里已经介绍过 BnlAiCtrl 的视觉配置、运动控制、上位机流程搭建方法。实际使用中工程师反映最多的几个痛点包括视觉参数不会调不知道怎么根据材质、光照、精度要求选择合适的曝光、阈值和处理算子。运动控制脚本记不住轴卡 API 很多点位运动、相对运动、手爪联动这些逻辑每次都要查手册。上位机控件绑定繁琐标签、按钮、文本框和 PLC 寄存器或视觉结果变量一一对应建多了容易乱。报错看不懂视觉定位不准、轴运动超时、通讯失败原因涉及多个模块定位慢。AI 助手集成后这些场景都会有明显改善。例如工程师可以直接在对话框里问“我的物料是反光金属件视野范围 50mm×40mm要求定位精度 0.1mm应该怎么选光源和阈值参数”AI 助手可以结合视觉配置工具给出建议并且直接在平台上把参数预览出来甚至生成一份视觉检测脚本。1.3 集成 AI 助手后的典型工作流先看一个典型的完整流程方便你理解后面各个模块的作用。工程师打开 BnlAiCtrl 项目的上位机配置页面点开右侧 AI 助手对话窗。输入需求“帮我配置一个视觉引导取料流程相机拍照后识别物料中心点把坐标发给运动控制轴。”AI 助手解析需求调用视觉配置工具生成视觉检测流程节点。用户确认后AI 助手继续调用运动控制脚本工具生成基于坐标的取料运动逻辑。最后 AI 助手在上位机页面中自动生成一个简单的操作界面包含“启动拍照”“结果坐标显示”“取料执行”三个控件。整个流程中用户可以随时在对话窗口里追问参数含义或让 AI 修改某个节点的配置。这个流程看起来并不复杂但实现起来需要把大模型、工具调用、无代码配置引擎、权限控制串在一起。下面我按模块逐步拆解。2. AI 助手整体架构设计2.1 核心功能拆分AI 助手不是一个简单的聊天机器人它是 BnlAiCtrl 平台的“智能操作入口”。从功能层面拆分包含以下几块。功能模块说明对话管理维护多轮会话上下文支持流式输出意图识别判断用户是想问问题、生成配置还是执行操作工具调用让大模型调用平台内部功能比如读取视觉配置、创建运动控制节点、生成上位机代码参数解释对平台内的参数项做解释和推荐脚本生成生成运动控制代码、视觉处理代码、上位机界面配置异常诊断分析平台日志和报错信息给出排错建议权限控制区分普通用户和管理员敏感操作需要二次确认这些模块不能全部塞进大模型 Prompt 里而是要让大模型通过“函数调用”的方式触发平台自身的能力。比如用户问“当前视觉方案里曝光时间是多少”大模型并不直接读数据库而是调用一个get_vision_config工具把返回值组织成自然语言回答。2.2 大模型接入与工具调用机制目前常见的大模型服务都提供函数调用Function Calling / Tool Calling能力。整体调用链路如下用户输入文本。后端把用户输入和历史消息发给大模型。后端同时声明可用的工具列表比如get_vision_config、create_motion_node。大模型根据用户意图决定是直接回答还是调用某个工具。如果需要调用工具大模型返回工具名称和参数。后端执行工具拿到结果后把结果返回给大模型。大模型根据工具结果生成最终回答流式返回给前端。关键点是工具本身必须由平台实现而不是由大模型“凭空生成”。大模型只是负责理解意图、抽取参数、生成要调用的工具调用请求具体执行仍然在 BnlAiCtrl 服务端这样能保证安全性和可控性。2.3 安全边界AI 能做什么不能做什么AI 助手集成不是把大模型接到数据库上就行。非标自动化项目通常连接真实设备一旦 AI 误操作轻则配置错误重则影响产线设备。因此我把平台内可被 AI 调用的工具分成三个等级。等级范围是否需要二次确认只读读取配置、查看日志、查询参数不需要写配置修改视觉参数、新增运动控制节点、修改上位机页面需要用户点“确认执行”设备控制下发 IO、启动轴运动、触发相机拍照禁止 AI 直接调用必须由用户在设备控制页面手动触发这个边界很重要。AI 助手可以帮你生成一套运动控制脚本但它不应该在没经过你确认的情况下直接让设备动起来。后文会专门讲如何在前端实现“工具执行确认弹窗”。3. 环境准备与版本说明3.1 后端运行环境AI 助手服务涉及 Python 后端开发和大模型接口对接。版本需要根据你的项目实际情况调整本文示例以常见环境为例重点演示配置思路。组件说明操作系统Windows 10/11 或 LinuxPython3.9 及以上Web 框架FastAPI大模型 SDKOpenAI SDK 或兼容任意大模型服务的 SDK前端BnlAiCtrl 无代码页面Vue 组件方式嵌入如果你使用的是国产大模型或本地部署模型只要服务支持 OpenAI 兼容的接口格式下面的代码基本都可以复用。3.2 前端集成方式BnlAiCtrl 上位机页面本身采用无代码配置方式可以通过两种方式嵌入 AI 对话窗方式一在页面中加入一个“AI 助手”按钮点击后弹出独立对话框适合基于 Vue/React 构建的自定义页面。方式二在布局组件中直接放置一个聊天面板控件适合桌面级 HMI 场景。本文以方式一为例因为它在视觉、运动控制、上位机三个配置页面中都可以复用。3.3 项目目录结构后端 AI 服务建议独立成一个模块避免与平台主服务耦合过深。参考目录结构如下。bnlaictrl-ai/ ├── app/ │ ├── main.py # FastAPI 入口 │ ├── config.py # 服务配置 │ ├── llm/ │ │ ├── client.py # 大模型接口封装 │ │ └── prompts.py # Prompt 模板 │ ├── tools/ │ │ ├── registry.py # 工具注册表 │ │ ├── vision_tools.py # 视觉相关工具 │ │ ├── motion_tools.py # 运动控制相关工具 │ │ └── hmi_tools.py # 上位机相关工具 │ └── chat/ │ └── session.py # 会话管理 ├── frontend/ │ └── AiChatPanel.vue # 前端对话组件 ├── requirements.txt └── README.md4. 后端 AI 服务实现4.1 FastAPI 服务骨架先创建一个基础的 FastAPI 应用包含聊天接口和健康检查接口。文件路径app/main.py。from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel, Field from typing import List, Optional from app.llm.client import LLMClient from app.chat.session import SessionManager from app.tools.registry import tool_registry app FastAPI(titleBnlAiCtrl AI Assistant Service) # 允许前端跨域访问实际部署时按域名收紧 app.add_middleware( CORSMiddleware, allow_origins[*], allow_credentialsTrue, allow_methods[*], allow_headers[*], ) session_manager SessionManager() llm_client LLMClient() class ChatRequest(BaseModel): session_id: str Field(..., description会话ID) message: str Field(..., description用户输入) user_id: str Field(anonymous, description用户标识) class ChatResponse(BaseModel): session_id: str reply: str tool_calls: List[dict] Field(default_factorylist, description本次触发的工具调用) need_confirm: bool Field(False, description是否有需要用户确认的写操作) app.post(/api/chat) async def chat(req: ChatRequest): session session_manager.get_or_create(req.session_id) messages session.messages() # 追加用户消息 session.append_user_message(req.message) # 调用大模型 result await llm_client.chat_with_tools( messagessession.messages(), toolstool_registry.tool_schemas(), user_idreq.user_id, ) if result.tool_calls: # 先把工具调用信息返回给前端由前端确认后执行 session.append_tool_calls(result.tool_calls) return ChatResponse( session_idreq.session_id, replyresult.content or 我计划执行以下操作请确认。, tool_callsresult.tool_calls, need_confirmTrue, ) # 无工具调用直接返回回答 session.append_ai_message(result.content) return ChatResponse( session_idreq.session_id, replyresult.content, tool_calls[], need_confirmFalse, ) app.post(/api/tools/confirm) async def confirm_tools(req: dict): session_id req.get(session_id) session session_manager.get_or_create(session_id) tool_calls session.pop_pending_tool_calls() if not tool_calls: raise HTTPException(status_code400, detail没有待确认的工具调用) results [] for call in tool_calls: # 执行工具这里必须校验权限 exec_result await tool_registry.execute( tool_namecall[name], argumentscall[arguments], user_idreq.get(user_id, anonymous), ) results.append(exec_result) # 把工具执行结果拼接后再次交给大模型生成最终回答 reply await llm_client.finalize_after_tools( session.messages(), tool_calls, results ) session.append_ai_message(reply) return {session_id: session_id, reply: reply} app.get(/api/health) async def health(): return {status: ok}这里把“调用大模型”和“执行工具”拆成了两个接口。第一次调用/api/chat只负责让大模型决定要不要调用工具把待确认的工具调用返回给前端用户点击确认后再调用/api/tools/confirm实际执行。这样能避免 AI 一上来就篡改配置。4.2 LLM 接口对接与配置大模型接口建议统一封装成LLMClient。文件路径app/llm/client.py。import os from typing import List, Optional from dataclasses import dataclass from openai import AsyncOpenAI dataclass class LLMResult: content: str tool_calls: Optional[list] None class LLMClient: def __init__(self): self.client AsyncOpenAI( api_keyos.getenv(LLM_API_KEY, your-api-key), base_urlos.getenv(LLM_BASE_URL, https://api.openai.com/v1), ) self.model os.getenv(LLM_MODEL, gpt-4o-mini) async def chat_with_tools(self, messages, tools, user_idNone): resp await self.client.chat.completions.create( modelself.model, messagesmessages, toolstools, tool_choiceauto, useruser_id, ) msg resp.choices[0].message tool_calls None if msg.tool_calls: tool_calls [ { id: tc.id, name: tc.function.name, arguments: tc.function.arguments, } for tc in msg.tool_calls ] return LLMResult(contentmsg.content, tool_callstool_calls) async def finalize_after_tools(self, messages, tool_calls, results): # 将工具调用结果追加到消息序列中 final_messages list(messages) ... resp await self.client.chat.completions.create( modelself.model, messagesfinal_messages, ) return resp.choices[0].message.content需要注意的是不同大模型服务返回tool_calls的字段结构会有细微差异。arguments是 JSON 字符串需要反序列化后再传给工具执行模块。生产环境建议再加上超时控制、重试机制和流式输出能力。4.3 工具注册与执行机制工具注册表是 AI 助手连接平台功能的中枢。文件路径app/tools/registry.py。import inspect import json from typing import Callable, Dict, List, Any class ToolRegistry: def __init__(self): self._tools: Dict[str, dict] {} def register(self, schema: dict): schema 示例 { name: get_vision_config, description: 获取当前视觉方案配置, parameters: { type: object, properties: {...}, required: [] }, handler: get_vision_config_handler } name schema[name] self._tools[name] schema def tool_schemas(self) - List[dict]: return [ { type: function, function: { name: s[name], description: s[description], parameters: s[parameters], }, } for s in self._tools.values() ] async def execute(self, tool_name: str, arguments: dict, user_id: str): if tool_name not in self._tools: raise ValueError(f工具 {tool_name} 不存在) schema self._tools[tool_name] handler schema[handler] # 执行前记录审计日志生产环境要记录 user_id、tool_name、arguments、时间 print(f[AUDIT] user{user_id} tool{tool_name} args{arguments}) result await handler(arguments, user_iduser_id) return result tool_registry ToolRegistry()在这个基础上开发新工具时只需要完成三件事编写工具执行函数。声明工具的 JSON Schema。调用tool_registry.register注册。这种设计让平台可以不断扩展新的 AI 能力而无需修改核心对话逻辑。4.4 对话历史与上下文管理对话上下文管理要注意两点一是不能无限追加历史消息否则会超出大模型上下文窗口二是工具调用结果需要保留在上下文中方便后续追问。一个简单的会话管理类如下。文件路径app/chat/session.py。import uuid from typing import List, Optional class Session: def __init__(self, session_id: str, max_messages: int 30): self.session_id session_id self.max_messages max_messages self._messages: List[dict] [] self._pending_tool_calls: Optional[list] [] def append_user_message(self, content: str): self._messages.append({role: user, content: content}) self._trim() def append_ai_message(self, content: str): self._messages.append({role: assistant, content: content}) self._trim() def append_tool_calls(self, tool_calls: list): self._pending_tool_calls tool_calls def pop_pending_tool_calls(self): calls self._pending_tool_calls or [] self._pending_tool_calls [] return calls def messages(self): return self._messages def _trim(self): if len(self._messages) self.max_messages: self._messages self._messages[-self.max_messages:] class SessionManager: def __init__(self): self._sessions: dict {} def get_or_create(self, session_id: str) - Session: if session_id not in self._sessions: self._sessions[session_id] Session(session_id) return self._sessions[session_id]生产环境建议把 Session 数据放到 Redis并设置过期时间避免内存占用无限增长。5. 平台侧工具集成视觉、运动控制、上位机5.1 视觉配置工具视觉工具用来读取和修改当前项目的视觉方案配置。以“读取视觉方案参数”为例# 文件路径app/tools/vision_tools.py import json from typing import Any from app.tools.registry import tool_registry async def get_vision_config_handler(args: dict, user_id: str): 实际项目里会从 BnlAiCtrl 配置库读取当前视觉方案的参数。 这里用一个字典模拟。 project_id args.get(project_id, P001) # 真实实现从数据库或配置文件加载 config { project_id: project_id, camera_exposure: 8000, camera_gain: 12.0, threshold: 128, processing_pipeline: [灰度化, 二值化, 轮廓提取, 中心点计算], } return json.dumps(config, ensure_asciiFalse) tool_registry.register({ name: get_vision_config, description: 获取指定项目的视觉方案配置包括相机曝光、增益、阈值和处理流程。, parameters: { type: object, properties: { project_id: { type: string, description: 项目编号例如 P001, } }, required: [project_id], }, handler: get_vision_config_handler, })视觉参数修改工具需要标记为“写操作”并且建议记录修改前后的差异便于回滚。这里有一个工程细节平台处理视觉任务时“要不要回调”常见于测量类应用。如果你的物料在运动过程中出现偏移通常需要视觉先输出坐标偏移量再由运动控制轴补偿。AI 助手可以通过读取配置帮助工程师快速判断是否需要加补偿逻辑。5.2 运动控制脚本生成工具运动控制工具的核心价值是“根据参数生成可用的运动控制程序”。比如用户希望生成一段“轴 0 相对移动 10mm”的代码工具可以自动拼接 BnlAiCtrl 接口调用。# 文件路径app/tools/motion_tools.py import json from app.tools.registry import tool_registry async def generate_motion_code_handler(args: dict, user_id: str): axis_id args.get(axis_id, 0) distance args.get(distance, 10.0) speed args.get(speed, 100.0) accel args.get(accel, 500.0) code f # 自动生成的运动控制逻辑 from bnlaictrl.core import MotionController mc MotionController() mc.get_axis({axis_id}).move_rel( distance{distance}, speed{speed}, accel{accel}, ) .strip() # 返回代码块方便前端直接展示 return json.dumps({axis_id: axis_id, code: code}, ensure_asciiFalse) tool_registry.register({ name: generate_motion_code, description: 根据轴号、距离、速度和加速度生成运动控制代码。, parameters: { type: object, properties: { axis_id: {type: integer, description: 轴号从0开始}, distance: {type: number, description: 相对移动距离单位mm}, speed: {type: number, description: 运动速度单位mm/s}, accel: {type: number, description: 加速度单位mm/s²}, }, required: [axis_id], }, handler: generate_motion_code_handler, })在真实平台中工具生成的代码不会直接执行而是先放到“待执行列表”里由操作员确认后再下发到运动控制器。AI 生成代码的作用是提高编程效率而不是替代安全确认流程。5.3 上位机界面代码生成工具上位机工具用于生成界面配置或者代码片段。BnlAiCtrl 的页面采用 JSON Schema 描述控件布局因此 AI 可以生成符合 Schema 的界面配置。# 文件路径app/tools/hmi_tools.py import json from app.tools.registry import tool_registry async def generate_hmi_panel_handler(args: dict, user_id: str): panel_name args.get(panel_name, 取料监控) variables args.get(variables, [x, y, theta]) # 生成一个简单的面板配置 controls [{ type: label, text: panel_name, font_size: 20, }] for var in variables: controls.append({ type: textbox, label: var, binding: fvision_result.{var}, readonly: True, }) controls.append({ type: button, text: 启动取料, action: start_pick, }) panel_config { panel_name: panel_name, layout: vertical, controls: controls, } return json.dumps(panel_config, ensure_asciiFalse) tool_registry.register({ name: generate_hmi_panel, description: 生成上位机界面面板配置可指定面板名称和需要显示的变量列表。, parameters: { type: object, properties: { panel_name: {type: string, description: 面板标题}, variables: { type: array, items: {type: string}, description: 需要绑定的变量名列表, }, }, required: [panel_name], }, handler: generate_hmi_panel_handler, })这个工具的好处是用户可以先用自然语言描述界面需求AI 直接生成面板配置省去手动拖拽控件和绑定变量的大量重复操作。5.4 配置执行与回滚机制配置类工具执行前必须做两件事校验参数合法性例如轴号不能超出范围、速度不能小于零。记录修改前的配置快照用于回滚。# 文件路径app/tools/motion_tools.py async def update_motion_node_handler(args: dict, user_id: str): node_id args.get(node_id) new_speed args.get(speed) old_config get_motion_node(node_id) # 假设函数存在 # 写配置前先保存快照 save_config_snapshot( node_idnode_id, user_iduser_id, old_valueold_config, new_value{speed: new_speed}, ) # 执行配置更新 update_motion_node(node_id, speednew_speed) return json.dumps({node_id: node_id, status: updated})平台侧工具是 AI 助手的“手和脚”没有这些工具AI 就只是一个聊天框。在非标自动化场景中工具的职责边界必须非常清楚生成脚本、读取配置、修改配置都可以交给 AI但最终设备动作必须由用户触发。6. 前端无代码界面接入6.1 在低代码页面中嵌入 AI 对话窗假设你的 BnlAiCtrl 上位机页面是基于 Vue 3 构建的可以直接把 AI 对话组件挂载到布局里。下面是一个简化版AiChatPanel.vue。template div classai-chat-panel div classchat-header spanBnlAiCtrl AI 助手/span button click$emit(close)关闭/button /div div classchat-messages refmessageBox div v-for(msg, index) in messages :keyindex :class[message, msg.role] pre v-ifmsg.type code{{ msg.content }}/pre div v-else{{ msg.content }}/div /div /div div v-ifpendingTools.length 0 classconfirm-bar pAI 请求执行以下操作/p ul li v-fortool in pendingTools :keytool.id {{ tool.name }} /li /ul button clickconfirmTools确认执行/button button clickcancelTools取消/button /div div classchat-input textarea v-modelinputText placeholder描述你的需求例如帮我配置视觉定位流程 keydown.enter.exact.preventsendMessage /textarea button clicksendMessage发送/button /div /div /template script setup import { ref, nextTick } from vue; const messages ref([]); const inputText ref(); const pendingTools ref([]); const sessionId ref(session_ Date.now()); async function sendMessage() { const text inputText.value.trim(); if (!text) return; messages.value.push({ role: user, content: text }); inputText.value ; const resp await fetch(/api/chat, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ session_id: sessionId.value, message: text, user_id: admin, }), }); const data await resp.json(); messages.value.push({ role: assistant, content: data.reply }); if (data.need_confirm data.tool_calls.length 0) { pendingTools.value data.tool_calls; } scrollToBottom(); } async function confirmTools() { const resp await fetch(/api/tools/confirm, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ session_id: sessionId.value, user_id: admin, }), }); const data await resp.json(); messages.value.push({ role: assistant, content: data.reply }); pendingTools.value []; scrollToBottom(); } function cancelTools() { pendingTools.value []; } function scrollToBottom() { nextTick(() { const box document.querySelector(.chat-messages); if (box) box.scrollTop box.scrollHeight; }); } /script style scoped .ai-chat-panel { width: 420px; border: 1px solid #ddd; border-radius: 8px; display: flex; flex-direction: column; } .chat-messages { flex: 1; max-height: 500px; overflow-y: auto; padding: 12px; } .message { margin-bottom: 8px; } .message.user { text-align: right; } .confirm-bar { border-top: 1px solid #ddd; padding: 8px; } .chat-input { display: flex; gap: 8px; padding: 8px; } /style在无代码平台里这个组件可以通过“自定义控件”的方式嵌入到任意页面而不需要修改框架内核。你可以把它理解为 BnlAiCtrl 预置的一个高级控件和普通文本框、按钮一样可以拖到画布上使用。6.2 对话流式输出一次请求等待大模型完整返回在网络状况不好时容易让用户觉得“卡住了”。更友好的做法是用 SSEServer-Sent Events流式输出。后端改造思路如下from fastapi.responses import StreamingResponse import json app.post(/api/chat/stream) async def chat_stream(req: ChatRequest): async def event_generator(): async for chunk in llm_client.stream_chat( session.messages(), tool_registry.tool_schemas() ): yield fdata: {json.dumps(chunk, ensure_asciiFalse)}\n\n return StreamingResponse( event_generator(), media_typetext/event-stream, headers{Cache-Control: no-cache, X-Accel-Buffering: no}, )前端通过EventSource或fetch读取流式增量。注意EventSource只能发送 GET 请求所以更常用的是fetchReadableStream方式读取 POST 接口的流。6.3 工具执行确认弹窗这是安全设计里最重要的一环。AI 生成的配置修改动作不能直接执行一定要等用户确认。前端在pendingTools不为空时弹出确认栏展示每一步要执行的工具名称和参数由用户决定是否继续。确认弹窗还可以增加一个“预览”功能。比如 AI 生成了一段运动控制代码前端可以在弹窗里直接显示代码内容用户确认后再写入平台。这样既保留了 AI 的便利性又把最终决定权放回到工程师手里。7. 完整实战AI 助手完成视觉引导取料配置7.1 项目需求假设我们接到一个非标自动化项目相机固定安装负责识别传送带上的物料中心点。机器人或运动轴需要根据视觉结果抓取物料。需要在 BnlAiCtrl 平台中完成视觉方案、运动程序和上位机界面的配置。传统做法是需要分别打开视觉配置页、运动控制脚本编辑页和上位机设计页至少需要半天时间。下面看 AI 助手如何把整个流程压缩到十几分钟。7.2 调用 AI 助手生成视觉脚本工程师在 AI 对话窗中输入请帮我配置一个视觉定位方案相机拍摄物料识别物料中心点坐标输出 X、Y 和旋转角度。物料是金属件表面有轻微反光。AI 助手经过意图识别后判断需要调用视觉配置工具。它会先生成一套初始参数{ camera_exposure: 6000, camera_gain: 8.0, threshold: 140, processing_pipeline: [灰度化, 高斯滤波, 二值化, 轮廓提取, 中心点计算, 旋转角度计算], outputs: [x, y, theta] }并在对话中解释金属件反光会导致边缘过曝建议降低曝光时间、适当增加滤波处理。工程师如果觉得没问题点击确认执行视觉方案节点写入平台。7.3 调用 AI 助手生成运动控制程序接着工程师继续对话视觉结果出来后让轴 0 移动到物料位置抓取取料安全高度 50mm速度 80mm/s。AI 助手调用运动控制脚本生成工具输出如下代码from bnlaictrl.core import MotionController mc MotionController() # 先移动到安全高度 mc.get_axis(0).move_abs(50, speed80) # 获取视觉结果 vision mc.get_vision_result(vision_node_1) x vision.x y vision.y theta vision.theta # 移动到物料位置补偿旋转角度 mc.get_axis(0).move_abs(x, y, speed80) mc.get_axis(0).move_abs(theta, speed40)这段代码会出现在确认弹窗中。工程师可以检查坐标单位、轴号和速度是否合理确认后写入运动控制节点。7.4 运行与验证最后AI 助手生成上位机面板配置包含“当前物料坐标”显示控件和“开始取料”按钮。工程师确认后面板自动出现在上位机页面中。点击“开始取料”后平台按以下顺序执行触发相机拍照。视觉节点返回物料中心点和角度。运动控制节点把坐标写入轴运动指令。轴移动到目标位置执行取料。上位机界面实时显示执行结果。整个过程里AI 助手负责的是“配置生成 参数建议 代码编写”设备动作仍然由操作员在界面上点击触发。这种设计既提高了效率也守住了安全底线。8. 常见问题与排查思路AI 助手集成过程中后端和前端都可能出现各种问题。下面整理几个高频问题。问题现象常见原因解决思路大模型返回空内容上下文过长或输入内容不合法检查消息长度适当裁剪历史消息确认tool_choice配置工具调用参数解析失败大模型返回的arguments不是合法 JSON用json.loads包一层异常处理解析失败时重试或提示用户重新描述确认执行后没有反应前端没有把session_id传回后端或后端 Session 过期检查前端请求参数Session Manager 改为 Redis 存储并设置有效期AI 回答与平台实际配置不一致工具返回的是缓存数据没有读取最新配置工具执行时直接读取配置库避免命中过期缓存跨域请求失败前端域名与后端服务域名不一致后端配置 CORS生产环境明确指定允许的域名列表大模型幻觉生成了不存在的 APIPrompt 中工具描述不够清晰或上下文缺少约束在 Prompt 中明确“只能调用已注册工具不能假设平台存在未声明的接口”前端代码块显示格式混乱返回内容中的代码没有使用 Markdown 代码块包装后端在返回代码片段时统一使用python包裹前端用 Markdown 渲染排查建议生产环境遇到问题建议先看三个地方后端日志重点看/api/chat的调用链确认大模型返回的 tool_calls 内容。工具审计日志确认工具是否被调用、参数是什么、执行结果是什么。前端 Network 面板确认/api/tools/confirm请求是否携带了正确的session_id。9. 最佳实践与工程建议9.1 模型选择与 Prompt 设计AI 助手的可用性很大程度上取决于 Prompt 设计。建议在系统 Prompt 中明确以下几点角色设定你是 BnlAiCtrl 平台的 AI 助手擅长机器视觉、运动控制和上位机配置。工具边界只能调用已提供的工具不能编造接口。回答风格先给结论再给参数解释必要时给出配置示例。安全约定涉及设备动作的操作必须提醒用户确认。如果你的场景需要处理中文专业术语建议在 Prompt 中补充一份“术语表”。比如“曝光时间”对应camera_exposure“轴 0”对应axis_id0可以明显减少大模型理解偏差。9.2 错误处理与超时控制大模型接口调用可能因为网络问题、服务端过载等原因超时。后端必须做好以下处理import asyncio from fastapi import HTTPException async def call_llm_with_timeout(coro, timeout30): try: return await asyncio.wait_for(coro, timeouttimeout) except asyncio.TimeoutError: raise HTTPException(status_code504, detailAI 服务响应超时请稍后重试)另外建议给大模型重试加指数退避策略避免高峰时段连续失败导致用户体验差。9.3 日志与审计由于 AI 助手能够修改平台配置日志和审计必须从第一天就做好。至少记录以下信息用户 ID、会话 ID、时间戳。模型请求的消息内容和返回结果。工具名称、调用参数、执行结果。确认动作由谁在什么时候触发。日志建议单独存储并定期备份。在非标自动化项目中这些日志不仅是排错依据也是责任追溯的重要凭证。9.4 权限与安全AI 助手集成后平台的攻击面变大了。需要重点注意接口鉴权/api/chat和/api/tools/confirm都必须要求登录态。工具权限不同角色能调用的工具不同。普通工程师只能调用只读工具项目管理员才能修改配置。敏感操作二次确认所有写操作都必须弹窗确认设备控制类操作禁止 AI 自动执行。敏感信息过滤日志中不要记录 API Key也不要记录完整的用户口令。10. 总结与后续规划这篇教程围绕 BnlAiCtrl 非标自动化无代码平台的 AI 助手集成梳理了从整体架构、工具注册、后端服务、前端嵌到完整案例的落地路径。核心要点可以总结为下面几条AI 助手必须建立在“工具调用”机制上大模型负责理解意图和生成参数平台工具负责实际执行。写配置与设备控制必须分开管理AI 可以生成代码和配置但不能在未经确认的情况下直接操作设备。前端对话窗属于无代码平台的一个高级控件可以嵌入视觉配置、运动控制和上位机设计任何页面。日志与审计是 AI 助手上生产环境的底线不能省。接下来可以考虑继续完善的方向包括基于 RAG 接入设备厂家手册让 AI 能回答针对特定轴卡、相机型号的问题增加多轮调优能力让 AI 根据视觉检测结果反向推荐参数调整方案把对话流式输出和语音播报加入上位机界面提高现场操作效率。如果你正在开发自己的非标自动化平台建议先从小范围读工具开始把 AI 助手接入“参数查询”和“脚本生成”两个场景跑通再逐步扩展到配置修改和跨模块协作。这种渐进式集成的风险更小也更容易让团队接受 AI 助手这个新角色。
返回列表