基于Next.js与LangChain构建私有知识库智能问答系统

news2026/5/6 13:07:24
1. 项目概述构建一个能与你的文档对话的智能应用最近在折腾一个挺有意思的项目叫“Chat your Data”。简单来说这就是一个能让你用自己的文档、书籍、笔记来“喂养”一个AI助手然后像聊天一样向它提问的应用。比如你有一本几百页的技术手册或者一堆内部项目文档不想一页页去翻就可以把这个应用部署起来让它帮你快速找到答案。这个项目的技术栈很现代用到了 Next.js、React、TypeScript核心的AI能力则基于 OpenAI 的 API 和 LangChain 这个强大的框架。我之所以花时间研究它是因为在实际工作中处理非结构化文档的痛点太明显了。无论是查找某个特定功能的实现细节还是快速理解一份新接触的代码库传统的搜索CtrlF在语义理解上总是差点意思。而这个项目通过将文档内容转化为向量嵌入Embeddings并利用大语言模型LLM进行语义检索和生成实现了真正意义上的“理解式问答”。它不是一个通用的聊天机器人而是一个专属于你私有知识库的专家。接下来我会从零开始带你完整地走一遍这个项目的搭建、数据准备、核心原理剖析以及实际部署的全过程。无论你是前端开发者想了解如何集成AI能力还是对RAG检索增强生成应用开发感兴趣这篇文章都会提供足够落地的细节和我踩过的一些坑。2. 技术栈深度解析与选型考量2.1 为什么是 Next.js React TypeScript这个组合几乎是当前构建现代化、全栈Web应用的事实标准。Next.js 提供了开箱即用的服务端渲染SSR、静态生成SSG以及简洁的API路由pages/api或app/api支持这对于我们这个需要前后端紧密交互的应用来说非常合适。AI问答通常涉及较长的处理时间Next.js的API路由可以很好地处理这些后端异步任务同时其前端框架又能提供流畅的用户交互体验。React 作为UI库的选择毋庸置疑其组件化思想非常适合构建复杂的聊天界面。TypeScript 的加入则是项目稳健性的关键。在与LangChain、OpenAI SDK这类第三方库打交道时类型提示能极大减少因参数错误导致的运行时问题尤其是在处理复杂的链Chain和提示词Prompt模板时TypeScript能帮你提前发现许多潜在的类型不匹配错误。注意原项目使用的是pages路由结构。如果你从零开始可以考虑使用Next.js 13的appRouter基于React Server Components它能提供更精细的渲染控制和更好的性能。但需要注意一些服务端相关的包如fs文件系统操作在appRouter中的使用方式略有不同。2.2 LangChain连接数据与AI的“胶水”LangChain是这个项目的灵魂。它不是一个AI模型而是一个用于开发由语言模型驱动的应用程序的框架。你可以把它想象成一套乐高积木它提供了各种标准化的“连接件”如文档加载器、文本分割器、向量存储接口、链让你能轻松地将文档处理、向量检索、提示工程和模型调用这几个环节串联起来。在这个项目中LangChain主要承担了以下核心职责文档加载与处理从本地文件如Markdown、PDF加载文本。文本分割将长文档切割成语义上相对完整的小块Chunks。这是关键一步块的大小和重叠度直接影响检索质量。通常我们会选择500-1000个字符的块并设置10%左右的重叠以确保上下文信息不会在切割时丢失。向量化与存储使用OpenAI的嵌入模型如text-embedding-ada-002将文本块转换为高维向量即嵌入然后存储到向量数据库Vector Store中。本项目使用的是hnswlib-node这是一个轻量级、纯JavaScript的向量搜索库非常适合在单机或Serverless环境如Vercel中运行因为它不需要额外的数据库服务。检索与生成链当用户提问时LangChain会从向量库中检索出与问题最相关的几个文本块然后将这些块和原始问题一起组装成一个详细的提示词Prompt发送给GPT模型如gpt-3.5-turbo或gpt-4来生成最终答案。这个过程就是RAGRetrieval-Augmented Generation检索增强生成。实操心得原项目README中提到需要锁定langchain版本为0.0.22这是因为LangChain早期版本迭代非常快API变动剧烈。现在截至2024年LangChain已相对稳定。建议使用较新的稳定版本如0.1.x但务必仔细阅读其迁移指南因为一些导入路径和函数名可能已经改变。直接使用最新版可能会遇到兼容性问题。2.3 OpenAI API模型能力的源泉项目的智能核心依赖于OpenAI的API主要用到两个服务Embeddings API用于将文本转换为向量。通常选用text-embedding-ada-002它在效果、速度和成本之间取得了很好的平衡。Chat Completions API用于生成最终答案。可以根据对回答质量和成本的要求在gpt-3.5-turbo和gpt-4系列之间选择。成本考量这是自建此类应用必须关注的一点。Embedding按token收费Chat Completion也按token收费。如果你的文档库很大例如超过100万字初次生成向量嵌入的成本可能较高但这是一次性投入。后续每次问答成本主要来自Chat Completion和少量检索时的Embedding计算对问题进行向量化。在项目初期建议先用小规模数据测试整个流程。3. 从零开始环境搭建与项目初始化3.1 前置条件与工具准备在开始之前请确保你的开发环境满足以下要求Node.js版本建议在18.x或以上。你可以使用nvm(Node Version Manager) 来管理多个Node版本。包管理器项目使用yarn你也可以使用npm或pnpm但需要相应调整命令。OpenAI账户你需要注册OpenAI平台并获取API密钥。准备好一定的额度。首先将项目克隆到本地git clone 原项目仓库地址 cd chat-your-data注意由于原项目已归档Archived你可以将其作为模板或者手动创建一个新的Next.js项目来跟随本文实践这样能避免依赖版本过旧的问题。3.2 依赖安装与关键配置进入项目目录后安装所有依赖yarn install # 或使用 npm install接下来是最关键的一步配置环境变量。项目根目录下应该有一个.env.example文件将其复制为.envcp .env.example .env然后用你喜欢的编辑器打开.env文件。它的核心内容通常如下OPENAI_API_KEYsk-your-secret-key-here将sk-your-secret-key-here替换为你从OpenAI平台获取的真实API密钥。安全警告.env文件包含了你的敏感密钥绝对不要将其提交到Git仓库中。确保.env已经在.gitignore文件中。在部署到Vercel等平台时需要通过平台的环境变量配置界面来设置OPENAI_API_KEY。3.3 解决依赖版本冲突避坑重点正如原项目提示LangChain版本是最大的坑点。对于归档项目直接安装可能会失败。我建议的做法是删除现有的node_modules文件夹和yarn.lock/package-lock.json文件。打开package.json将langchain的依赖版本手动修改为一个较新且稳定的版本例如^0.1.0。同时检查其他相关依赖如langchain/community如果新版本需要的版本。重新运行yarn install。如果遇到hnswlib-node编译失败特别是在Windows或某些Linux环境下这通常是由于本地缺少C编译工具链。解决方案Windows安装windows-build-tools(以管理员身份运行npm install --global windows-build-tools) 或使用Visual Studio Build Tools。macOS确保安装了Xcode Command Line Tools (xcode-select --install)。Linux安装build-essential等基础编译包。如果问题依旧可以考虑在package.json中暂时将hnswlib-node替换为纯JavaScript实现的向量库比如pinecone-database/pinecone需要连接网络服务或vectra本地但这需要修改后端的向量存储代码。4. 核心环节一数据准备与向量化Ingestion Pipeline这是让应用“认识”你的数据的关键步骤也是最消耗计算资源和时间的一步。4.1 数据源准备与格式化项目默认期望的数据源是Markdown.md文件。为什么是Markdown因为它的结构相对清晰标题、列表、代码块便于LangChain的文本分割器进行有意义的切割保留一定的格式信息。实操步骤获取你的文档这可以是任何文本文件——PDF、Word、TXT、网页文章。你需要先将它们转换为纯文本或Markdown格式。PDF可以使用pdf-parse或pdfjs-dist库在Node.js中解析或者使用在线的转换工具。网页可以使用cheerio或puppeteer进行抓取和内容提取。Word可以使用mammoth库。格式清理转换后的文本往往包含多余的空格、换行符、页眉页脚等。编写简单的脚本或使用正则表达式进行清洗确保核心内容连贯。保存为MD文件将清洗后的内容保存为.md文件并放置在你项目的某个目录下例如docs/。4.2 剖析数据摄取脚本ingest.ts原项目的ingest.ts脚本是数据管道的核心。我们来拆解它通常包含的逻辑你需要根据新版本LangChain的API进行调整// ingest.ts - 概念性代码展示流程 import { DirectoryLoader } from langchain/document_loaders/fs/directory; import { TextLoader } from langchain/document_loaders/fs/text; import { RecursiveCharacterTextSplitter } from langchain/text_splitter; import { OpenAIEmbeddings } from langchain/embeddings/openai; import { HNSWLib } from langchain/vectorstores/hnswlib; import * as fs from fs/promises; import path from path; async function main() { // 1. 指定你的数据文件路径 const filePath path.join(__dirname, docs, my_data.md); // 2. 加载文档这里以单个文件为例 const loader new TextLoader(filePath); const rawDocs await loader.load(); // 3. 分割文本 const textSplitter new RecursiveCharacterTextSplitter({ chunkSize: 1000, // 每个块的最大字符数 chunkOverlap: 200, // 块之间的重叠字符数 }); const docs await textSplitter.splitDocuments(rawDocs); console.log(已将文档分割成 ${docs.length} 个块。); // 4. 创建向量存储 const embeddings new OpenAIEmbeddings({ openAIApiKey: process.env.OPENAI_API_KEY, }); // 5. 从文档生成向量并存储 const vectorStore await HNSWLib.fromDocuments(docs, embeddings); // 6. 将向量存储保存到磁盘 const savePath path.join(__dirname, data); await vectorStore.save(savePath); console.log(向量数据已保存至: ${savePath}); } main().catch(console.error);关键参数解析chunkSize: 1000这是平衡检索精度和上下文长度的关键。太小可能丢失完整语义太大可能会在提示词中引入过多无关信息影响模型专注度也增加token消耗。对于技术文档800-1500是个不错的起点。chunkOverlap: 200重叠是为了避免一个完整的句子或概念被硬生生切断。重叠部分确保了上下文在不同块之间的连续性。4.3 运行摄取脚本并验证在修改好ingest.ts中的文件路径后运行yarn ingest # 或 npx tsx ingest.ts 如果你使用tsx这个过程可能会花费几分钟到几十分钟取决于你的文档大小和网络速度因为要调用OpenAI的Embedding接口。完成后你应该在项目根目录下看到一个新生成的data/文件夹里面包含了序列化后的向量索引文件如hnswlib.index,docstore.json等。重要检查点务必确认data/文件夹已成功生成且非空。Next.js服务端代码将直接从这个目录加载向量库。如果此步骤失败后续的聊天功能将无法工作。5. 核心环节二问答后端API实现解析当用户在前端界面提出问题时请求会被发送到Next.js的一个API路由例如pages/api/chat.ts。这个后端接口是整个智能问答的中枢。5.1 API路由的工作流程一个典型的实现流程如下接收用户输入从HTTP POST请求的body中获取用户的问题question和可选的聊天历史history。加载向量存储从本地data/目录加载之前生成的HNSWLib向量存储实例。检索相关文档使用向量存储的similaritySearch方法将用户问题转换为向量并在库中查找最相似的几个文本块例如前4个最相关的结果。这就是语义检索的核心。构建提示词Prompt这是决定回答质量的关键。一个典型的RAG提示词模板如下你是一个乐于助人的助手。请严格根据以下提供的上下文信息来回答问题。如果上下文信息中没有明确包含答案请直接说“根据我现有的资料无法回答这个问题”不要编造信息。 上下文信息 {context} 问题{question} 请根据上下文提供答案其中{context}会被替换为检索到的多个文本块拼接起来的内容{question}就是用户的问题。调用语言模型将组装好的提示词、聊天历史如果需要多轮对话发送给OpenAI的Chat Completion API使用ChatOpenAI类。流式传输响应为了获得更好的用户体验通常采用Server-Sent Events (SSE) 或类似技术将模型生成答案的token流式地传回前端实现打字机效果。原项目使用了microsoft/fetch-event-source来处理这个流。5.2 关键代码片段与优化点// pages/api/chat.ts - 概念性代码 import { HNSWLib } from langchain/vectorstores/hnswlib; import { OpenAIEmbeddings } from langchain/embeddings/openai; import { ChatOpenAI } from langchain/chat_models/openai; import { RetrievalQAChain } from langchain/chains; import { PromptTemplate } from langchain/prompts; export default async function handler(req, res) { if (req.method ! POST) { return res.status(405).json({ error: Method not allowed }); } const { question, history } req.body; try { // 1. 加载向量库 const embeddings new OpenAIEmbeddings(); const vectorStore await HNSWLib.load(data, embeddings); // 2. 创建检索器 const retriever vectorStore.asRetriever({ k: 4, // 返回最相关的4个文档块 }); // 3. 定义提示词模板 const promptTemplate PromptTemplate.fromTemplate( 你是一个专业的文档助手。请仅根据以下上下文信息回答问题。如果答案不在上下文中请礼貌地告知你无法根据现有信息回答。 上下文 {context} 问题{question} 基于上下文的回答); // 4. 初始化模型 const model new ChatOpenAI({ temperature: 0.2, // 较低的温度值使输出更确定、更专注于上下文 streaming: true, // 启用流式输出 callbacks: [ { handleLLMNewToken(token: string) { // 这里将每个新token通过SSE发送给前端 res.write(data: ${JSON.stringify({ token })}\n\n); }, }, ], }); // 5. 创建检索问答链 const chain RetrievalQAChain.fromLLM(model, retriever, { prompt: promptTemplate, returnSourceDocuments: true, // 可选返回检索到的源文档用于前端显示引用来源 }); // 设置SSE响应头 res.writeHead(200, { Content-Type: text/event-stream, Cache-Control: no-cache, Connection: keep-alive, }); // 6. 调用链 const response await chain.call({ query: question, chat_history: history || [], }); // 流式传输结束 res.write(data: [DONE]\n\n); res.end(); } catch (error) { console.error(Chat API error:, error); res.status(500).json({ error: Internal server error }); } }优化与注意事项温度Temperature设置为较低值如0.1-0.3可以让模型的回答更忠实于检索到的上下文减少“胡言乱语”。引用来源returnSourceDocuments: true是一个非常好的实践。它允许你将检索到的原始文本块返回给前端这样用户就能看到答案具体来源于哪些文档增加了可信度。前端可以将其渲染为可折叠的引用或脚注。错误处理务必用try-catch包裹核心逻辑并给前端返回清晰的错误信息避免服务直接崩溃。超时设置对于大型文档或复杂问题模型生成可能需要较长时间。在Vercel等Serverless环境中需要注意函数执行超时限制默认10秒。对于长文本可能需要优化检索数量或使用更快但能力稍弱的模型。6. 核心环节三前端交互界面构建前端的目标是提供一个直观、流畅的聊天界面。原项目借鉴了langchain-chat-nextjs的UI这是一个很好的起点。6.1 核心组件与状态管理主要组件通常包括ChatWindow主聊天区域包含消息列表和输入框。Message单条消息的展示组件区分用户消息和AI消息。InputArea包含文本输入框和发送按钮处理用户输入。状态管理可以使用React的useState和useRef来管理消息列表、加载状态等。对于流式响应需要将后端SSE推送过来的token逐个追加到当前AI回复的消息内容中。6.2 实现流式响应接收这是前端体验的关键。使用EventSource或fetch-event-source库来建立与后端/api/chat的SSE连接并实时处理数据流。// 前端处理流式响应的示例片段 import { fetchEventSource } from microsoft/fetch-event-source; const handleSendMessage async (userInput: string) { // 将用户消息添加到UI setMessages(prev [...prev, { type: user, content: userInput }]); // 添加一个空的AI消息占位符 setMessages(prev [...prev, { type: ai, content: }]); setIsLoading(true); await fetchEventSource(/api/chat, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ question: userInput, history: [] }), onopen(res) { if (res.ok res.status 200) { console.log(Connection made); } else { console.log(Client error, res); } }, onmessage(event) { // 接收到后端推送的每一个token if (event.data [DONE]) { // 流结束 setIsLoading(false); return; } const parsedData JSON.parse(event.data); const token parsedData.token; // 将token追加到最后一条AI消息的内容中 setMessages(prev { const newMessages [...prev]; const lastMessage newMessages[newMessages.length - 1]; lastMessage.content token; return newMessages; }); }, onerror(err) { // 处理错误 setIsLoading(false); setError(对话出错请重试。); }, }); };6.3 UI/UX优化建议引用高亮如果后端返回了sourceDocuments可以在AI消息下方以较小字体、不同背景色展示引用的原文片段并支持点击展开/折叠。这极大地提升了答案的可验证性。停止生成按钮在流式生成过程中提供一个“停止”按钮允许用户中断冗长的回答。消息持久化使用localStorage或IndexedDB在浏览器端临时保存聊天记录避免页面刷新后历史丢失。Markdown渲染AI的回答很可能包含代码块、列表等Markdown格式。使用react-markdown和remark-gfm来漂亮地渲染这些内容提升可读性。7. 部署上线与生产环境考量7.1 部署到Vercel推荐这是最快捷的部署方式因为Next.js和Vercel是“一家人”。将你的代码推送到GitHub、GitLab或Bitbucket仓库。在Vercel官网导入你的仓库。在Vercel项目的环境变量设置中添加OPENAI_API_KEY。关键步骤Vercel在构建时Build Time会运行yarn build但我们的data/文件夹是在构建后通过运行yarn ingest生成的且依赖OpenAI API。Vercel的构建环境无法也不应该在构建时调用外部API并生成大文件。解决方案A推荐将data/文件夹视为构建产物的一部分。在本地运行yarn ingest生成data/文件夹然后将其一并提交到Git仓库。这样Vercel在构建时就能直接使用它。缺点是向量数据文件可能较大会增加仓库体积。解决方案B使用Vercel的Serverless Function在应用启动时或首次请求时动态生成/加载向量库。但这可能触发冷启动延迟且需要将文档文件放在云端存储如AWS S3并在函数中下载处理复杂度较高。7.2 生产环境优化与安全API密钥安全永远不要在前端代码或客户端暴露OPENAI_API_KEY。所有对OpenAI的调用必须通过你自己的后端即Next.js的API路由进行代理。速率限制与缓存在API路由中实施速率限制例如使用rate-limiter-flexible防止滥用。对于常见问题可以考虑在内存或Redis中缓存答案减少对OpenAI API的调用和成本。错误与超时处理完善后端的错误处理给前端返回友好的错误信息。对于长时间运行的任务考虑使用异步任务队列如BullMQ并通过WebSocket或轮询通知前端结果。向量存储的替代方案hnswlib-node将数据存储在本地文件系统这在Serverless环境中如Vercel是只读的且每次冷启动都需要重新加载可能较慢。对于生产环境考虑使用云端的向量数据库服务如Pinecone、Weaviate、Qdrant或Milvus。它们提供持久化存储和更快的检索速度但会引入额外的成本和外部依赖。8. 常见问题排查与进阶技巧8.1 问题速查表问题现象可能原因解决方案运行yarn ingest失败提示Module not found或 API 错误1. 依赖版本不兼容。2..env文件未配置或API密钥无效。3. OpenAI API额度不足或网络问题。1. 检查并统一依赖版本特别是langchain相关包。2. 确认.env文件在根目录且密钥正确无误。3. 检查OpenAI账户余额和网络连接。前端聊天界面显示“无法连接到服务器”或500错误1. 后端API路由 (/api/chat) 有未处理的异常。2.data/文件夹缺失或路径错误。3. Serverless函数超时Vercel默认10秒。1. 查看Vercel函数日志或本地终端错误信息。2. 确认已成功运行yarn ingest并生成了data/文件夹。3. 对于复杂问题尝试简化提示词、减少检索的文档数量 (k值)或升级到Vercel的Pro计划以获得更长超时时间。AI的回答与文档内容无关或开始“胡编乱造”1. 检索到的文档块 (k值) 不相关或质量差。2. 提示词 (Prompt) 没有强制模型基于上下文回答。3. 模型温度 (temperature) 设置过高。1. 调整文本分割的chunkSize和chunkOverlap优化文档预处理质量。2. 强化提示词例如明确写上“如果上下文未提供相关信息请回答‘我不知道’”。3. 将temperature调低至0.1-0.3。回答速度很慢1. 文档块太多检索耗时。2. OpenAI API响应慢。3. 网络延迟。1. 优化k值如从5减到3或使用更高效的向量索引。2. 考虑使用gpt-3.5-turbo替代gpt-4速度更快成本更低。3. 部署服务的地理位置尽量靠近你的用户。部署到Vercel后应用无法找到data/目录data/目录未包含在构建产物中或路径引用不对。确保data/目录被提交到了Git仓库并且在代码中使用path.join(process.cwd(), data)这样的绝对路径来引用。检查Vercel的构建日志确认data文件夹是否存在。8.2 进阶技巧与扩展思路多文档源与混合检索不止是Markdown可以集成多种加载器PDF、网页、Notion、Confluence。甚至可以结合关键词检索如BM25和向量检索进行混合搜索提升召回率。对话历史管理实现真正的多轮对话。将之前的问答对作为上下文传递给模型可以让AI更好地理解指代关系如“它”、“上面提到的”。但要注意token数量限制可能需要一个智能的“历史总结”机制。元数据过滤在向量化时为每个文档块添加元数据如来源文件名、章节标题、创建日期。在检索时可以允许用户通过前端UI筛选特定来源的文档使问答更精准。评估与迭代构建一个简单的评估流程。准备一批“问题-标准答案”对定期运行测试查看问答的准确率Accuracy和相关性Relevance。根据结果调整文本分割策略、检索参数和提示词模板。前端优化实现消息的本地存储、对话重命名、导出/导入聊天记录等功能提升产品化体验。这个项目是一个绝佳的起点它清晰地展示了RAG应用的核心闭环。在实际使用中你会发现提示词工程、数据清洗和向量检索策略的调优是提升应用效果最耗精力但也最有价值的部分。每个不同的知识库都有其特点需要你不断地实验和调整。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2588316.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;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…