LangChain.js:模块化AI应用开发框架,从原理到实战构建智能体

news2026/5/13 5:17:48
1. 项目概述LangChain.js一个面向未来的AI应用构建框架如果你正在用JavaScript或TypeScript捣鼓大语言模型LLM应用大概率已经听过LangChain这个名字。它不是一个具体的AI模型而是一个框架一个工具箱一个帮你把各种AI能力像乐高积木一样拼装起来的“胶水”。简单来说LangChain.js 让你能更轻松、更结构化地开发出能理解、生成、推理和行动的智能应用。为什么需要它想象一下你想做一个能回答你公司内部文档问题的聊天机器人。你需要1把文档变成AI能理解的格式向量化2找个地方存这些向量向量数据库3选择一个LLM比如GPT-4、Claude或开源模型4设计一个流程用户提问 - 从文档库找相关片段 - 组合成提示词 - 发给LLM - 返回答案。如果没有框架你得自己写代码处理每一步的连接、错误、格式转换代码会很快变得臃肿且难以维护。LangChain.js 的价值就在于它为你标准化了这些步骤提供了预构建的模块它称之为“组件”让你能专注于业务逻辑而不是底层管道。它的核心定位是“智能体工程平台”。“智能体”在这里指的是能感知环境、做出决策并执行动作的AI程序。LangChain.js 提供了一套完整的抽象来定义这些智能体的思考逻辑、工具使用、记忆能力和执行流程。无论是简单的问答链还是复杂的、能调用API和数据库的多步骤推理智能体你都能在这个框架下找到高效的实现路径。2. 核心设计哲学与架构解析2.1 模块化与“链”式思维LangChain.js 最根本的设计思想是“模块化”和“链式组合”。它将构建LLM应用所需的各种能力抽象成独立的、可互换的组件。主要组件包括模型 I/O (Model I/O)这是与LLM对话的接口。包括提示词模板PromptTemplate、语言模型本身ChatOpenAI,ChatAnthropic等和输出解析器OutputParser。它确保了输入输出的标准化。检索 (Retrieval)处理如何从外部知识源如文档、数据库中获取相关信息。核心是Retriever接口它与向量存储VectorStore协同工作。智能体 (Agents)这是LangChain的“大脑”。一个智能体由三部分组成一个LLM、一系列它可用的工具Tools如搜索、计算器、API调用以及一个决定如何调用这些工具的推理逻辑AgentExecutor。记忆 (Memory)让对话或交互拥有上下文。从简单的对话缓冲区ConversationBufferMemory到更复杂的、能总结关键点的记忆类型ConversationSummaryMemory它让应用能进行多轮有状态的对话。链 (Chains)这是将上述组件组合成工作流的核心概念。一个链可以非常简单如LLMChain提示词 模型也可以非常复杂包含条件逻辑、多个检索步骤等。SequentialChain允许你按顺序执行多个链。这种设计的优势在于解耦和可复用性。你可以像搭积木一样用不同的模型、不同的检索器、不同的记忆模块快速组装出功能迥异的应用。当某个组件比如底层的LLM API发生变化时你通常只需要更换那个组件而不必重写整个应用逻辑。2.2 面向生产与生态协同LangChain.js 不是一个孤立的库它是一个庞大生态的入口。其设计紧密围绕生产就绪性展开TypeScript 原生整个库用TypeScript编写提供了极佳的代码提示和类型安全这在构建复杂AI应用时能极大减少运行时错误。环境普适性它不仅仅用于Node.js后端。通过精心的打包和适配它可以运行在浏览器、Cloudflare Workers、Vercel Edge Functions、Deno、Bun等几乎任何现代JavaScript运行时中。这意味着你可以用同一套逻辑开发全栈AI应用。与LangSmith深度集成这是LangChain团队提供的官方监控与调试平台。你可以将应用的每次LLM调用、工具执行、中间结果无缝地记录到LangSmith。当应用回答出错时你能清晰地看到是提示词的问题、检索结果不准还是模型本身“胡言乱语”从而进行精准优化。对于生产部署这是不可或缺的“黑匣子”和“调试器”。与LangGraph.js 分工明确对于简单的线性链LangChain.js 本身足够。但对于需要复杂循环、状态管理、分支判断的智能体工作流比如一个需要反复查阅资料、自我验证的推理智能体官方推荐使用LangGraph.js。你可以把LangGraph理解为LangChain的“工作流引擎”扩展它用图Graph的概念来定义智能体的执行路径支持循环、并行、人工干预等高级模式适合构建企业级可靠智能体。3. 从零开始环境搭建与第一个链理论说了不少我们直接上手看看如何用LangChain.js快速构建一个应用。这里假设你已有Node.js环境版本18。3.1 项目初始化与安装首先创建一个新目录并初始化项目mkdir my-langchain-app cd my-langchain-app npm init -y接下来安装LangChain.js核心库以及我们示例中需要用的OpenAI模型包和环境变量管理工具npm install langchain langchain/openai dotenv注意从LangChain.js v0.1.0开始官方采用了“命名空间包”的模式。核心框架是langchain而各个模型提供商和集成的功能被拆分为独立的包如langchain/openai、langchain/anthropic、langchain/community等。这样做的好处是依赖更清晰打包体积更小。务必查阅官方文档确认你需要的具体包名。创建一个.env文件来安全地存储你的API密钥如果你使用OpenAIOPENAI_API_KEY你的_openai_api_key_在这里3.2 构建一个简单的问答链让我们创建一个最简单的链接收用户输入让LLM生成一首关于该主题的俳句诗。创建一个文件simple_chain.jsimport { ChatOpenAI } from langchain/openai; import { PromptTemplate } from langchain/core/prompts; import { LLMChain } from langchain/chains; import * as dotenv from dotenv; // 加载环境变量 dotenv.config(); // 1. 初始化模型 // 这里我们使用gpt-3.5-turbo性价比高。temperature控制创造性越高答案越随机。 const model new ChatOpenAI({ modelName: gpt-3.5-turbo, temperature: 0.7, openAIApiKey: process.env.OPENAI_API_KEY, }); // 2. 创建提示词模板 // {topic} 是一个占位符我们稍后会动态填入 const prompt PromptTemplate.fromTemplate( 你是一位诗人。请以“{topic}”为主题创作一首俳句。俳句应遵循五-七-五的音节结构并体现季节感。 ); // 3. 将模型和提示词组合成链 const chain new LLMChain({ llm: model, prompt }); // 4. 运行链 async function run() { try { // 调用链并传入参数对象对应提示词模板中的占位符 const result await chain.call({ topic: 秋夜 }); console.log(result.text); // 输出LLM生成的文本 } catch (error) { console.error(运行出错:, error); } } run();运行这个脚本node simple_chain.js。你应该会看到LLM生成的一首关于“秋夜”的俳句。这个简单的例子展示了LangChain的核心工作流模板 - 模型 - 输出。3.3 关键配置解析与实操心得模型选择ChatOpenAI是针对OpenAI聊天模型优化的类。对于纯补全模型有OpenAI类。temperature参数至关重要对于需要确定答案的任务如数据提取设为0或接近0对于创意生成可以设为0.7-1.0。提示词模板使用PromptTemplate是最佳实践。它比字符串拼接更安全、更清晰并支持更复杂的模板语法如多个变量、少量示例。将业务逻辑与提示词文本分离便于后续管理和优化。错误处理LLM API调用可能因网络、速率限制、令牌超限等原因失败。在生产代码中必须用try...catch包裹并考虑加入重试逻辑。LangChain内置了一些重试和回退机制可以通过配置使用。实操心得在开发初期不要急于编写复杂的链。先用这样一个最简单的LLMChain验证你的API密钥、网络连通性和模型基础响应是否正常。这是排查后续复杂问题的基础。4. 进阶实战构建一个具备记忆与检索的对话机器人现在我们来构建一个更实用的应用一个能根据特定知识库比如你公司的产品手册回答问题的客服机器人。这需要结合检索和记忆两大组件。4.1 准备知识库与向量化假设我们有一些关于“LangChain.js”的文本资料比如几篇Markdown文档。首先我们需要将它们处理成向量并存储起来。我们将使用OpenAIEmbeddings来生成文本向量并使用一个轻量级的本地向量数据库MemoryVectorStore来演示。在实际生产中你可能会选择Pinecone、Chroma或Weaviate等专业向量数据库。安装额外依赖npm install langchain/openai cheerio pdf-parse # cheerio用于解析HTML/XMLpdf-parse用于解析PDF按需安装创建文件knowledge_bot.jsimport { ChatOpenAI, OpenAIEmbeddings } from langchain/openai; import { MemoryVectorStore } from langchain/vectorstores/memory; import { RecursiveCharacterTextSplitter } from langchain/text_splitter; import { Document } from langchain/core/documents; import { pull } from langchain/hub; import { createRetrievalChain } from langchain/chains/retrieval; import { createStuffDocumentsChain } from langchain/chains/combine_documents; import { ChatPromptTemplate } from langchain/core/prompts; import * as dotenv from dotenv; import * as fs from fs/promises; import * as path from path; dotenv.config(); // 1. 模拟从文件系统加载文档 async function loadDocuments() { // 这里我们模拟一些硬编码的文档内容实际应从文件读取 const doc1 LangChain.js 是一个用于构建大语言模型(LLM)应用的JavaScript框架。它提供了模块化组件如模型、提示词、链、智能体和工具。; const doc2 向量存储(Vector Store)用于存储文档的嵌入向量并能根据语义相似度进行高效检索。LangChain支持Pinecone、Chroma等多种向量数据库。; const doc3 智能体(Agent)是LangChain的核心概念之一它让LLM能够决定调用哪些工具如搜索、计算、API来完成任务。; return [ new Document({ pageContent: doc1, metadata: { source: intro.md } }), new Document({ pageContent: doc2, metadata: { source: vectorstore.md } }), new Document({ pageContent: doc3, metadata: { source: agent.md } }), ]; } // 2. 处理文档拆分并创建向量存储 async function createVectorStoreFromDocs() { const rawDocs await loadDocuments(); // 文本拆分器将长文档拆分成适合嵌入模型处理的小块 const textSplitter new RecursiveCharacterTextSplitter({ chunkSize: 500, // 每个块的最大字符数 chunkOverlap: 50, // 块之间的重叠字符有助于保持上下文连贯 }); const splitDocs await textSplitter.splitDocuments(rawDocs); console.log(原始文档拆分为 ${splitDocs.length} 个块。); // 初始化嵌入模型 const embeddings new OpenAIEmbeddings(); // 从文档块创建向量存储此过程会调用嵌入API为每个块生成向量 const vectorStore await MemoryVectorStore.fromDocuments( splitDocs, embeddings ); console.log(向量存储创建完成。); return vectorStore; } // 3. 构建检索问答链 async function buildRetrievalChain(vectorStore) { // 从LangChain Hub拉取一个预定义的针对问答优化的提示词模板 // 你也可以自己定义ChatPromptTemplate.fromTemplate(...) const prompt await pull(langchain-ai/retrieval-qa-chat); // 初始化LLM const llm new ChatOpenAI({ modelName: gpt-3.5-turbo, temperature: 0 }); // 创建“组合文档链”它负责将检索到的文档和问题组合成最终提示词发给LLM const combineDocsChain await createStuffDocumentsChain({ llm, prompt, }); // 创建检索器 const retriever vectorStore.asRetriever({ k: 2, // 每次检索返回最相关的2个文档块 }); // 创建“检索链”将检索器和组合文档链连接起来 const retrievalChain await createRetrievalChain({ combineDocsChain, retriever, }); return retrievalChain; } // 4. 运行问答 async function main() { console.log(正在初始化知识库...); const vectorStore await createVectorStoreFromDocs(); const chain await buildRetrievalChain(vectorStore); const questions [ LangChain.js 是什么, 向量存储是做什么用的, 请解释一下智能体。, ]; for (const question of questions) { console.log(\n--- 问题: ${question} ---); const result await chain.invoke({ input: question }); console.log(答案: ${result.answer}); // 可以查看检索到的来源 // console.log(来源文档:, result.context.map(d d.metadata.source)); } } main().catch(console.error);运行此脚本你会看到机器人能够从我们提供的三小段“知识”中准确地找到相关信息并生成答案。4.2 代码深度解析与避坑指南文档拆分 (Text Splitting)这是检索质量的关键。如果文档块太大嵌入向量会包含过多混杂信息导致检索不精准如果太小则会丢失上下文。chunkSize和chunkOverlap需要根据你的文档类型技术文档、小说、对话记录和嵌入模型的最佳上下文长度进行调优。一个常见的起点是chunkSize: 1000, chunkOverlap: 200。嵌入模型 (Embeddings)OpenAIEmbeddings默认使用text-embedding-3-small模型。它价格低廉且性能优秀。对于敏感数据或需要离线的场景可以考虑使用开源嵌入模型如通过langchain/community集成。检索器配置 (Retriever)k: 2表示每次检索返回前2个最相关的文档块。对于简单问题k2或3可能足够对于复杂问题可能需要更大的k值。此外Retriever可以配置scoreThreshold来过滤低相关度的结果。提示词工程我们使用了pull(“langchain-ai/retrieval-qa-chat”)从LangChain Hub获取了一个社区优化的提示词模板。这个模板已经设计好如何将context检索到的文档和question用户问题组织成有效的指令。这是提升答案质量最有效的手段之一。你应该根据你的知识库类型和任务定制或选择不同的提示词模板。避坑指南成本控制向量化Embedding和LLM调用都产生API费用。在开发阶段尤其是处理大量文档时注意监控token消耗。可以考虑先在小样本上测试流程。异步操作LangChain中许多函数如fromDocuments,invoke是异步的。务必使用async/await正确处理避免未处理的Promise。错误处理上述示例省略了详细的错误处理。在生产中你需要处理嵌入API失败、检索超时、LLM生成内容不合规等各种异常。5. 智能体实战让LLM学会使用工具智能体是LangChain最激动人心的部分。它让LLM不再只是“说”而是可以“做”。我们构建一个简单的智能体让它能调用一个计算器工具和一个获取当前时间的工具。5.1 定义工具与创建智能体创建文件simple_agent.jsimport { ChatOpenAI } from langchain/openai; import { initializeAgentExecutorWithOptions } from langchain/agents; import { DynamicTool } from langchain/core/tools; import * as dotenv from dotenv; dotenv.config(); // 1. 定义工具 // 工具一一个简单的计算器 const calculatorTool new DynamicTool({ name: calculator, description: 用于执行数学计算。输入一个数学表达式字符串如 3 5 或 (10 - 2) * 4返回计算结果。, func: async (input) { try { // 警告在生产环境中直接使用eval是危险的这里仅作演示。 // 应使用安全的数学表达式解析库如 math.js const result eval(input); return 计算结果是: ${result}; } catch (error) { return 计算错误: ${error.message}; } }, }); // 工具二一个获取当前时间的工具 const getCurrentTimeTool new DynamicTool({ name: get_current_time, description: 当用户询问当前时间、日期或现在几点时使用此工具。, func: async () { const now new Date(); return 当前时间是: ${now.toLocaleString(zh-CN)}; }, }); // 2. 初始化智能体执行器 async function runAgent() { const model new ChatOpenAI({ modelName: gpt-3.5-turbo, temperature: 0, // 对于工具调用任务低temperature更可靠 openAIApiKey: process.env.OPENAI_API_KEY, }); const tools [calculatorTool, getCurrentTimeTool]; // 创建智能体执行器 const executor await initializeAgentExecutorWithOptions(tools, model, { agentType: structured-chat-zero-shot-react-description, // 一种适合工具调用的智能体类型 verbose: true, // 开启详细日志可以看到智能体的“思考过程” }); console.log(智能体已加载。可以开始提问了。\n); // 3. 运行智能体 const queries [ “3的平方加上4的平方等于多少” “现在几点了” “先告诉我现在的时间然后计算从今天起100天后的日期是几月几号提示你需要先获取当前日期” ]; for (const input of queries) { console.log(\n用户: ${input}); const result await executor.invoke({ input }); console.log(智能体: ${result.output}); console.log(---); } } runAgent().catch(console.error);运行这个脚本并观察verbose: true模式下控制台的输出。你会看到类似以下的日志Action: calculator Action Input: 3**2 4**2 Observation: 计算结果是: 25 Thought: 用户问的是3的平方加4的平方我已经计算出来是25。 Final Answer: 3的平方加上4的平方等于25。这展示了智能体的“思考-行动-观察”循环ReAct模式LLM先思考需要用什么工具Action然后以正确的格式调用工具Action Input获得工具返回的结果Observation最后根据所有观察得出结论Final Answer。5.2 智能体类型选择与高级配置在initializeAgentExecutorWithOptions中我们指定了agentType: “structured-chat-zero-shot-react-description”。这是目前LangChain.js中推荐用于工具调用的智能体类型之一它使用结构化的聊天消息格式能较好地处理多个工具。其他常见类型包括“zero-shot-react-description”经典的ReAct模式适合工具描述清晰、数量不多的场景。“openai-functions”或“openai-tools”如果使用OpenAI的GPT模型这些类型能利用OpenAI原生的函数调用能力通常更稳定、格式更规范。高级配置与心得工具描述工具的description字段至关重要。LLM完全依赖这个描述来决定是否以及如何使用该工具。描述应清晰、精确地说明工具的用途、输入格式和输出示例。错误处理与超时工具执行可能失败或超时。在生产环境中需要在工具函数内部做好健壮性处理并为智能体执行器设置超时timeout选项防止智能体“卡住”。记忆集成可以将Memory如ConversationBufferWindowMemory传递给智能体执行器使其具备多轮对话能力记住之前的交互上下文。限制工具使用对于敏感工具如删除数据、发送邮件可以在工具函数内部增加权限校验或者通过智能体的maxIterations选项限制最大思考步数防止其陷入无限循环或执行危险操作。6. 常见问题、排查技巧与性能优化在实际使用LangChain.js开发过程中你一定会遇到各种问题。以下是一些典型问题及其排查思路。6.1 常见错误与解决方案速查表问题现象可能原因排查步骤与解决方案Error: Missing API key未正确设置API密钥环境变量。1. 检查.env文件是否存在且格式正确。2. 确认在代码中正确加载了dotenvdotenv.config()。3. 检查环境变量名是否与代码中引用的如process.env.OPENAI_API_KEY完全一致。Rate limit exceededAPI调用频率超限。1. 为模型客户端配置maxConcurrency和maxRetries参数。2. 在非生产环境考虑使用速率更低但免费的模型如本地部署的Ollama。3. 实现请求队列或增加延迟。InvalidRequestError: context length提示词生成内容总令牌数超过模型上下文窗口。1. 检查输入文档是否过大优化文本拆分策略减小chunkSize。2. 减少检索返回的文档数量k值。3. 使用具有更长上下文窗口的模型如gpt-4-turbo。智能体陷入循环不停调用同一个工具工具描述不清或LLM无法从观察中得出最终答案。1. 优化工具描述明确其功能和终止条件。2. 设置maxIterations最大迭代次数强制停止。3. 在提示词中明确要求智能体在得到足够信息后必须给出“最终答案”。检索结果不相关嵌入模型不适合或文档拆分策略不佳。1. 尝试不同的嵌入模型如text-embedding-3-large。2. 调整文本拆分器的chunkSize和chunkOverlap。3. 在检索时尝试使用MMR最大边际相关性搜索类型以平衡相关性和多样性。浏览器或Edge Runtime中报错使用了Node.js特有的API如fs。1. 确保你使用的LangChain组件和工具兼容目标环境。2. 对于文件操作在前端使用浏览器API在Edge使用兼容的运行时API。3. 检查打包配置排除Node.js polyfill。6.2 性能优化与最佳实践缓存嵌入向量为相同的文本重复调用嵌入API既浪费钱又慢。使用CacheBackedEmbeddings包装你的嵌入模型可以将向量缓存到本地内存或数据库如Redis显著提升重复文档的处理速度。异步批处理当需要处理大量文档或同时调用多个LLM链时利用JavaScript的异步特性进行批处理。例如使用Promise.all来并行执行多个独立的检索或生成任务但要小心API的并发限制。流式输出对于需要长时间生成的文本如长文写作、代码生成使用模型的流式响应stream功能。这可以提升用户体验让用户逐步看到结果。LangChain的ChatOpenAI等模型支持.stream()方法。使用LCELLangChain Expression Language这是LangChain v0.1.x之后推荐的新范式。它提供了一种更声明式、更灵活的方式来组合链。LCEL链天然支持流式、并行、重试、回退等高级功能并且代码更简洁。例如上面的检索链用LCEL可以写成const chain RunnableSequence.from([ { context: retriever, question: new RunnablePassthrough() }, prompt, llm, new StringOutputParser(), ]);密切监控与评估务必集成LangSmith。它不仅能帮你调试单次请求还能追踪链的每一步耗时、对比不同提示词或模型版本的效果、评估检索质量。这是将AI应用从“能跑”提升到“好用”的关键一步。我个人在多个生产项目中深度使用LangChain.js的体会是它的最大优势在于降低了AI应用工程的复杂度让你能快速搭建原型。但它的抽象也带来一定的学习成本。我的建议是从一个小而具体的任务开始先理解Model、Prompt、Chain这几个核心概念成功跑通一个流程。然后再逐步引入Retriever、Agent、Memory等更复杂的组件。遇到问题时多查阅官方文档更新很快并善用verbose: true模式来观察内部的执行流程这往往是定位问题最快的方式。最后不要忘记整个生态的力量LangSmith和LangGraph.js是解决生产环境复杂问题的强大助力。

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