首页/新闻资讯/正文详情

从零手搓AI工程:不依赖框架实现RAG全链路

发布时间:2026/11/3 21:07:21 来源:云帆数科 栏目:资讯中心
从零手搓AI工程:不依赖框架实现RAG全链路
1. 从零搭建AI工程能力为什么“手搓一遍”比调包更值钱这两年AI应用层的工具链成熟得吓人LangChain、LlamaIndex、各种Agent框架几乎把能封装的都封装了。打开文档几行代码就能跑通一个RAG问答复制一段示例十分钟搭出一个对话机器人。表面上看门槛被拉到了地板但真正做过线上项目的人心里都清楚——能跑通Demo和能扛住生产中间隔着一整条工程化的鸿沟。ai-engineering-from-scratch这个标题说的就是一件很“笨”但很值钱的事不依赖高层框架从最底层的原理和最小依赖开始把AI工程里那些关键环节自己实现一遍。它不是一个具体的开源库而更像一种学习路径和工程方法论——把检索、向量化、提示编排、上下文管理、评测这些模块用最朴素的方式亲手搭起来搞清楚每一步到底发生了什么。我为什么觉得这件事值得做因为我在实际项目里踩过太多“黑盒坑”。用框架时一切正常一旦效果不达预期你根本不知道问题出在切分策略、嵌入模型、还是检索排序上。框架帮你省了写代码的时间但也顺手把可观测性和可调试性一起藏了起来。当你被迫从零实现一遍那些原本模糊的概念会瞬间变得具体为什么chunk大小要这么设、为什么top-k不能拍脑袋定、为什么重排序能救回一大半的召回质量。这篇内容适合三类人一是刚入行AI应用、只会调API但想搞懂底层机制的开发者二是被框架“惯坏”后遇到瓶颈、想重建技术判断力的工程师三是准备做技术选型、需要评估各环节真实成本的团队负责人。我会按一个完整的从零实现路径来讲从整体设计思路到每个核心模块的细节和实操再到我实际踩过的坑和排查方法。全程不依赖重型框架代码能跑、参数有依据、坑有出处。2. 整体设计与思路拆解为什么选择“最小依赖”路线2.1 核心思路把AI应用拆成可独立验证的积木从零做AI工程第一步不是写代码而是想清楚一个AI应用到底由哪些独立环节组成。我的拆法是五块积木文档加载与切分、向量化与索引、检索与重排序、提示编排与生成、评测与回归。这五块每一块都可以单独测试、单独替换、单独优化彼此之间通过清晰的数据结构通信。为什么强调“独立验证”因为AI系统最大的痛点是效果归因困难。用户说“答得不准”可能是切分把关键信息切断了可能是嵌入模型对领域词汇不敏感可能是检索召回了无关内容也可能是提示词把上下文用错了。如果这些环节耦合在一个黑盒里你只能靠猜。拆成积木后你可以固定其他四块只动一块用同一批测试用例对比效果——这才是工程化的调试方式。我选择最小依赖路线具体是指向量计算用NumPy手写余弦相似度不引入向量数据库文本切分自己写规则不用框架的splitter检索排序自己实现不调现成的rerank服务。这样做不是为了“炫技”而是为了让每个环节的行为完全透明。等你把原理跑通、知道每个参数的影响后再换成生产级组件你会有明确的选型依据而不是被文档牵着走。2.2 方案选型背后的取舍逻辑有人会问都2024年了为什么还要手写余弦相似度直接用FAISS或者向量数据库不香吗这里要区分学习阶段和生产阶段。学习阶段的目标是建立心智模型手写一遍能让你彻底理解“向量检索本质就是高维空间里的最近邻搜索”这件事理解为什么归一化很重要、为什么内积和余弦在归一化后等价。等你理解了生产阶段当然该用成熟组件。再比如切分策略。框架通常提供按字符、按token、按递归分隔符等几种模式但它们不会告诉你为什么你的场景该用哪种。自己实现一遍后你会发现按固定字符切分简单但会切断语义按段落切分保留语义但长度不可控递归切分是折中但分隔符优先级需要针对你的文档类型调。这些认知只有亲手写过、对比过不同策略的召回效果才会真正长在身上。还有一个关键取舍是评测先行。很多团队是先做功能再想评测结果做完了不知道好不好。我的做法是从第一天就建一个小的评测集哪怕只有二三十条问答对每次改动都跑一遍。这个评测集不需要多完美它的价值在于提供相对比较的基准——你改了切分参数分数涨了还是跌了一目了然。这是从零做AI工程最容易被忽略、但回报最高的一步。2.3 整体数据流设计把五块积木串起来完整的数据流是这样的原始文档经过加载和切分变成一批文本块每个文本块经过嵌入模型变成向量存进一个简单的索引结构用户提问时问题也被嵌入成向量在索引里检索出top-k相关块这些块经过重排序精排后按相关性拼进提示词最后交给生成模型产出回答。评测环节则贯穿始终对每个阶段的输出都能单独打分。这个数据流看起来简单但每一环都有讲究。比如索引结构我一开始用最简单的列表存所有向量检索时全量算相似度。文档少的时候没问题上千个块之后延迟就上来了。这时候你自然会想到用近似最近邻算法也就理解了为什么生产环境需要专门的向量数据库。这种“先遇到问题再解决”的路径比直接上重型组件更能建立技术判断力。3. 核心细节解析与实操要点五个模块的深水区3.1 文档切分被低估的效果杀手切分是整条链路里最不起眼、但影响最大的环节。我见过太多项目检索效果差最后发现是切分把答案切成了两半检索时只召回了一半生成模型自然答不全。自己实现切分核心要处理三件事切分单位、块大小、重叠策略。切分单位我推荐按语义边界优先——段落、句子、列表项实在不行再按字符硬切。块大小没有万能值但有个经验公式块大小应该略大于你期望回答所依赖的最小完整语义单元。比如FAQ场景一个问答对就是一个单元块大小设成能容纳一个完整问答即可长文档摘要场景块可以大一些保留更多上下文。重叠策略是很多人忽略的点。块之间留10%到20%的重叠能有效缓解“答案正好卡在边界”的问题。但重叠不是越多越好重叠太多会导致检索结果高度重复浪费上下文窗口。我实测下来重叠比例设在块大小的15%左右是个比较稳的起点然后根据评测结果微调。def split_by_semantic(text, max_len500, overlap75): # 先按段落切再合并到接近max_len paragraphs [p.strip() for p in text.split(\n\n) if p.strip()] chunks, current [], for p in paragraphs: if len(current) len(p) max_len: current (\n\n if current else ) p else: if current: chunks.append(current) # 处理超长段落按句子再切 if len(p) max_len: sentences p.replace(。, 。\n).split(\n) buf for s in sentences: if len(buf) len(s) max_len: buf s else: chunks.append(buf) buf s current buf else: current p if current: chunks.append(current) # 加重叠 result [] for i, c in enumerate(chunks): if i 0: c chunks[i-1][-overlap:] c result.append(c) return result注意重叠部分会让块的实际长度超过max_len如果你的嵌入模型有硬性token上限记得把重叠算进去否则会被静默截断导致尾部信息丢失。3.2 向量化与索引理解相似度的本质嵌入模型把文本变成向量这一步的选型直接决定检索质量的上限。从零实现时我建议先用一个通用的开源嵌入模型跑通流程重点理解向量维度、归一化、相似度度量这三件事的关系。向量维度决定了表达能力但不是越高越好。高维向量检索慢、存储大而且很多模型的高维部分信息量并不高。归一化是把向量长度统一到1这样内积就等于余弦相似度计算更简单。相似度度量里余弦相似度关注方向、欧氏距离关注绝对位置文本检索通常用余弦更合适因为文本的“语义方向”比“绝对位置”更有意义。索引结构从零实现我推荐先用一个二维NumPy数组存所有向量检索时做矩阵乘法一次性算出所有相似度。这个方案在几千个块以内完全够用而且代码极简、行为完全透明。import numpy as np class SimpleIndex: def __init__(self): self.vectors None self.texts [] def add(self, vectors, texts): vectors np.array(vectors, dtypenp.float32) # 归一化让内积等价于余弦相似度 norms np.linalg.norm(vectors, axis1, keepdimsTrue) vectors vectors / np.clip(norms, 1e-8, None) if self.vectors is None: self.vectors vectors else: self.vectors np.vstack([self.vectors, vectors]) self.texts.extend(texts) def search(self, query_vec, top_k5): q np.array(query_vec, dtypenp.float32) q q / np.clip(np.linalg.norm(q), 1e-8, None) scores self.vectors q # 归一化后内积即余弦 idx np.argsort(-scores)[:top_k] return [(self.texts[i], float(scores[i])) for i in idx]提示归一化时一定要加一个极小值防止除零我见过因为某个向量全零导致整个检索返回NaN的案例排查了半天。3.3 检索与重排序召回和精排是两件事检索分两个阶段召回和精排。召回阶段追求“不漏”用向量相似度快速从海量块里捞出候选精排阶段追求“准”用更重的模型对候选重新打分排序。很多人把这两步混为一谈结果要么召回不够、要么排序不准。从零实现时召回用上面的SimpleIndex就够了。精排我推荐引入一个交叉编码器cross-encoder的思路把查询和候选块拼在一起送进模型打分而不是分别编码后算相似度。交叉编码器能捕捉查询和文档之间的交互信息精度明显高于双塔式的向量相似度代价是慢——所以只用在top-k的少量候选上。如果不想引入额外模型也可以用一些轻量的重排信号关键词覆盖率、块的位置权重、块的长度惩罚等。我实测下来简单的关键词覆盖率重排就能把召回质量提升一截因为向量相似度有时会漏掉字面匹配这种强信号。def rerank(query, candidates, keyword_weight0.3): query_terms set(query.lower().split()) scored [] for text, vec_score in candidates: text_terms set(text.lower().split()) overlap len(query_terms text_terms) / max(len(query_terms), 1) final (1 - keyword_weight) * vec_score keyword_weight * overlap scored.append((text, final)) return sorted(scored, keylambda x: -x[1])3.4 提示编排上下文不是越多越好检索出一堆块之后怎么塞进提示词直接决定生成质量。新手常犯的错是把top-k全部拼进去觉得信息越多越好。实际上上下文过长会稀释关键信息还可能引入矛盾内容让模型无所适从。我的做法是先按相关性排序从高到低逐个加入直到接近上下文预算就停。同时给每个块加上来源标记方便模型引用也方便你排查。提示词结构上我习惯把指令放前面、上下文放中间、问题放最后这样模型在生成时离问题最近注意力更集中。还有一个细节是指令要明确告诉模型“只用给定上下文回答”并给出“如果上下文没有答案就直说”的兜底。这一条能大幅降低幻觉率我实测下来比任何花哨的提示技巧都管用。3.5 评测没有评测就没有优化评测是从零做AI工程里最容易被跳过、但最不能跳过的一环。我的评测集构建方法是从真实文档里挑出二三十个有代表性的问题人工标注每个问题的标准答案和应该被召回的关键块。这样你既能评生成质量也能评检索质量。评测指标上检索用召回率关键块有没有被召回和MRR关键块排在第几位生成用人工打分或用一个强模型做裁判。每次改动只动一个变量跑一遍评测看分数变化。这套流程听起来笨但它是唯一能让你**从“感觉好像好了点”变成“确实好了X%”**的方法。4. 实操过程与核心环节实现从空目录到能跑的问答系统4.1 环境准备与依赖选择从零做依赖就要克制。我的最小依赖清单是NumPy做向量计算一个嵌入模型的客户端可以是本地模型也可以是API一个生成模型的客户端再加一个简单的HTTP框架如果需要暴露接口。不需要LangChain不需要向量数据库不需要复杂的配置管理。为什么这么克制因为每多一个依赖就多一层你不理解的抽象。学习阶段的目标是理解不是效率。等你把整条链路跑通、知道每个环节的瓶颈在哪再按需引入组件那时候你是带着明确目的去选的而不是被框架的默认行为绑架。环境搭好后先写一个最小的端到端脚本读一个文档、切分、嵌入、存索引、检索、拼提示、生成。这个脚本可能只有一百多行但它跑通的那一刻你就拥有了一个完全可控的AI应用骨架。4.2 端到端流程的关键参数计算参数不能拍脑袋要有计算依据。以块大小为例假设你的嵌入模型上下文上限是512个token中文大致1个token对应1.5到2个字符那么块大小上限大约是512乘以1.5再打个折取600到700字符比较稳。再考虑重叠15%实际块大小设500到600字符重叠75到90字符。top-k怎么定看你的上下文预算。假设生成模型上下文窗口是8k token提示词模板和问题占1k剩下7k给上下文。每个块平均500字符约300 token那么最多能放23个块。但实际不需要放满我通常从top-5开始根据评测结果调整。top-k不是越大越好超过某个点后加入的都是低相关块反而拉低质量。重排序的候选数一般是top-k的3到5倍。比如最终要5个块召回阶段取20个候选精排后取前5。这样既保证召回率又控制精排成本。4.3 一次完整的调试记录我拿一份技术文档做测试第一版跑出来效果很差答非所问。排查过程是这样的先看检索结果发现召回的块和问题相关性很低。于是单独测嵌入模型发现它对文档里的专业术语不敏感通用模型对领域词汇的语义捕捉确实弱。换了一个在技术语料上表现更好的嵌入模型后召回明显改善。但还有问题有些答案明明在文档里却没被召回。检查切分结果发现答案被切成了两半前半段在一个块里后半段在另一个块里检索只召回了其中一个。调整切分策略让块边界尽量落在段落边界并加大重叠问题解决。最后一轮优化是重排序。加入关键词覆盖率重排后原本排在第7、第8的关键块被提到了前3生成质量又上一个台阶。整个过程我改了三次切分、换了两次嵌入模型、调了一次重排权重每一步都有评测数据支撑不是瞎调。4.4 把系统跑起来的完整代码骨架# 1. 加载与切分 raw open(doc.txt, encodingutf-8).read() chunks split_by_semantic(raw, max_len550, overlap80) # 2. 嵌入与索引 vectors [embed(c) for c in chunks] index SimpleIndex() index.add(vectors, chunks) # 3. 检索与重排 q_vec embed(question) candidates index.search(q_vec, top_k20) ranked rerank(question, candidates)[:5] # 4. 提示编排 context \n\n.join(f[来源{i1}] {t} for i, (t, _) in enumerate(ranked)) prompt f仅根据以下上下文回答问题上下文没有的信息不要编造。 如果无法从上下文得出答案直接说“根据现有资料无法回答”。 上下文 {context} 问题{question} # 5. 生成 answer generate(prompt) print(answer)这段骨架没有任何框架依赖每一行你都能看懂、能改、能调试。这就是从零做AI工程的价值——你拥有完整的控制权和可观测性。5. 常见问题与排查技巧实录那些文档不会告诉你的坑5.1 检索效果差的排查顺序检索效果差是最常见的问题排查要有顺序别乱试。我的排查顺序是先看切分结果确认答案所在的块是否完整再看嵌入模型用几个已知相关的查询-文档对测相似度看模型是否能区分最后看相似度计算确认归一化和度量方式没问题。这个顺序的逻辑是从上游到下游因为上游的问题会污染下游的所有环节。切分错了再好的嵌入模型也救不回来嵌入模型不行再精细的重排也是垃圾进垃圾出。我见过有人一上来就调top-k和重排权重结果根因在切分白折腾半天。5.2 生成质量不稳定的应对生成质量忽好忽坏通常是上下文不稳定导致的。同一个问题两次检索召回的块略有不同生成结果就差异很大。解决办法有两个一是降低检索的随机性确保相同问题召回相同块二是在提示词里强化约束让模型严格基于上下文。还有一个隐蔽原因是上下文里的矛盾信息。如果召回的块里有相互矛盾的内容模型会摇摆。这时候要么提高重排精度把低质量块过滤掉要么在提示词里明确告诉模型“如果上下文有冲突以更具体、更近期的信息为准”。5.3 常见问题速查表现象可能原因排查方法解决方向答非所问检索召回无关块打印召回块人工检查换嵌入模型或调切分答案不完整答案被切分切断检查切分边界加大重叠或按语义切幻觉严重上下文不足或指令不清检查提示词约束强化“仅用上下文”指令响应慢全量相似度计算计时各环节引入近似检索或缓存结果不稳定检索随机性固定随机种子确保检索确定性专业术语检索差通用嵌入模型不敏感测领域词相似度换领域模型或加关键词重排5.4 几个我踩过的坑第一个坑是嵌入模型的token上限被静默截断。有些模型超长输入不报错直接截断导致块尾信息丢失。解决办法是在嵌入前先按token数检查超长的块先切短。第二个坑是归一化遗漏。有一次我忘了归一化用内积当相似度结果长向量天然得分高检索全被长块霸占。归一化后问题消失。这个坑很隐蔽因为不归一化也能跑只是结果悄悄变差。第三个坑是评测集泄露。我一开始用评测集里的问题去调参数调着调着分数很高但换一批新问题就崩了。后来我把评测集分成调参集和验证集调参只用调参集验证集只在最后跑才得到真实的效果评估。经验调参时一定要留一手别把所有数据都用来调否则你调出来的是对这批数据的过拟合不是真实能力。6. 从零实现之后什么时候该引入重型组件把整条链路手写一遍之后你会对每个环节的瓶颈有清晰认知这时候再决定引入什么组件就是有的放矢。如果检索延迟成为瓶颈引入近似最近邻或向量数据库如果嵌入质量不够换更强的模型或做领域微调如果重排精度不够引入交叉编码器如果评测太慢搭建自动化评测流水线。关键区别在于这时候你是带着问题和数据去选型的而不是被框架的默认行为牵着走。你知道向量数据库解决的是检索速度问题知道交叉编码器解决的是排序精度问题知道每个组件的引入会带来什么收益、什么成本。这种判断力才是从零做AI工程真正要收获的东西。我个人在实际操作中的体会是手写一遍花的时间远比想象中少但带来的认知提升远超预期。那些原本在框架文档里看不懂的参数自己实现一遍后全明白了那些原本靠猜的调优现在有了明确的因果链。如果你正在做AI应用又总觉得隔着一层纱我强烈建议你找个周末把这条链路从零搭一遍。搭完之后再回头看那些框架你会发现它们不再是黑盒而是一堆你熟悉的积木的封装。

相关推荐

Paperclip:Node.js与React协同的AI Agent编排协议层
Paperclip:Node.js与React协同的AI Agent编排协议层

1. “Paperclip”不是回形针:它是一套AI Agent开发范式的代号最近在几个技术社区和内部分享里,频繁看到“paperclip”这个词被当作项目代号或内部术语使用——不是指办公用品,也不是某款UI组件库,而是一个正在快速成型的、面向AI … · 2026/11/3 21:07:21

RAP Fiori开发核心:CDS+Behavior+Projection三位一体架构
RAP Fiori开发核心:CDS+Behavior+Projection三位一体架构

简介:本资源是一份面向ABAP开发者与SAP Fiori初/中级学习者的RAP(ABAP RESTful Application Programming)开发教程合集,聚焦SAP S/4HANA环境下基于ABAP的现代化Fiori应用构建。内容系统覆盖RAP核心概念、CDS视图建模、行为定义与实… · 2026/11/3 21:06:21

Visual Studio Express 2015桌面开发入门指南
Visual Studio Express 2015桌面开发入门指南

1. Visual Studio Express 2015 for Windows Desktop 中文学习版概述Visual Studio Express 2015 for Windows Desktop是微软推出的轻量级集成开发环境(IDE),专为Windows桌面应用程序开发设计。这个中文学习版特别适合刚接触C#、C等语言的开发者,提供了完… · 2026/11/3 21:06:21

模型压缩与推理加速:量化剪枝蒸馏打造高效部署流水线
模型压缩与推理加速:量化剪枝蒸馏打造高效部署流水线

模型优化这件事,圈内一直有个尴尬的局面:模型效果做得漂漂亮亮,指标刷得飞起,一上生产环境就卡成幻灯片。尤其这两年大模型、端侧模型遍地开花,模型体积和推理延迟成了绕不开的坎。我自己在推进多个模型上线项目的过程… · 2026/11/3 21:51:52

HarmonyOS实数数轴教学工具开发实践
HarmonyOS实数数轴教学工具开发实践

1. 项目背景与核心价值实数数轴定位器是一款基于HarmonyOS开发的数学教学辅助工具,主要面向中小学数学教育场景。这个应用的核心功能是将抽象的实数概念通过可视化数轴呈现,帮助学生直观理解实数在数轴上的分布规律和相对位置关系。在传统数学教学中&… · 2026/11/3 21:51:52

大模型推理加速工程:从PyTorch到vLLM/TensorRT-LLM的完整落地路径
大模型推理加速工程:从PyTorch到vLLM/TensorRT-LLM的完整落地路径

1. 项目概述:Model-Optimizer 不是工具名,而是一类工程实践的统称“Model-Optimizer”这个标题乍看像某个开源项目或商业软件的名字,但结合你提供的热搜词——NVIDIA、TensorRT-LLM、vLLM、TensorRT、PT文件转换——我立刻意识到:… · 2026/11/3 21:51:52

buzz营销实战:从内容设计到社交裂变的完整指南
buzz营销实战:从内容设计到社交裂变的完整指南

做市场、做增长的人,嘴里天天念叨的buzz,说白了就是口碑热度。这个词听起来很玄,但它不靠运气,靠的是一套可以被拆解、被设计的传播工程。我最早对buzz有体感,是在一款消费产品上市的时候。当时预算不够打传统广告&… · 2026/11/3 21:51:52

2026年BI软件选型趋势与AI问数功能实战指南
2026年BI软件选型趋势与AI问数功能实战指南

1. 2026年BI软件选型的关键趋势判断 2026年的BI市场正在经历一场由AI技术驱动的深度变革。从最近三年Gartner的魔力象限报告来看,传统BI工具与AI助手的融合速度远超预期。根据我们团队对全球Top 20 BI产品的跟踪研究,以下几个趋势已经非常明确&#xff1… · 2026/11/3 21:51:52

LLM API操作审计系统:基于Docker与eBPF的可观测性实践
LLM API操作审计系统:基于Docker与eBPF的可观测性实践

1. 项目概述:Hindsight 不是“事后诸葛亮”,而是一套可落地的 LLM 操作审计与回溯系统你有没有遇到过这样的情况:调用 OpenAI API 时突然返回401 Unauthorized: incorrect api key provided,但你明明刚复制粘贴了新密钥&#xff1… · 2026/11/3 21:50:52

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46

STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码