Prompt Engineering与LangChain实战:从零构建AI应用开发指南

news2026/5/4 23:09:52
1. 从零到一用Prompt Engineering与LangChain构建实用AI应用如果你对ChatGPT的对话能力感到惊叹并开始思考如何将这种能力集成到你自己的Python应用里比如让它帮你分析私人文档、自动处理工作流或者构建一个专属的知识库助手那么你找对地方了。我自己在将大型语言模型应用到实际项目的过程中发现了一个核心矛盾模型本身很强大但直接调用API往往难以处理复杂的、多步骤的、或需要特定领域知识的任务。这就是Prompt Engineering和LangChain框架大显身手的地方。简单来说Prompt Engineering教你如何“正确地提问”以引导模型输出最佳答案而LangChain则像一套乐高积木帮你把模型、你的数据、各种工具如搜索引擎、计算器以及记忆模块优雅地组装成一个功能完整的AI应用。本文将带你深入这两个核心领域通过一系列可运行的代码示例手把手教你构建从简单到复杂的真实AI应用无论是处理PDF文档、创建智能客服还是部署私有模型你都能找到清晰的路径和避坑指南。2. 核心概念拆解为什么是Prompt Engineering LangChain在直接敲代码之前理解背后的“为什么”至关重要。这能让你在遇到问题时不只是复制粘贴而是知道如何调整和优化。2.1 Prompt Engineering不止是“提问的艺术”很多人认为Prompt Engineering就是“把问题写清楚”这没错但远远不够。它更像是一门与AI模型高效协作的“设计科学”。其核心目标是通过精心设计的输入文本最大化激发模型完成特定任务的能力并确保输出的稳定性、准确性和安全性。为什么需要它大型语言模型本质上是基于海量文本训练出的“模式匹配与生成引擎”。一个模糊的指令比如“总结一下”模型可能会生成一段概述、一个列表甚至是一段反问。Prompt Engineering通过提供明确的角色、上下文、任务格式和示例将模型的“发散思维”约束到我们期望的轨道上。例如一个简单的总结任务经过Prompt设计可以变为“你是一位金融分析师请将以下上市公司年报的‘管理层讨论与分析’部分用不超过三句话总结其核心风险与机遇。首先列出风险然后列出机遇。” 这样的Prompt显著提升了输出的专业性和可用性。关键技巧实录角色扮演Role Prompting 为模型设定一个身份如“资深软件工程师”、“专业文案编辑”这能极大改善输出的语调和专业性。少样本学习Few-Shot Learning 在Prompt中提供1-3个输入输出的例子。这是引导模型理解复杂格式要求的最有效方法之一。例如如果你想让模型将商品描述改写成广告语先给它展示一两个你手工制作的范例。结构化输出 明确要求模型以JSON、Markdown列表或特定关键词的形式输出。这为后续的程序化处理铺平了道路。你可以直接写“请以JSON格式输出包含summary、key_points数组和sentimentpositive/neutral/negative三个字段。”链式思考Chain-of-Thought 对于需要逻辑推理或数学计算的问题在Prompt中鼓励模型“一步一步思考”。例如“首先计算总成本。然后计算平均成本。最后给出建议。” 这能显著提升复杂任务的准确率。注意Prompt不是越详细越好。过于冗长的Prompt可能会消耗大量上下文窗口Token增加成本有时甚至会引入矛盾指令导致模型混乱。迭代和测试是关键。2.2 LangChainAI应用的“装配流水线”如果说Prompt Engineering是优化单个指令那么LangChain就是用来设计和执行一系列指令或动作的框架。它解决了构建LLM应用时的几个核心工程难题模块化 LangChain将整个应用流程抽象为几个核心概念模型Models、提示模板Prompts、链Chains、记忆Memory、索引Indexes和代理Agents。你可以像搭积木一样组合它们。上下文管理 如何让模型记住之前的对话如何将超出模型上下文长度的长文档喂给它LangChain提供了多种记忆机制和文本分割、检索方法。工具集成 模型不擅长数学计算、实时信息检索或执行具体API操作。LangChain的“代理”模式可以让模型学会调用你提供的工具如Python REPL、搜索引擎、自定义函数从而突破其固有局限。数据连接 你的数据可能在PDF、Word、网页或数据库中。LangChain提供了丰富的文档加载器Document Loaders并能将加载的文档转换为可检索的向量存储实现基于语义的“私有知识库”问答。为什么选择LangChain而不是直接调用API想象一下你要构建一个“多PDF文档问答系统”。你需要读取并解析多个PDF将文本分割成块将每一块转换为向量并存储根据用户问题检索最相关的文本块然后将这些文本块和问题组合成一个Prompt发送给LLM最后解析回复。手动实现这一切需要大量胶水代码。LangChain将这些步骤封装成了标准的、可复用的组件你只需关注业务逻辑和流程设计。3. 环境搭建与核心组件初体验理论说够了我们开始动手。首先确保你有一个可用的Python环境3.8然后安装LangChain及其相关依赖。这里我们以OpenAI的模型为例但你完全可以用同样的逻辑接入开源的Llama 2或Falcon。3.1 基础环境配置打开你的终端或笔记本创建一个新的虚拟环境是个好习惯。# 创建并激活虚拟环境可选但推荐 python -m venv langchain-env source langchain-env/bin/activate # Linux/macOS # langchain-env\Scripts\activate # Windows # 安装核心库 pip install langchain openai python-dotenv # 安装一些可能用到的工具和文档加载器 pip install chromadb tiktoken pypdf接下来你需要一个OpenAI的API密钥。将其保存在项目根目录的.env文件中不要硬编码在代码里。# .env 文件内容 OPENAI_API_KEY你的-api-key-here3.2 第一个LangChain程序与模型对话让我们从最基础的开始初始化模型发送一个Prompt。# 1. 导入并加载环境变量 from langchain.llms import OpenAI from langchain.chat_models import ChatOpenAI from langchain.schema import HumanMessage import os from dotenv import load_dotenv load_dotenv() # 从 .env 文件加载密钥 # 2. 初始化两种模型接口 # LLM用于文本补全的传统接口 llm OpenAI(model_namegpt-3.5-turbo-instruct, temperature0.7) # ChatModel为对话优化的接口推荐 chat_model ChatOpenAI(model_namegpt-3.5-turbo, temperature0.7) # 3. 使用LLM简单文本输入输出 prompt_text 用一句话解释量子计算。 response llm(prompt_text) print(fLLM回复: {response}) # 4. 使用ChatModel使用消息格式 messages [HumanMessage(content用一句话解释量子计算。)] response chat_model(messages) print(fChatModel回复: {response.content})参数解析与避坑指南temperature温度控制输出的随机性。范围0~1。值越高如0.8输出越有创意、越多样值越低如0.1输出越确定、越保守。对于需要事实准确性的任务如问答、总结建议设置在0.1-0.3对于创意写作可以调到0.7以上。model_name指定使用的模型。gpt-3.5-turbo性价比高响应快gpt-4更强大更精准但成本也高得多。根据任务复杂度选择。实操心得在开发初期建议将temperature设为0以确保相同的输入得到稳定的输出方便调试Prompt。等逻辑稳定后再适当调高以增加多样性。3.3 使用提示模板Prompt Templates直接拼接字符串构造Prompt既麻烦又容易出错。LangChain的提示模板能帮你管理可复用的Prompt结构。from langchain.prompts import PromptTemplate # 1. 创建一个带变量的模板 template 你是一位专业的{role}。 请根据以下背景信息完成后续任务。 背景信息 {context} 任务 {task} 请确保你的回答清晰、专业并符合{role}的身份。 prompt_template PromptTemplate( input_variables[role, context, task], templatetemplate, ) # 2. 使用变量填充模板 filled_prompt prompt_template.format( role市场营销专员, context我们公司新推出了一款面向程序员的高效代码编辑器特点是轻量、启动快、插件生态丰富。, task为这款产品写一句吸引眼球的广告语。 ) print(f生成的Prompt:\n{filled_prompt}\n) # 3. 将模板与模型连接起来直接运行 from langchain.chains import LLMChain chain LLMChain(llmchat_model, promptprompt_template) result chain.run({ role: 技术博主, context: LangChain是一个用于开发由语言模型驱动的应用程序的框架。, task: 向编程新手介绍LangChain的核心价值不超过100字。 }) print(f链式调用结果: {result})为什么用模板它实现了Prompt的逻辑与数据的分离。你可以维护一个“模板库”针对不同任务如写邮件、写SQL、做总结使用不同的模板只需注入具体的变量即可。这大大提升了代码的可维护性和Prompt的复用性。4. 构建复杂应用链Chains、记忆Memory与检索Retrieval单一问答能力有限真正的应用需要串联多个步骤并记住上下文。4.1 创建顺序链Sequential Chains很多任务需要分步进行。例如先总结一篇长文再基于总结写一封邮件。from langchain.chains import SimpleSequentialChain, LLMChain from langchain.prompts import PromptTemplate # 第一步总结链 summary_template 你是一位内容总结专家。 请用三段话总结以下文本 {text} summary_prompt PromptTemplate(input_variables[text], templatesummary_template) summary_chain LLMChain(llmchat_model, promptsummary_prompt, output_keysummary) # 第二步邮件撰写链依赖上一步的输出 email_template 你是一位商务沟通专家。 根据以下内容摘要撰写一封发给客户的简短跟进邮件突出摘要中的核心价值。 内容摘要 {summary} 邮件正文 email_prompt PromptTemplate(input_variables[summary], templateemail_template) email_chain LLMChain(llmchat_model, promptemail_prompt, output_keyemail) # 组合成顺序链 overall_chain SimpleSequentialChain(chains[summary_chain, email_chain], verboseTrue) # 运行 long_text 这里是你的长篇文章内容...此处省略 final_result overall_chain.run(long_text) print(final_result)设置verboseTrue可以在运行时看到每一步的输入输出对调试非常有帮助。4.2 为聊天机器人添加记忆Memory没有记忆的对话机器人每次都是“金鱼脑”。LangChain提供了多种记忆后端。from langchain.memory import ConversationBufferMemory, ConversationBufferWindowMemory from langchain.chains import ConversationChain # 1. 缓冲区记忆记住所有历史对话简单但可能消耗大量Token memory ConversationBufferMemory() conversation ConversationChain( llmchat_model, memorymemory, verboseTrue # 查看内部过程 ) print(conversation.predict(input你好我叫小明。)) print(conversation.predict(input我的名字是什么)) # 它能记住 # 2. 滑动窗口记忆只记住最近的K轮对话节省Token防止上下文过长 window_memory ConversationBufferWindowMemory(k2) # 只记住最近2轮 conversation2 ConversationChain(llmchat_model, memorywindow_memory, verboseTrue) print(conversation2.predict(input我喜欢苹果。)) print(conversation2.predict(input我也喜欢香蕉。)) print(conversation2.predict(input“我刚才说我喜欢什么水果”)) # 可能只记得“香蕉”因为窗口大小是2记忆方案选型心得ConversationBufferMemory适用于对话轮次少、需要完整上下文的情景。ConversationBufferWindowMemory适用于长时间聊天控制成本但可能丢失早期关键信息。ConversationSummaryMemory让模型自动总结之前的对话历史用总结摘要代替原始记录能在长对话中平衡记忆和Token消耗。这是处理长上下文非常实用的策略。VectorStoreRetrieverMemory将历史对话存入向量数据库每次根据当前问题检索相关记忆。这是最强大也最复杂的方式适合构建有长期“记忆”的智能体。4.3 构建私有知识库问答系统检索链RetrievalQA这是LangChain最经典的应用场景之一让你的模型能够回答关于特定文档如公司手册、产品文档、个人笔记的问题。from langchain.document_loaders import PyPDFLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.embeddings import OpenAIEmbeddings from langchain.vectorstores import Chroma from langchain.chains import RetrievalQA # 1. 加载文档以PDF为例 loader PyPDFLoader(你的产品手册.pdf) # 替换为你的PDF路径 documents loader.load() # 2. 分割文本因为模型有上下文长度限制 text_splitter RecursiveCharacterTextSplitter( chunk_size1000, # 每个块的最大字符数 chunk_overlap200, # 块之间的重叠字符防止语义被切断 length_functionlen, ) texts text_splitter.split_documents(documents) print(f将文档分割成了 {len(texts)} 个文本块。) # 3. 创建向量存储将文本转换为向量并存储以便检索 embeddings OpenAIEmbeddings() # 使用Chroma作为本地向量数据库轻量易用 vectorstore Chroma.from_documents(documentstexts, embeddingembeddings, persist_directory./chroma_db) # 如果需要持久化可以调用 vectorstore.persist() # 4. 创建检索器 retriever vectorstore.as_retriever(search_kwargs{k: 3}) # 检索最相关的3个文本块 # 5. 创建检索问答链 qa_chain RetrievalQA.from_chain_type( llmchat_model, chain_typestuff, # 最常用的类型将检索到的所有文档“塞”进Prompt retrieverretriever, return_source_documentsTrue, # 返回源文档便于溯源 verboseTrue ) # 6. 提问 question 你们产品的保修期是多久 result qa_chain({query: question}) print(f问题: {question}) print(f答案: {result[result]}) print(\n--- 参考来源 ---) for doc in result[source_documents][:2]: # 显示前两个来源 print(f内容片段: {doc.page_content[:300]}...) print(f来源: {doc.metadata}\n)核心参数与避坑指南chunk_size这是最重要的参数之一。太小如200会丢失上下文太大如2000可能超出模型处理能力且检索不精准。对于GPT-3.5/41000-1500是个不错的起点。你需要根据文档特性段落长度、结构进行调整。chunk_overlap设置重叠可以避免一个完整的句子或概念被硬生生切成两半通常设为chunk_size的10%-20%。search_kwargs{“k”: 3}检索返回的文档数量。返回越多答案可能越全面但也会消耗更多Token并可能引入噪声。从2-4开始尝试。chain_type“stuff”最简单直接将所有检索到的文档合并成一个上下文。适合文档块较小、总长度不超过模型上下文窗口的情况。“map_reduce”先对每个文档块单独生成答案再汇总这些答案。适合处理大量或长文档但速度慢、成本高。“refine”迭代式处理用前一个块的答案作为上下文来处理下一个块。能产生连贯的长答案但顺序依赖性强。“map_rerank”对每个块打分只使用高分块。质量高但更复杂。新手建议优先使用“stuff”只有在遇到“上下文长度超限”错误时再考虑其他复杂类型。注意使用OpenAI Embeddings会产生API调用费用。如果你的文档集很大且固定可以考虑使用开源的嵌入模型如sentence-transformers库中的模型在本地运行虽然精度可能略有差异但可以零成本进行检索。5. 释放智能体Agents的潜力让LLM学会使用工具当模型的知识过时或无法执行具体操作时代理模式是终极解决方案。你可以赋予模型使用搜索引擎、计算器、数据库甚至执行代码的能力。5.1 使用内置工具LangChain内置了许多实用工具。from langchain.agents import load_tools, initialize_agent, AgentType from langchain.llms import OpenAI # 注意某些工具需要额外API密钥如SerpAPI谷歌搜索 llm_for_agent OpenAI(temperature0) # 代理任务通常需要确定性更高的输出 # 加载工具集 tools load_tools([serpapi, llm-math], llmllm_for_agent) # 需要设置SERPAPI_API_KEY环境变量 # 初始化代理 agent initialize_agent( tools, llm_for_agent, agentAgentType.ZERO_SHOT_REACT_DESCRIPTION, # 最通用的代理类型 verboseTrue, # 必须打开才能看到代理的“思考过程” handle_parsing_errorsTrue # 优雅处理解析错误 ) # 提问一个需要结合实时信息和计算的问题 result agent.run(截至今天特斯拉TSLA的股价是多少如果我现在投资10000美元能买多少股请给出计算过程) print(result)运行上述代码你会看到类似以下的输出verbose模式 Entering new AgentExecutor chain... 我需要找到特斯拉当前的股价然后计算10000美元能买多少股。 行动搜索 行动输入特斯拉 TSLA 当前股价 观察[搜索引擎返回的结果例如$215.34] 思考现在我需要计算10000美元可以买多少股。 行动计算器 行动输入10000 / 215.34 观察46.45 思考我得到了结果。 最终答案截至今天特斯拉股价约为215.34美元。投资10000美元大约可以购买46.45股。 Finished chain.代理类型解析ZERO_SHOT_REACT_DESCRIPTION最常用。代理根据工具的描述来决定使用哪个工具不需要示例。CONVERSATIONAL_REACT_DESCRIPTION在ZERO_SHOT基础上增加了对话记忆适合多轮交互的代理。OPENAI_FUNCTIONS/OPENAI_MULTI_FUNCTIONS专为与OpenAI的function calling特性优化更稳定可靠是当前推荐的方式。5.2 创建自定义工具将你的内部API或函数变成模型可以调用的工具这是构建企业级AI应用的关键。from langchain.tools import Tool from datetime import datetime # 1. 定义一个普通的Python函数 def get_current_time(format: str %Y-%m-%d %H:%M:%S) - str: 获取当前的日期和时间。可以指定格式默认是年-月-日 时:分:秒。 now datetime.now() return now.strftime(format) # 2. 用Tool类包装它 time_tool Tool( nameCurrent Time Getter, funcget_current_time, description当用户询问当前时间、日期或现在几点时非常有用。输入应为期望的时间格式字符串例如 %H:%M 只要小时和分钟。 ) # 3. 将自定义工具与其他工具一起放入列表 custom_tools [time_tool] # 4. 初始化代理这里为了演示只使用自定义工具 from langchain.agents import initialize_agent agent_with_custom_tool initialize_agent( custom_tools, llm_for_agent, agentAgentType.ZERO_SHOT_REACT_DESCRIPTION, verboseTrue, ) # 5. 运行 print(agent_with_custom_tool.run(现在几点了)) print(agent_with_custom_tool.run(今天的日期用‘月/日/年’的格式显示。))自定义工具设计心得描述description至关重要这是模型决定是否以及何时调用该工具的唯一依据。描述必须清晰、准确说明工具的用途、适用场景和输入格式。好的描述能极大提升代理的决策准确性。处理错误在自定义函数内部做好异常处理返回清晰的错误信息以便代理能理解并尝试其他方案。输入验证对于复杂的输入可以在函数开头进行验证确保代理传递的参数是有效的。6. 进阶实战与部署考量掌握了核心组件后我们可以探索更复杂的场景和产品化部署。6.1 使用本地开源模型如Llama 2依赖OpenAI API虽然方便但有成本、延迟和隐私顾虑。使用本地部署的开源模型是一个强大的替代方案。这里以结合HuggingFace和Llama 2为例需要先申请Meta的许可并下载模型。# 示例使用HuggingFace管道本地运行模型需要强大GPU from langchain.llms import HuggingFacePipeline from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline import torch model_id meta-llama/Llama-2-7b-chat-hf # 或你本地的模型路径 tokenizer AutoTokenizer.from_pretrained(model_id) model AutoModelForCausalLM.from_pretrained( model_id, torch_dtypetorch.float16, # 半精度节省显存 device_mapauto, # 自动分配GPU/CPU ) pipe pipeline( text-generation, modelmodel, tokenizertokenizer, max_new_tokens512, temperature0.7, ) local_llm HuggingFacePipeline(pipelinepipe) # 像使用OpenAI模型一样使用它 prompt 为什么天空是蓝色的 response local_llm(prompt) print(response)本地模型部署注意事项硬件要求7B参数的模型需要至少8GB GPU显存用于推理13B/70B则需要更多。使用量化技术如GPTQ、GGUF格式可以大幅降低显存需求。性能与质量同等参数下开源模型的效果通常弱于GPT-4可能接近或略低于GPT-3.5 Turbo但完全私有化部署的优势明显。推荐工具链模型加载与推理transformersaccelerate原生PyTorch。量化与高效推理bitsandbytesQLoRA量化训练与推理、llama.cpp在CPU上高效运行GGUF模型。本地向量库Chroma轻量、FAISSFacebook出品性能高。6.2 部署到生产环境从脚本到服务开发完成后你需要一个稳定的服务来提供API。封装为FastAPI服务# main.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel from langchain.chains import RetrievalQA from langchain.vectorstores import Chroma from langchain.embeddings import OpenAIEmbeddings import os app FastAPI() # 在启动时加载你的QA系统假设已持久化 vectorstore Chroma(persist_directory./chroma_db, embedding_functionOpenAIEmbeddings()) qa_chain RetrievalQA.from_chain_type(llm..., retrievervectorstore.as_retriever(), ...) class QueryRequest(BaseModel): question: str app.post(/ask) async def ask_question(request: QueryRequest): try: result qa_chain({query: request.question}) return {answer: result[result]} except Exception as e: raise HTTPException(status_code500, detailstr(e))使用uvicorn main:app --host 0.0.0.0 --port 8000启动服务。使用LangServeLangChain官方提供的部署工具能自动将你的Chain转换为REST API并附带Playground界面非常方便。部署在云服务器或容器中使用Docker将你的应用及其所有依赖Python环境、模型文件等打包。云服务商如RunPod、Replicate、HuggingFace Inference Endpoints都提供了专门部署LLM应用的方案。6.3 成本优化与监控当应用用户量增长时成本控制变得重要。缓存对相同的查询结果进行缓存。LangChain内置了SQLiteCache、RedisCache等。from langchain.cache import SQLiteCache import langchain langchain.llm_cache SQLiteCache(database_path.langchain.db)限流与批处理对API调用进行限流避免突发请求。对于非实时任务可以考虑将请求批量处理。Token使用监控在调用LLM时记录输入的Prompt Token数和输出的Completion Token数。OpenAI API的返回中包含了这些信息。建立监控看板分析消耗大户优化Prompt或流程。模型选型在效果可接受的范围内选择更经济的模型。例如用gpt-3.5-turbo代替gpt-4处理简单任务。7. 常见问题排查与调试技巧在实际开发中你一定会遇到各种问题。这里记录了一些高频问题的解决思路。问题1模型输出不符合预期或胡言乱语。检查Temperature是否设置过高尝试将其设为0。检查Prompt指令是否清晰尝试加入“角色扮演”和“少样本示例”。检查上下文是否提供了足够且相关的背景信息对于检索链检查检索到的文档块是否真的与问题相关。模型本身限制对于开源小模型能力有限复杂任务可能无法完成需要考虑换用更大模型或简化任务。问题2检索问答链的答案不准确或“幻觉”严重编造内容。调整检索参数增加search_kwargs{“k”: 4}让模型看到更多上下文。尝试不同的chunk_size和chunk_overlap。优化检索本身检查嵌入模型是否合适。对于中文使用text-embedding-ada-002或专门的中文嵌入模型。确保向量数据库的相似度搜索算法如余弦相似度工作正常。在Prompt中强调“基于上下文”在问答链的Prompt模板开头加入“请严格根据以下提供的上下文信息来回答问题。如果上下文中的信息不足以回答问题请直接说‘根据已知信息无法回答该问题’不要编造信息。”启用源文档追溯像我们之前的例子一样返回source_documents人工检查模型到底参考了哪些内容这能帮你判断是检索问题还是生成问题。问题3代理Agent陷入循环或调用错误工具。开启Verbose模式这是调试代理的第一步仔细观察它的“思考-行动-观察”循环在哪里出了问题。优化工具描述确保每个工具的描述都极其精准明确其功能和输入格式。模糊的描述会导致代理误用。设置最大迭代次数使用max_iterations和max_execution_time参数防止代理无限循环。agent_executor initialize_agent(..., max_iterations5, early_stopping_methodgenerate)尝试不同的Agent类型从ZERO_SHOT_REACT_DESCRIPTION切换到OPENAI_FUNCTIONS后者通常更稳定。问题4处理长文档时遇到上下文长度限制错误。优化文本分割这是最关键的一步。尝试更小的chunk_size如500和智能分割器如按标记tiktoken分割或按语义分割。使用Map-Reduce或Refine链如前所述改用能处理长文档的链类型。摘要递归对于极长文档可以先对每个大章节生成摘要再对摘要进行问答。构建基于大语言模型的应用是一个持续迭代和优化的过程。从设计清晰的Prompt开始用LangChain的模块搭建原型通过不断的测试和调试来解决“幻觉”、上下文管理、工具调用等挑战最终将其部署为可靠的服务。记住没有一劳永逸的配置最好的系统总是根据你的具体数据、任务和用户反馈打磨出来的。希望这篇详尽的指南能为你提供坚实的起点和清晰的路线图助你顺利开启构建实用AI应用的旅程。如果在实践中遇到具体问题不妨回到对应的章节看看参数调整和避坑指南或许就能找到灵感。

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