OpenGL渲染与几何内核那点事-项目实践理论补充(二-1-(4)-当你的CAD学会“听话”:从“按钮点击”到“自然语言诊断”的演进之路

张开发
2026/4/15 12:03:42 15 分钟阅读

分享文章

OpenGL渲染与几何内核那点事-项目实践理论补充(二-1-(4)-当你的CAD学会“听话”:从“按钮点击”到“自然语言诊断”的演进之路
TOC重要提示本文依旧按照之前的风格进行表达如果你想看看具体如何通过你的电子宠物【gemini、trae等】相互之间的交互包括提示词、反馈结果如果根据结果继续向AI发起追问直至拿到你想要的结果完成你的需求和目标可以看看如下的两篇OpenGL渲染与几何内核那点事-项目实践理论补充(二-1-(4)在你的两个AI小宠物GEMINI与TRAE的交互下帮你实现能听懂人话并诊断模型错误的小助手)OpenGL渲染与几何内核那点事-项目实践理论补充(二-1-(5)在你的GEMINI和TRAE 宠物帮助下帮你实现能听懂人话并诊断模型错误的小助手-问题总结和解决篇)代码仓库入口github源码地址。gitee源码地址。系列文章规划(OpenGL渲染与几何内核那点事-项目实践理论补充一-1-1从开发的视角看下CAD画出那些好看的图形们))OpenGL渲染与几何内核那点事-项目实践理论补充一-1-2看似“老派”的 C 底层优化恰恰是这些前沿领域最需要的基础设施OpenGL渲染与几何内核那点事-项目实践理论补充一-1-3你的 CAD 终于能画标准零件了但用户想要“弧面”、“流线型”怎么办OpenGL渲染与几何内核那点事-项目实践理论补充一-1-4GstarCAD / AutoCAD 客户端相关产品 —— 深入骨髓的数据库哲学OpenGL渲染与几何内核那点事-项目实践理论补充(一-1-(5)番外篇给 CAD 加上“控制台”——让用户能实时“调参数、看性能”)OpenGL渲染与几何内核那点事-项目实践理论补充(一-1-(6)番外篇让视图“活”起来——鼠标拖拽、缩放背后的数学魔法OpenGL渲染与几何内核那点事-项目实践理论补充(一-1-(7)-番外篇点击的瞬间发生了什么OpenGL渲染与几何内核那点事-项目实践理论补充(一-1-(8)-番外篇当你的 CAD 遇上“活”的零件)OpenGL渲染与几何内核那点事-项目实践理论补充(一-2-(1)-当你的CAD想“联网”时从单机绘图到多人实时协作)OpenGL渲染与几何内核那点事-项目实践理论补充(一-2-(2)-当你的CAD需要处理“百万个螺栓”时从内存爆炸到丝般顺滑)OpenGL渲染与几何内核那点事-项目实践理论补充(一-2-(3)-当你的协同CAD服务器面临“千人同屏”时从单机优化到分布式高并发)OpenGL渲染与几何内核那点事-项目实践理论补充(二-1-(2):当你的CAD学会“听话”从鼠标点击到自然语言命令)巨人的肩膀deepseekgemini当你的CAD学会“听话”从“按钮点击”到“自然语言诊断”的演进之路故事开篇用户不想点按钮了你的CAD查看器已经能加载STL、检查法线、检测冗余顶点甚至能通过故障注入验证算法正确性。用户很满意但总有人问“为什么我要记住‘check_normals’这个命令我就想说‘帮我看看这个模型有没有毛病’不行吗”你意识到自然语言交互才是真正的“智能”。用户不是程序员他们不想记指令。他们想要的是一个能“听懂人话”的助手——就像钢铁侠的贾维斯。但这条路比你想象的要长。让我们从最简单的方式开始一步步走向真正的AI Agent。第一阶段关键词匹配幼儿园水平你第一个想法很简单用户输入一句话你扫描里面有没有“法线”这个词。std::string userInput帮我检查一下法线有没有问题;if(userInput.find(法线)!std::string::npos){executeCheckNormals();}这个方案马上就能用。用户说“法线”“法线方向”“法线一致性”都能触发。你甚至加了英文支持normal。问题来了用户说“我想看看面的朝向”——不行因为没有“法线”二字。用户说“不要检查法线”——还是触发了因为包含了“法线”。用户说“检查一下顶点”——OK但如果说“看看有没有多余的点”又不认识了。你发现关键词匹配就像教一个婴儿他只知道“妈妈”“水”“饿”但听不懂“我渴了”。深度扩展字符串匹配的演进1. 朴素匹配Naive Matchingfind()函数O(n*m) 复杂度无法处理同义词、否定词。2. 正则表达式Regex可以匹配模式如法线|朝向|面的方向但依然受限于预定义词库。3. 词袋模型Bag of Words将句子分词统计每个词的TF-IDF计算与预定义意图的相似度。这是早期的文本分类方法。4. 局限无法理解“不”字否定无法处理多义词“面”可以是面条也可以是表面无法应对复杂的句式结构。第二阶段简单意图识别小学生水平你决定引入意图-槽位模型。意图就是用户想做什么检查法线、获取信息槽位就是参数阈值、文件名。你手写了一个简陋的分词器把句子切成词然后匹配一个预定义的意图字典。structIntent{std::string name;std::vectorstd::stringkeywords;std::vectorstd::stringnegativeKeywords;};std::vectorIntentintents{{check_normals,{法线,朝向,面的方向},{不要,别,取消}},{check_vertices,{顶点,冗余,孤立},{}},{get_info,{信息,大小,面数,顶点数},{}}};然后遍历句子如果命中某个意图的关键词且没有否定词就执行对应动作。这次好多了“面的方向对吗” → 命中check_normals“不要检查法线” → 因为包含“不要”跳过“这个模型有多大” → 命中get_info但还有问题“法线和顶点都查一下”——你想同时做两件事但意图识别只返回一个。“把半径大于5的面找出来”——需要参数半径阈值但你的简单匹配无法提取数字。深度扩展自然语言理解NLU基础1. 意图分类Intent Classification将用户输入分类到预定义的意图类别。传统方法TF-IDF 朴素贝叶斯/SVM深度学习方法BERT、RoBERTa 等预训练模型微调。2. 槽位填充Slot Filling从句子中提取参数如数字、日期、实体名称。常用模型BiLSTM-CRF、BERT for Token Classification。3. 联合模型Joint Model同时做意图分类和槽位填充共享编码层提升准确率。4. 中文分词挑战中文没有天然空格“检查法线”是“检查”“法线”但“南京市长江大桥”有歧义。需使用结巴分词、LTP、HanLP等工具。5. 否定词处理需要解析语法树判断否定词的修饰范围。“不要检查法线”否定的是“检查”“不检查法线但是检查顶点”则需要更复杂的逻辑。第三阶段正则表达式 参数提取中学生水平为了让用户能说“半径大于5的面”你开始写正则表达式来匹配数字和比较符。std::regexthresholdRegex(R(大于\s*(\d(?:\.\d)?)));std::smatch match;if(std::regex_search(userInput,match,thresholdRegex)){doublethresholdstd::stod(match[1]);executeGetCurvedSurfaces(threshold);}你也支持了组合命令如果句子包含“且”“和”“也”就拆分成多个子句分别处理。效果“半径大于5的曲面” → 正确提取5.0“检查法线同时也看看顶点” → 先查法线再查顶点新问题用户说“法线检查和顶点检查”——没加“和”你的拆分逻辑没识别。用户说“把所有法线反了的面标红”——你做不到因为“标红”是一个动作但你没有“修改渲染颜色”的功能。正则表达式越写越复杂维护成了噩梦。深度扩展正则表达式与上下文无关文法1. 正则表达式局限只能描述正则语言无法处理嵌套结构如“如果法线反向且顶点冗余则…否则…”。2. 上下文无关文法CFG可以用 BNF 描述命令语法如Command :: CheckCommand | InfoCommand CheckCommand :: 检查 Entity Entity :: 法线 | 顶点 | 曲面使用解析器生成器如 ANTLR、Boost.Spirit可以将自然语言子集编译成解析器。3. 槽位提取进阶使用 CRF条件随机场或 Spacy 的命名实体识别NER来提取数字、单位、实体类型。4. 组合命令解析需要构建语法树理解“先A后B”还是“同时A和B”。这涉及到时序逻辑。第四阶段函数调用Function Calling—— 真正的“AI原生”接口你开始思考与其自己写死所有匹配规则不如让大语言模型LLM来理解用户意图然后输出一个标准化的JSON。这就是OpenAI提出的Function Calling。你定义了一组函数工具每个函数有名称、描述、参数。然后你把用户的输入和这些函数定义一起发给LLM比如DeepSeek、GPT-4。LLM会返回一个JSON告诉你应该调用哪个函数参数是什么。// 函数定义{name:check_normals,description:检查模型的法线一致性找出法线反向的面片,parameters:{type:object,properties:{}}}{name:check_isolated_vertices,description:检测模型中未被任何面片引用的孤立顶点,parameters:{}}{name:get_curved_surfaces,description:找出曲率超过阈值的曲面,parameters:{threshold:{type:number,description:曲率阈值默认0.05}}}用户说“帮我看看这个模型有没有法线反了的地方”LLM返回{function:check_normals,arguments:{}}用户说“找出曲率大于0.1的曲面”LLM返回{function:get_curved_surfaces,arguments:{threshold:0.1}}这个方案的革命性你不再需要维护成百上千个关键词和正则表达式。LLM能理解同义词、否定、复杂句式。你可以轻松增加新功能只需在函数列表里加一个定义LLM就能学会调用它。你立刻在项目中集成了DeepSeek API。你的processUserInput变成了std::stringcallLLM(conststd::stringuserInput){// 构造prompt包含函数定义和用户输入// 发送HTTP请求到DeepSeek API// 解析返回的JSON提取function name和arguments}深度扩展大语言模型与函数调用1. Function Calling 原理LLM在训练时学习了大量的API调用数据。推理时你在prompt中提供函数签名JSON Schema模型会生成一个特殊的token序列表示“我要调用函数X参数是Y”。这不是真正的“调用”而是输出结构化文本。2. 实现方案对比OpenAI / DeepSeek / Claude原生支持function calling返回JSON。开源模型Llama 3, Qwen可通过prompt工程让模型输出特定格式再用正则提取。本地模型 工具调用框架如LangChain、Semantic Kernel封装了模型调用和函数执行。3. 上下文管理为了让LLM理解当前状态“这个模型”指的是哪个你需要把模型信息面数、文件名等也作为上下文传给LLM。4. 流式响应用户可能想要实时反馈可以使用SSE或WebSocket流式传输LLM的思考过程。5. 成本与延迟每次调用API需要几百毫秒到几秒且按token收费。优化方案本地缓存常见意图如“检查法线”的直接映射只有复杂句子才走LLM。6. 私有化部署对于企业用户数据不能出内网。你需要部署开源模型如Qwen-7B-Chat在本地GPU服务器再用vLLM或TGI提供服务。第五阶段从“听懂”到“诊断”——集成几何算法你已经在GeometryExpert里实现了checkNormals、checkIsolatedVertices等算法。现在只需要把它们注册成可调用的函数。你设计了一个统一的执行引擎classFunctionRegistry{std::unordered_mapstd::string,std::functionstd::string(constnlohmann::json)functions;public:voidregisterFunction(conststd::stringname,autofunc){functions[name]func;}std::stringexecute(conststd::stringname,constnlohmann::jsonargs){if(functions.count(name))returnfunctions[name](args);returnUnknown function;}};然后注册你的几何算法registry.registerFunction(check_normals,[this](constautoargs){returngeometryExpert.executeCommand(R({command: check_normals}));});registry.registerFunction(check_isolated_vertices,...);当LLM返回{function: check_normals}时你直接调用注册的函数拿到结果再返回给用户或显示在UI上。用户对话示例用户“这个模型能3D打印吗”LLM需要先检查法线一致性和流形性 → 调用check_normals和check_manifold→ 返回“有3个法线反向的面片建议修复后再打印”。深度扩展Agent架构与工具使用1. ReAct模式Reasoning ActingLLM先思考Reasoning再行动Acting然后观察结果Observation循环直到任务完成。例如思考“用户想知道能否打印我需要检查法线和流形”→行动“调用check_normals”→观察“有3个反向”→思考“需要修复”→行动“调用auto_repair”→观察“修复成功”→回答“可以打印”。2. 多工具协同一个任务可能需要调用多个工具如先get_model_info再check_normals。LLM需要规划工具调用顺序。3. 错误处理与重试如果工具调用失败如模型未加载LLM应能捕获错误并提示用户或尝试其他路径。4. 流形检测Manifold Detection除了法线和孤立顶点3D打印还需要检查非流形边一条边被三个面共享、孔洞、自交等。这些都可以作为独立工具注册。5. 自动修复你可以实现auto_repair_normals工具自动翻转反向的面片。LLM可以在用户授权后调用它。第六阶段从单机到分布式 —— 当你的AI助手需要服务千人你的CAD助手在本地运行得很好。但老板说“我们要做一个网页版让几千人同时在线用。”你面临新的挑战并发请求每个用户都可能调用LLM API成本飙升。模型加载每个用户上传自己的STL文件服务器内存爆炸。状态管理用户说“这个模型”时服务器必须知道是哪个模型。你开始设计分布式架构1. 会话隔离每个用户连接对应一个会话ID会话中存储当前加载的模型数据文件路径、三角形池指针。使用Redis存储会话元数据。2. 模型池Model Pool热门模型如标准零件库预加载到内存池冷模型按需从对象存储S3加载并设置LRU淘汰策略。3. LLM网关Gateway所有用户请求先经过一个缓存层。如果用户说的是“检查法线”这种常见指令直接命中本地缓存不走LLM。只有复杂请求才转发给LLM API并合并相似请求如去重、批处理。4. 异步任务队列几何诊断可能耗时几秒不能阻塞HTTP请求。用户提交命令后返回一个任务ID后端异步执行结果通过WebSocket推送给客户端。5. 水平扩展你的服务是无状态的会话状态在Redis可以随意增加实例。使用Kubernetes自动伸缩。深度扩展分布式AI服务架构1. 推理加速模型量化INT8/FP16量化减少显存占用提升推理速度。批处理Batching将多个用户的请求合并成一个batch一次性输入LLM显著提升吞吐量。投机解码Speculative Decoding用小模型快速生成候选大模型验证减少延迟。2. 缓存策略精确匹配缓存相同用户输入直接返回缓存结果。语义缓存使用向量数据库如Milvus、Qdrant存储用户输入的embedding新输入与历史输入计算相似度超过阈值则复用结果。3. 混合部署边缘计算在用户浏览器运行轻量级模型如TinyBERT做初步意图识别只有复杂请求才回源。云边协同本地模型处理常见指令云端处理长尾复杂指令。4. 成本控制预算限制设置每月LLM API调用上限超出后降级为本地关键词匹配。用户分级免费用户只能使用本地匹配付费用户享受LLM能力。5. 隐私与合规用户上传的模型数据属于敏感信息不能发送给第三方LLM API。解决方案本地部署开源模型如Qwen-7B所有计算在内网完成。使用联邦学习Federated Learning在用户本地微调模型不上传原始数据。第七阶段未来的方向 —— 多模态与主动助手你畅想下一步多模态输入用户画一个圈说“把这个区域里的孔都补上”。你需要结合图形交互鼠标圈选和自然语言。主动诊断助手不等人问自动扫描模型发现法线反了就弹窗提示“我注意到有3个面方向反了需要我帮你翻转吗”生成式设计用户说“设计一个能承受100kg重量的支架”助手自动生成多个候选模型用有限元分析筛选最优解。你发现自然语言不再是“命令”而是人与机器共同探索设计空间的媒介。你的CAD正在从“工具”变成“伙伴”。深度解析从关键词到Agent的全技术栈通过以上七个阶段我们走完了自然语言CAD助手从无到有、从简单到复杂、从单机到分布式的完整演进。下面我们将每个阶段涉及的核心技术点进行系统化、深度化的总结作为你博客的“硬核附录”。1. 字符串匹配与正则表达式KMP算法高效子串匹配O(nm)。实现简单适合固定关键词。正则表达式引擎PCRE、RE2Google出品保证线性时间复杂度。支持捕获组、反向引用、环视等高级特性。Aho-Corasick自动机同时匹配多个关键词时间复杂度O(n总匹配数)。常用于敏感词过滤、多关键词匹配。局限性只能处理字面量无法理解语义。“法线”和“面的法向”需要人工列举所有变体。2. 自然语言理解NLU经典方法分词最大匹配法正向/反向/双向、HMM隐马尔可夫模型、CRF条件随机场。现代工具Jieba、LTP、HanLP。词性标注识别名词、动词、形容词辅助意图解析。如“检查”是动词“法线”是名词。依存句法分析构建句法树理解“不检查法线”中“不”修饰“检查”而不是“法线”。意图分类模型传统TF-IDF 朴素贝叶斯 / SVM / 逻辑回归。深度学习TextCNN、LSTM、BERT微调。槽位填充模型序列标注BIO标注B-阈值、I-阈值、O。模型BiLSTM-CRF、BERT-tagger。指针网络直接输出参数在句子中的起始和结束位置。3. 大语言模型LLM与提示工程Transformer架构自注意力机制、多头注意力、位置编码、Feed-Forward网络。参数量从1B到1000B。提示工程技巧Few-shot在prompt中给2-3个例子指导模型输出格式。Chain-of-Thought要求模型先推理再输出提升复杂任务准确率。Self-consistency多次采样投票选出最一致的结果。Function Calling原理模型在训练时见过大量functiontoken的序列。推理时给定函数签名模型生成{name: func, arguments: {...}}。实现在tokenizer中加入特殊tokenfunction在训练数据中混合函数调用示例。开源模型部署llama.cpp纯C实现支持CPU推理适合边缘设备。vLLM高吞吐量推理引擎支持PagedAttention、连续批处理。TGIText Generation InferenceHugging Face出品支持流式输出、张量并行。量化技术GPTQ4-bit、AWQ激活感知量化、GGUFllama.cpp格式。INT4量化可将70B模型压缩到35GB几乎无损。4. 工具调用与Agent架构ReAct模式Thought → Action → Observation 循环。Thought让模型展示推理过程Action调用工具Observation返回结果模型据此修正下一步。LangChain最流行的Agent框架内置多种工具搜索、计算器、数据库支持自定义工具。Semantic Kernel微软出品深度集成C#适合企业级应用。工具注册与执行使用JSON Schema描述工具参数。执行时进行参数类型校验、默认值填充、异常捕获。支持异步工具如网络请求、长时几何计算。多步规划当任务需要多个工具时模型需要规划顺序。可以输出一个JSON数组包含多个函数调用。错误恢复如果工具返回错误模型应能解析错误信息并选择重试、换用其他工具或向用户提问澄清。5. 分布式服务架构无状态设计会话状态外置到Redis服务实例可随意扩缩容。任务队列使用RabbitMQ、Kafka或Redis Streams将耗时任务异步化返回task_id客户端轮询或WebSocket接收结果。缓存层级L1本地内存缓存Cstd::unordered_map LRU毫秒级。L2Redis微秒级跨实例共享。L3向量数据库Milvus、Qdrant用于语义缓存。负载均衡四层LVS、HAProxy按IP分发。七层Nginx、Envoy按URL路径、header分发。一致性哈希将同一会话的请求路由到同一实例提高缓存命中率。限流与熔断令牌桶算法限制QPS。熔断器Hystrix、Resilience4j下游服务异常时快速失败防止雪崩。可观测性日志结构化日志JSON格式使用ELK或Loki收集。指标Prometheus采集QPS、延迟、错误率、GPU利用率。链路追踪Jaeger或Zipkin追踪一次请求跨多个服务的完整路径。6. 本地化与隐私保护本地模型部署硬件要求7B模型需16GB显存FP1670B需140GB可多卡并行。推理框架TensorRT-LLM英伟达官方性能最佳、vLLM、TGI。混合推理简单指令走本地模型延迟低、免费。复杂指令云端API准确率高。敏感数据请求拒绝云端转发。联邦学习用户在本地微调模型只上传梯度或模型差分不传原始数据。框架FATE、TensorFlow Federated。差分隐私在模型输出中添加噪声使得无法反推具体用户数据。7. 未来趋势多模态模型GPT-4V、ImageBind、Unified-IO 2能同时理解图像、深度、点云、文本。你的CAD可以直接“看”模型截图而不需要解析STL。世界模型Sora、Genie能模拟物理规律。未来的CAD助手可以“想象”零件装配后的受力情况并给出建议。Agent自主编程用户说“我想加一个功能自动把法线反的面翻转”Agent直接修改你的C代码并重新编译。这已经由Devin等产品展示了雏形。你现在已经拥有了从“关键词匹配”到“分布式Agent”的全套知识。你的CAD小助手终于能真正“听懂人话”了。如果想了解一些成像系统、图像、人眼、颜色等等的小知识快去看看视频吧 抖音数字图像哪些好玩的事咱就不照课本念轻轻松松谝闲传快手数字图像哪些好玩的事咱就不照课本念轻轻松松谝闲传B站数字图像哪些好玩的事咱就不照课本念轻轻松松谝闲传认准一个头像保你不迷路您要是也想站在文章开头的巨人的肩膀啦可以动动您发财的小指头然后把您的想要展现的名称和公开信息发我这些信息会跟随每篇文章屹立在文章的顶部哦

更多文章