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

0 阅读22分钟
  • 故事开篇:用户不想点按钮了

  • 第一阶段:关键词匹配(幼儿园水平)

  • 深度扩展:字符串匹配的演进

  • 第二阶段:简单意图识别(小学生水平)

  • 深度扩展:自然语言理解(NLU)基础

  • 第三阶段:正则表达式 + 参数提取(中学生水平)

  • 深度扩展:正则表达式与上下文无关文法

  • 第四阶段:函数调用(Function Calling)—— 真正的“AI原生”接口

  • 深度扩展:大语言模型与函数调用

  • 第五阶段:从“听懂”到“诊断”——集成几何算法

  • 深度扩展:Agent架构与工具使用

  • 第六阶段:从单机到分布式 —— 当你的AI助手需要服务千人

  • 深度扩展:分布式AI服务架构

  • 第七阶段:未来的方向 —— 多模态与主动助手

  • 深度解析:从关键词到Agent的全技术栈

  • 1. 字符串匹配与正则表达式

  • 2. 自然语言理解(NLU)经典方法

  • 3. 大语言模型(LLM)与提示工程

  • 4. 工具调用与Agent架构

  • 5. 分布式服务架构

  • 6. 本地化与隐私保护

  • 7. 未来趋势


重要提示:本文依旧按照之前的风格进行表达,如果你想看看具体如何通过你的电子宠物【gemini、trae等】相互之间的交互(包括提示词、反馈结果,如果根据结果继续向AI发起追问,直至拿到你想要的结果),完成你的需求和目标,可以看看如下的两篇:

  • OpenGL渲染与几何内核那点事-项目实践理论补充(二-1-(4):在你的两个AI小宠物GEMINI与TRAE的交互下,帮你实现能听懂人话并诊断模型错误的小助手)-(ywmhhbaiminminai.github.io/archives/20…)

  • OpenGL渲染与几何内核那点事-项目实践理论补充(二-1-(5):在你的GEMINI和TRAE 宠物帮助下,帮你实现能听懂人话并诊断模型错误的小助手-问题总结和解决篇)-(ywmhhbaiminminai.github.io/archives/20…)


代码仓库入口:


系列文章规划:

  • (OpenGL渲染与几何内核那点事-项目实践理论补充(一-1-(1):从开发的视角看下CAD画出那些好看的图形们))

  • OpenGL渲染与几何内核那点事-项目实践理论补充(一-1-(2):看似“老派”的 C++ 底层优化,恰恰是这些前沿领域最需要的基础设施)

  • OpenGL渲染与几何内核那点事-项目实践理论补充(一-1-(3):你的 CAD 终于能画标准零件了,但用户想要“弧面”、“流线型”,怎么办?)

  • OpenGL渲染与几何内核那点事-项目实践理论补充(一-1-(4):GstarCAD / 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学会“听话”:从鼠标点击到自然语言命令)

巨人的肩膀:

  • deepseek

  • gemini


当你的CAD学会“听话”:从“按钮点击”到“自然语言诊断”的演进之路

故事开篇:用户不想点按钮了

你的CAD查看器已经能加载STL、检查法线、检测冗余顶点,甚至能通过故障注入验证算法正确性。用户很满意,但总有人问:“为什么我要记住‘check_normals’这个命令?我就想说‘帮我看看这个模型有没有毛病’,不行吗?”

你意识到,自然语言交互才是真正的“智能”。用户不是程序员,他们不想记指令。他们想要的是一个能“听懂人话”的助手——就像钢铁侠的贾维斯。

但这条路,比你想象的要长。让我们从最简单的方式开始,一步步走向真正的AI Agent。


第一阶段:关键词匹配(幼儿园水平)

你第一个想法很简单:用户输入一句话,你扫描里面有没有“法线”这个词。

std::string userInput = "帮我检查一下法线有没有问题";
if (userInput.find("法线") != std::string::npos) {
    executeCheckNormals();
}

这个方案马上就能用。用户说“法线”“法线方向”“法线一致性”,都能触发。你甚至加了英文支持:"normal"

问题来了

  • 用户说“我想看看面的朝向”——不行,因为没有“法线”二字。

  • 用户说“不要检查法线”——还是触发了,因为包含了“法线”。

  • 用户说“检查一下顶点”——OK,但如果说“看看有没有多余的点”,又不认识了。

你发现,关键词匹配就像教一个婴儿:他只知道“妈妈”“水”“饿”,但听不懂“我渴了”。

深度扩展:字符串匹配的演进

1. 朴素匹配(Naive Matching)find() 函数,O(n*m) 复杂度,无法处理同义词、否定词。2. 正则表达式(Regex):可以匹配模式,如 "法线|朝向|面的方向",但依然受限于预定义词库。3. 词袋模型(Bag of Words):将句子分词,统计每个词的TF-IDF,计算与预定义意图的相似度。这是早期的文本分类方法。4. 局限:无法理解“不”字否定,无法处理多义词(“面”可以是面条也可以是表面),无法应对复杂的句式结构。


第二阶段:简单意图识别(小学生水平)

你决定引入意图-槽位模型。意图就是用户想做什么(检查法线、获取信息),槽位就是参数(阈值、文件名)。

你手写了一个简陋的分词器:把句子切成词,然后匹配一个预定义的意图字典。

struct Intent {
    std::string name;
    std::vector<std::string> keywords;
    std::vector<std::string> negativeKeywords;
};
std::vector<Intent> intents = {
    {"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::regex thresholdRegex(R"(大于\s*(\d+(?:\.\d+)?))");
std::smatch match;
if (std::regex_search(userInput, match, thresholdRegex)) {
    double threshold = std::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::string callLLM(const std::string& userInput) {
    // 构造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里实现了checkNormalscheckIsolatedVertices等算法。现在只需要把它们注册成可调用的函数。

你设计了一个统一的执行引擎:

class FunctionRegistry {
    std::unordered_map<std::string, std::function<std::string(const nlohmann::json&)>> functions;
public:
    void registerFunction(const std::string& name, auto&& func) {
        functions[name] = func;
    }
    std::string execute(const std::string& name, const nlohmann::json& args) {
        if (functions.count(name)) return functions[name](args);
        return "Unknown function";
    }
};

然后注册你的几何算法:

registry.registerFunction("check_normals", [this](const auto& args) {
    return geometryExpert.executeCommand(R"({"command": "check_normals"})");
});
registry.registerFunction("check_isolated_vertices", ...);

当LLM返回{"function": "check_normals"}时,你直接调用注册的函数,拿到结果,再返回给用户(或显示在UI上)。

用户对话示例

  • 用户:“这个模型能3D打印吗?”

  • LLM:需要先检查法线一致性和流形性 → 调用check_normalscheck_manifold → 返回“有3个法线反向的面片,建议修复后再打印”。

深度扩展:Agent架构与工具使用

1. ReAct模式(Reasoning + Acting):LLM先思考(Reasoning),再行动(Acting),然后观察结果(Observation),循环直到任务完成。例如:思考“用户想知道能否打印,我需要检查法线和流形”→行动“调用check_normals”→观察“有3个反向”→思考“需要修复”→行动“调用auto_repair”→观察“修复成功”→回答“可以打印”。2. 多工具协同:一个任务可能需要调用多个工具,如先get_model_infocheck_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(n+m)。实现简单,适合固定关键词。

  • 正则表达式引擎:PCRE、RE2(Google出品,保证线性时间复杂度)。支持捕获组、反向引用、环视等高级特性。

  • 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原理

  • 模型在训练时见过大量function token的序列。推理时,给定函数签名,模型生成{"name": "func", "arguments": {...}}

  • 实现:在tokenizer中加入特殊token <function>,在训练数据中混合函数调用示例。

  • 开源模型部署

  • llama.cpp:纯C++实现,支持CPU推理,适合边缘设备。

  • vLLM:高吞吐量推理引擎,支持PagedAttention、连续批处理。

  • TGI(Text Generation Inference):Hugging Face出品,支持流式输出、张量并行。

  • 量化技术:GPTQ(4-bit)、AWQ(激活感知量化)、GGUF(llama.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:本地内存缓存(C++ std::unordered_map + LRU),毫秒级。

  • L2:Redis,微秒级,跨实例共享。

  • L3:向量数据库(Milvus、Qdrant),用于语义缓存。

  • 负载均衡

  • 四层(LVS、HAProxy):按IP分发。

  • 七层(Nginx、Envoy):按URL路径、header分发。

  • 一致性哈希:将同一会话的请求路由到同一实例,提高缓存命中率。

  • 限流与熔断

  • 令牌桶算法:限制QPS。

  • 熔断器(Hystrix、Resilience4j):下游服务异常时快速失败,防止雪崩。

  • 可观测性

  • 日志:结构化日志(JSON格式),使用ELK或Loki收集。

  • 指标:Prometheus采集QPS、延迟、错误率、GPU利用率。

  • 链路追踪:Jaeger或Zipkin,追踪一次请求跨多个服务的完整路径。

6. 本地化与隐私保护

  • 本地模型部署

  • 硬件要求:7B模型需16GB显存(FP16),70B需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站:数字图像哪些好玩的事,咱就不照课本念,轻轻松松谝闲传

  • 您要是也想站在文章开头的巨人的肩膀啦,可以动动您发财的小指头,然后把您的想要展现的名称和公开信息发我,这些信息会跟随每篇文章,屹立在文章的顶部哦在这里插入图片描述