从零构建智能文档工厂:自动化生成API文档与多格式发布

news2026/5/11 3:00:41
1. 项目概述从“文档生成”到“智能文档工厂”在软件开发和团队协作的日常里文档工作常常被戏称为“脏活累活”。它不像写代码那样有即时的反馈和成就感但又不可或缺。无论是API接口文档、项目说明、还是内部流程手册一份清晰、准确、及时更新的文档往往是团队效率的基石也是项目质量的直接体现。然而现实情况往往是代码更新了文档还停留在上个版本接口变了文档却没人想起来同步或者不同格式的文档如Markdown、HTML、PDF需要手动维护多份费时费力且极易出错。eagleisbatman/docugen这个项目正是瞄准了这个普遍存在的痛点。从名字就能看出它的核心使命——DocumentGenerator一个文档生成器。但它绝不仅仅是一个简单的格式转换工具。在我深入研究和实践后我更愿意把它理解为一个**“智能文档工厂”**。它的设计哲学是将文档视为代码的“一等公民”通过一套可配置、可扩展、自动化的流水线将结构化的数据源如代码注释、数据库Schema、配置文件或半结构化的文本高效、一致地转化为多种格式的、可发布的文档。这个项目适合所有被文档工作困扰的开发者、技术写作者、项目经理和开源项目维护者。无论你是在维护一个庞大的微服务API体系需要自动生成Swagger/OpenAPI文档还是管理一个产品手册需要从多个Markdown文件生成统一的网站和PDF亦或是团队内部需要将会议纪要和决策记录自动归档成标准格式docugen都能提供一套优雅的解决方案。它不是一个“黑盒”魔法而是一个你可以完全掌控、根据自己团队工作流深度定制的工具集。2. 核心设计理念与架构拆解2.1 核心理念配置即代码流水线驱动docugen最吸引我的设计理念是“配置即代码”和“流水线驱动”。这意味着整个文档生成的过程从数据源读取、内容处理、模板渲染到最终输出都被抽象为一个个可配置的“步骤”并通过一个核心的配置文件通常是docugen.yml或docugen.json来串联。这种设计带来了几个显著优势版本化与可复用性配置文件可以和项目代码一起提交到Git仓库文档生成的流程因此具备了版本历史。团队新成员拉取代码后一键命令就能生成和所有人一致的文档消除了环境差异。灵活性与可扩展性流水线的每个环节都是可插拔的。如果内置的Markdown解析器不满足需求你可以很容易地替换成自己的如果需要输出一种新的格式比如ePub你只需要编写一个新的“输出器”并配置到流水线中。透明与可调试因为整个过程是声明式的你可以清晰地看到数据是如何一步步被转换的。当生成的文档不符合预期时你可以沿着流水线逐步排查是数据源的问题、模板的问题还是渲染引擎的问题。2.2 核心架构组件解析一个典型的docugen流水线通常包含以下核心组件我们可以将其类比为一个现代化的出版印刷厂数据源Source这是文档的“原材料仓库”。docugen支持多种数据源文件系统最常见的源直接读取指定目录下的Markdown、JSON、YAML等文件。代码注释通过集成JSDoc、JavaDoc、GoDoc等工具直接从源代码中提取结构化注释信息。API定义读取OpenAPI/Swagger规范文件swagger.json或openapi.yaml将其作为生成API文档的权威数据源。数据库连接数据库读取表结构Schema信息自动生成数据字典。远程数据通过HTTP API获取数据适用于需要整合多个系统信息的场景。处理器Processor这是文档的“加工车间”。原始数据进入后会经过一系列处理器的加工。常见的处理器包括Front Matter解析器识别和处理Markdown文件顶部的YAML或TOML格式的元数据如标题、作者、标签。链接解析与重写器处理文档内部的相对链接确保在最终生成的网站或PDF中链接依然有效。代码高亮器自动检测代码块的语言并应用语法高亮。自定义脚本处理器允许你注入Python、JavaScript等脚本实现更复杂的逻辑比如从外部系统获取数据并注入到文档变量中。模板引擎Template Engine这是文档的“排版设计室”。处理器加工后的数据通常是一个包含所有文档内容、元数据的上下文对象会被送入模板引擎。docugen通常支持如Jinja2、Handlebars、Nunjucks等流行的模板引擎。模板决定了文档的最终视觉结构和布局你可以为网站设计一个HTML模板为PDF设计一个LaTeX或WeasyPrint模板。输出器Writer/Exporter这是文档的“成品出厂通道”。渲染好的内容通过不同的输出器生成最终产物静态网站生成器生成一个完整的、可部署的静态网站如HTML文件。PDF生成器调用wkhtmltopdf、WeasyPrint或Puppeteer等工具将HTML渲染为高质量的PDF文档。单文件输出将所有内容合并成一个大的Markdown或HTML文件。发布器自动将生成的文档部署到GitHub Pages、Netlify、AWS S3等托管服务。注意docugen的具体实现可能是一个集成了上述所有功能的单体工具也可能是一个轻量级的“胶水”框架负责编排调用上述各个独立的成熟工具如用MkDocs做网站生成用Pandoc做格式转换。关键在于它提供了一套统一的配置抽象层。3. 实战配置从零搭建一个API文档站点理论说得再多不如动手实践。假设我们有一个Node.js后端项目使用Express框架并且我们已经用JSDoc规范编写了接口注释。现在我们的目标是自动从代码注释生成OpenAPI规范再基于此规范生成一个可交互的API文档网站并同时输出一份PDF版的技术手册。下面我将一步步拆解如何使用docugen或其理念下的工具组合来实现这个目标。3.1 环境准备与工具选型首先我们需要选择合适的工具链。纯粹的docugen可能是一个概念原型在实际生态中我们可以选用社区成熟方案组合。这里我选择数据提取swagger-jsdoc- 从JSDoc注释生成OpenAPI规范。文档生成核心Redocly或Speccy- 用于处理和增强OpenAPI规范并驱动生成流程。我们可以将其视为docugen的核心控制器。网站生成Redoc用于纯API文档或集成Docusaurus/VuePress用于混合内容。这里为了简单选用Redoc。PDF生成redoc-cli自带PDF导出功能或使用puppeteer自行渲染。项目根目录初始化后安装核心依赖npm init -y npm install --save-dev swagger-jsdoc redoc-cli3.2 编写核心配置文件docugen.config.js我们不使用YAML而用JavaScript来编写配置以获得更强的编程能力。创建docugen.config.js// docugen.config.js const swaggerJSDoc require(swagger-jsdoc); const { writeFileSync, mkdirSync } require(fs); const { execSync } require(child_process); module.exports { // 1. 定义数据源扫描源代码中的JSDoc sources: [ { type: jsdoc, options: { apis: [./src/routes/*.js, ./src/models/*.js], // 扫描的路由和模型文件 swaggerDefinition: { openapi: 3.0.0, info: { title: 我的产品API, version: 1.0.0, description: 基于Node.js和Express构建的后端服务接口文档 }, servers: [{ url: https://api.example.com/v1 }] } }, processor: (options) { // 调用swagger-jsdoc生成OpenAPI规范对象 const swaggerSpec swaggerJSDoc(options); // 可以在这里对规范进行预处理例如添加安全定义、标签排序等 if (!swaggerSpec.tags) { swaggerSpec.tags []; } return swaggerSpec; } }, { type: file, pattern: ./docs/**/*.md, // 额外的Markdown说明文档 processor: (content, filePath) { // 简单的Markdown front matter解析 const lines content.split(\n); if (lines[0] ---) { const endIndex lines.slice(1).indexOf(---) 1; const frontMatter lines.slice(1, endIndex).join(\n); const body lines.slice(endIndex 1).join(\n); // 返回结构化的数据供模板使用 return { frontMatter: require(js-yaml).load(frontMatter), body }; } return { body: content }; } } ], // 2. 定义模板和输出 outputs: [ { name: openapi-spec, type: json, template: null, // 直接输出数据源的结果 destination: ./dist/openapi.json, postProcess: (data) { // 确保生成的JSON是格式化的便于阅读和版本控制 return JSON.stringify(data, null, 2); } }, { name: api-docs-site, type: html, // 使用Redoc的Standalone HTML模板 template: ./templates/redoc-standalone.html, destination: ./dist/index.html, dataMerge: (sourcesData) { // 合并数据主要使用第一个数据源OpenAPI spec return { openapiSpec: sourcesData[0] }; } }, { name: api-docs-pdf, type: command, // 自定义命令类型输出器 command: (data) { // 先确保OpenAPI规范文件已生成 const specPath ./dist/openapi.json; writeFileSync(specPath, JSON.stringify(data.openapiSpec)); // 调用redoc-cli生成PDF try { execSync(npx redoc-cli bundle ${specPath} --output ./dist/api-docs.pdf --title API技术手册, { stdio: inherit }); } catch (error) { console.error(PDF生成失败:, error.message); // 可以在这里加入降级方案比如生成一个打印友好的HTML } }, dependsOn: [openapi-spec] // 声明依赖确保先有JSON文件 } ], // 3. 全局钩子函数 hooks: { beforeAll: () { console.log(文档生成开始...); mkdirSync(./dist, { recursive: true }); }, afterAll: () { console.log(文档生成完成输出至 ./dist 目录); } } };这个配置文件清晰地定义了一条流水线从源代码和Markdown文件中提取数据处理合并然后分别输出为OpenAPI规范JSON文件、一个独立的HTML文档站点和一份PDF手册。3.3 创建HTML模板templates/redoc-standalone.htmlRedoc提供了一个标准的Standalone HTML模板我们可以稍作定制。创建文件templates/redoc-standalone.html!DOCTYPE html html head title{{ openapiSpec.info.title }} - {{ openapiSpec.info.version }}/title meta charsetutf-8/ meta nameviewport contentwidthdevice-width, initial-scale1 link hrefhttps://fonts.googleapis.com/css?familyMontserrat:300,400,700|Roboto:300,400,700 relstylesheet style body { margin: 0; padding: 0; } /* 可以在这里添加自定义CSS覆盖Redoc的默认样式 */ .api-content { max-width: 1200px; margin: 0 auto; padding: 20px; } /style /head body !-- 可以在这里添加自定义页眉比如公司Logo和导航 -- div idcustom-header h1{{ openapiSpec.info.title }} 交互式文档/h1 p{{ openapiSpec.info.description }}/p /div !-- Redoc容器 -- div idredoc-container/div !-- 加载Redoc库并渲染 -- script srchttps://cdn.jsdelivr.net/npm/redoclatest/bundles/redoc.standalone.js/script script const spec {{ openapiSpec | safe }}; // 注意模板引擎需要能安全输出JSON Redoc.init(spec, { scrollYOffset: 50, // 固定头部时的偏移量 hideDownloadButton: false, expandResponses: 200,201, pathInMiddlePanel: true, }, document.getElementById(redoc-container)); /script !-- 可以在这里添加自定义页脚 -- div idcustom-footer p© 2023 我的公司. 文档最后生成于: span idgen-date/span/p /div scriptdocument.getElementById(gen-date).textContent new Date().toLocaleDateString();/script /body /html实操心得在模板中直接使用{{ openapiSpec | safe }}需要模板引擎支持。如果使用简单的字符串替换需要先将JSON对象序列化成字符串并转义其中的特殊字符如/script。更安全的做法是在配置文件的postProcess步骤中将数据直接注入到模板字符串的特定占位符中。3.4 编写运行脚本与集成到CI/CD最后我们创建一个简单的运行脚本scripts/generate-docs.js// scripts/generate-docs.js const config require(../docugen.config.js); const { writeFileSync } require(fs); async function generateDocs() { console.log(执行前置钩子...); if (config.hooks.beforeAll) { await config.hooks.beforeAll(); } // 1. 处理所有数据源 console.log(正在从数据源收集信息...); const sourcesData []; for (const source of config.sources) { let data; if (source.type jsdoc source.processor) { data await source.processor(source.options); } else if (source.type file) { // 简化处理实际需要递归读取文件 const fs require(fs).promises; const glob require(glob); // 需要安装glob const files glob.sync(source.pattern); const fileData []; for (const file of files) { const content await fs.readFile(file, utf-8); if (source.processor) { fileData.push(await source.processor(content, file)); } else { fileData.push(content); } } data fileData; } sourcesData.push(data); } // 2. 执行所有输出任务 console.log(正在生成输出产物...); for (const output of config.outputs) { // 处理依赖关系简化版 if (output.dependsOn) { // 在实际项目中这里需要实现一个简单的任务依赖图调度 console.log(输出任务【${output.name}】等待依赖项: ${output.dependsOn}); } let outputData; if (output.dataMerge) { outputData output.dataMerge(sourcesData); } else { // 默认使用第一个数据源 outputData sourcesData[0]; } if (output.type json) { let content outputData; if (output.postProcess) { content await output.postProcess(content); } writeFileSync(output.destination, content); console.log(✅ 已生成: ${output.destination}); } else if (output.type html output.template) { // 简化版模板渲染实际应使用如EJS、Handlebars等引擎 const template require(fs).readFileSync(output.template, utf-8); // 这是一个非常简单的替换仅用于演示。生产环境务必使用正规模板引擎。 let rendered template.replace({{ openapiSpec | safe }}, JSON.stringify(outputData.openapiSpec)); writeFileSync(output.destination, rendered); console.log(✅ 已生成: ${output.destination}); } else if (output.type command output.command) { await output.command(outputData); console.log(✅ 已执行命令生成: ${output.name}); } } // 3. 执行后置钩子 if (config.hooks.afterAll) { await config.hooks.afterAll(); } } // 错误处理 generateDocs().catch(err { console.error(文档生成过程出错:, err); process.exit(1); });然后在package.json中添加脚本命令{ scripts: { docs:generate: node scripts/generate-docs.js, docs:serve: serve ./dist, // 使用serve包本地预览 docs:deploy: npm run docs:generate ./deploy-to-gh-pages.sh // 假设有部署脚本 } }现在运行npm run docs:generate你就会在./dist目录下得到openapi.json、index.html和api-docs.pdf三个文件。4. 高级技巧与定制化扩展基础的流水线搭建完成后我们可以探索一些高级用法让文档生成更智能、更贴合团队需求。4.1 多环境配置与变量注入文档中经常需要根据生成环境开发、测试、生产动态变化的内容比如API服务器的地址。我们可以在配置中引入环境变量// 在docugen.config.js中 const environment process.env.DOCS_ENV || development; const serverUrls { development: http://localhost:3000, staging: https://staging-api.example.com, production: https://api.example.com }; module.exports { sources: [{ type: jsdoc, options: { swaggerDefinition: { // ... 其他配置 servers: [{ url: serverUrls[environment] }] } } }], // ... 其他配置 };运行命令时指定环境DOCS_ENVproduction npm run docs:generate。4.2 集成测试与文档健康度检查生成的文档是否正确能否真实反映API状态我们可以将文档生成与API测试集成。使用swagger-test或Dredd这些工具可以根据OpenAPI规范自动生成测试用例并对真实的API端点进行测试确保文档与实现一致。在流水线中添加“校验”阶段在outputs之前新增一个validators阶段。validators: [ { name: openapi-spec-validator, validator: (spec) { const SwaggerParser require(apidevtools/swagger-parser); return SwaggerParser.validate(spec).then(() { console.log(✅ OpenAPI 规范验证通过); }).catch(err { throw new Error(OpenAPI 规范验证失败: ${err.message}); }); } } ]在generateDocs函数中在执行输出前先运行所有校验器。4.3 自定义处理器从外部系统拉取数据假设我们的API使用了第三方身份验证服务我们希望在文档中动态展示该服务的状态或配置示例。可以创建一个自定义处理器// processors/external-auth-info.js const axios require(axios); module.exports async function fetchAuthInfo() { try { // 从内部配置管理系统或第三方API获取信息 const response await axios.get(https://internal-config-api.example.com/auth-providers); return response.data.find(p p.name Okta); // 示例获取Okta配置 } catch (error) { console.warn(无法获取外部认证信息使用默认值); return { clientId: YOUR_CLIENT_ID, issuer: https://your-org.okta.com }; } }; // 在配置中引用 const fetchAuthInfo require(./processors/external-auth-info); // ... 在某个数据源或输出模板的上下文中注入该数据然后在模板中就可以使用{{ externalAuthInfo.clientId }}这样的变量了。5. 常见问题与排查技巧实录在实际使用和推广docugen这类工具的过程中我踩过不少坑也总结了一些排查问题的经验。5.1 问题生成的OpenAPI规范不全或字段错误可能原因1JSDoc注释格式不正确。swagger-jsdoc对注释格式有严格要求。排查检查源代码中的swagger或openapi注释块是否完整闭合参数定义param的数据类型是否正确如{string}{number}。技巧先在一个独立的.js文件中写一个最简单的接口注释进行测试确保swagger-jsdoc能正确解析再对比项目中的复杂注释。可能原因2扫描路径配置错误。排查检查apis配置项中的Glob模式是否正确匹配到了你的路由文件。可以使用console.log在processor函数中打印出swaggerJSDoc(options)生成的原始对象查看是否包含了预期的路径paths。可能原因3OpenAPI 3.0与2.0Swagger语法混淆。排查确认swaggerDefinition中openapi: 3.0.0的版本号。3.0和2.0的语法有较大差异例如参数定义位置in: queryvsin: query虽然一样但schema结构不同、请求体定义等。5.2 问题模板渲染失败或输出乱码可能原因1模板引擎语法错误或上下文数据缺失。排查如果使用如Nunjucks或EJS确保模板文件语法正确。在渲染前将传递给模板的数据上下文console.log出来检查是否包含模板中引用的所有变量如openapiSpec,externalAuthInfo。技巧在模板中先使用{{ JSON.stringify(context, null, 2) }}输出整个上下文对象检查数据结构。可能原因2字符编码问题。排查确保模板文件、源代码文件、配置文件的编码都是UTF-8。在Windows环境下尤其要注意。在读取文件时显式指定编码utf8。技巧在项目的根目录添加.editorconfig文件统一规定文件编码和换行符。5.3 问题PDF生成质量差或排版错乱可能原因1CSS样式在打印/PDF渲染时不兼容。排查用于生成PDF的HTML页面其CSS必须考虑打印样式。很多用于屏幕显示的CSS属性如position: fixed在PDF中可能表现异常。技巧为PDF生成专门编写或引入一套打印样式表link relstylesheet mediaprint hrefprint.css。使用page规则控制页面边距、页眉页脚。可能原因2PDF生成工具如wkhtmltopdf版本或依赖问题。排查这是最常见的问题。不同版本、不同操作系统下的wkhtmltopdf行为可能不一致。技巧锁定版本在Docker容器或CI环境中使用特定版本的wkhtmltopdf。考虑替代方案如果问题难以解决可以评估切换到WeasyPrint对CSS支持更好或Puppeteer无头Chrome渲染一致性高。redoc-cli的PDF功能底层也是基于Puppeteer通常更稳定。生成中间HTML调试先命令工具输出用于生成PDF的HTML文件在浏览器中打开这个HTML文件检查其样式和布局是否正确。如果HTML正确但PDF错误问题基本可以定位在PDF转换工具上。5.4 问题文档生成流程在CI/CD中太慢可能原因每次构建都从头开始安装所有依赖Node modules, Python包等并执行完整的文档生成流程。优化技巧缓存依赖在CI配置如GitHub Actions的actions/cache GitLab CI的cache中缓存node_modules、pip包目录等。增量生成如果文档源文件Markdown没有变化可以跳过生成步骤。可以通过比较Git哈希或文件时间戳来实现。对于从代码注释生成的部分由于代码常变增量意义不大但可以缓存生成的中间产物如openapi.json。并行化如果流水线中有多个独立的任务如生成网站、生成PDF、运行文档测试可以在CI中配置并行作业。使用更轻量的工具链评估是否所有工具都是必需的。有时一个简单的markdown-to-html转换器比一个全功能的静态网站生成器要快得多。5.5 问题团队不愿意写注释或维护文档这不是技术问题而是流程和文化问题。技术工具只能降低维护成本不能创造动力。解决思路将文档作为合并请求PR的门禁在Git钩子或CI流水线中集成检查如果修改了某个API的代码但没有更新对应的JSDoc注释或OpenAPI描述则构建失败或给出强烈警告。让文档“活”起来将生成的交互式API文档如Redoc或Swagger UI集成到开发环境、测试环境甚至生产环境的入口让开发者和测试人员每天都能看到和使用它。当他们发现文档过时导致沟通成本增加时自然有动力去更新。降低编写门槛提供注释模板或代码片段Snippet让开发者能快速生成符合规范的注释框架。将文档质量纳入代码评审Code Review的考量范围。通过将docugen这样的自动化文档生成理念和工具深度集成到开发工作流中我们最终的目标是让高质量的文档成为开发过程的自然副产品而不是一个额外的、令人厌烦的负担。它从一项任务转变为一个可靠的基础设施。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2602260.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…