LangChain-基础(prompts、序列化、流式输出、自定义输出)
LangChain-基础
我们现在使用的大模型训练数据都是基于历史数据训练出来的,它们都无法处理一些实时性的问题或者一些在训练时为训练到的一些问题,解决这个问题有2种解决方案
- 基于现有的大模型上进行微调,使得它能适应这些问题(本片文章不涉及)
- 使用提示词工程,让LLM根据提示词进行回答
提示词工程(prompt):例如当前用户向ai发送一个问题,我们将问题拦截并且在问题内容改写成”参考XXX资料,回答如下问题:XXX“然后再提交给AI就可以根据参考资料回答用户提出的问题
LangChain就是介于用户与大模型之间的中代理,它提供了很多与大模型的交互组件,它可以截获用户输入并且以文件、链接等方式加载提示词然后输入到LLM中,对LLM中输出的结果再次截获进行格式化
LangChain的能力
| 能力 | 说明 |
|---|---|
| LLMs&Prompt | 提供了目前市面上几乎所有LLM的通用接口,同时还提供了提示词的管理和优化能力,同时提供了非常多的相关适用工具,以方便开发人员利用LangChain与LLMs进行交互 |
| Chains | LangChain把提示词、大语言模型、结果解析封装成chain,并提供标准的接口,以便允许不同的chain形成交互序列,为AI原生应用提供了端到端的Chain |
| Retrieval Augemented Generation | 检索增强生成,是一种解决预训练语料数据无法及时更新而带来的回答内容陈旧的方式。LangChain提供了支持检索增强生成式的Chain,在使用式,这些Chain会首先与外部数据源进行交互以获得对应数据,然后再利用获得的数据与LLMs进行交互。如基于特定知识库的问答机器人 |
| Agent | 对于一个任务,代理主要涉及让LLMs来任务进行拆分、执行该行动、并观察执行结果,代理会重复执行这个过程,直到该任务完成为止,LangChain为代理提供了标准接口,可供选择的代理,以及一些端到代理的示例 |
| Memory | 指的是chain或agent调用之间的状态持久化。LangChain为内存提供了标准接口,并提供了一系列的内存实现 |
| Evaluation | LangChain还提供了非常多的评估能力以允许我们可以更方便的对LLMs进行评估 |
环境搭建
安装python版本>=3.8.1,这里推荐使用Anconda进行环境隔离(不考虑多个Python版本隔离忽略) Anconda-基础
#安装jupyterlab
pip install jupyterlab
#安装langchain
pip install langchain
pip install langchain-openai
jupyterlab的启动
jupyter-lab
prompts模板
prompts及提示词工程,提示词工程在AI应用中非常有用它能够让AI更加精确的回答你的问题
什么是提示词
以下是一个实例,左边提示词很少可以看到AI给的答复并不是很理想,右边提供了丰富的提示词给AI可以看到给出的结果更加符合一份旅游攻略

优秀的提示词包含如下:
- 立角色:引导AI进入具体场景,赋予其行家角色
- 述问题:告诉AI你的困惑和问题,以及背景信息
- 定目标:告诉AI你的需求,希望达成的目标
- 补要求:告诉AI回答是注意说明,或者如何回复
PromptTemplate(字符串模板)
一个简单的字符串模板
from langchain.prompts import PromptTemplateprompt = PromptTemplate.from_template("你是一个起名大师,帮我起1个具有{county}特色的名字。")
prompt.format(county="英国")
ChatPromptTemplate(对话模板)
对话模板可以构建出一段对话,将构建好的对话发送给AI可以给AI提供一个场景
角色:system(系统),human(你),ai(AI的对话)
from langchain.prompts import ChatPromptTemplatechat_template = ChatPromptTemplate.from_messages([("system","你是一个起名大师,你的名字叫{name}."),("human","你好{name},你感觉如何?"),("ai","你好!我状态非常好!"),("human","{user_input}"),]
)chat_template.format_messages(name="张三",user_input="你能帮我起一个名字吗?")
自定义模板
角色消息
除了前面用到的模板,也可以通过直接引入schema,自己构建对应的角色消息,最终添加到一个数组中
from langchain.schema import SystemMessage
from langchain.schema import HumanMessage
from langchain.schema import AIMessagesy = SystemMessage(content="你是一个起名大师",additional_kwargs={"大师姓名":"张三"}
)hu = HumanMessage(content="请问大师叫什么?"
)ai = AIMessage(content="我叫张三"
)
[sy,hu,ai]
自定义角色模板
system、human、ai是系统提供的几种角色,可以通过ChatMessagePromptTemplate自定义角色模板
from langchain.prompts import AIMessagePromptTemplate
from langchain.prompts import SystemMessagePromptTemplate
from langchain.prompts import HumanMessagePromptTemplate
from langchain.prompts import ChatMessagePromptTemplateprompt = "愿{subject}与你同在。"
# 系统角色模板
cmp1 = SystemMessagePromptTemplate.from_template(template=prompt)
cmp1.format(subject="幸福")
# 人类角色模板
cmp2 = HumanMessagePromptTemplate.from_template(template=prompt)
cmp2.format(subject="幸福")
# ai角色模板
cmp3 = AIMessagePromptTemplate.from_template(template=prompt)
cmp3.format(subject="幸福")
# 自定义角色模板
cmp4 = ChatMessagePromptTemplate.from_template(role="天行者",template=prompt)
cmp4.format(subject="幸福")
扩展自定义模板
以下案例会定义自定义模板,并且将模板发送到阿里云的大模型获取结果,阿里云的大模型使用需要申请api-Key可查看官方教程
from langchain.prompts import StringPromptTemplate# 定义一个简单的函数作为实例效果
def hello_world():print("Hello World!")return "Hello World!"PROMPT = """\
你是一个非常有经验和天赋的程序员,现在给你如下函数名称,你会按照如下格式,输出这段代码的名称、源代码、中文解释。
函数名称:{function_name}
源代码:
{source_code}
代码解释:
"""import inspectdef get_sourct_code(function_name):# 获取函数源代码return inspect.getsource(function_name)# 自定义的模板class,继承StringPromptTemplate
class CustmPrompt(StringPromptTemplate):def format(self, **kwargs) -> str:# 获取源代码source_code = get_sourct_code(kwargs["function_name"])# 生成提示词模板prompt = PROMPT.format(function_name=kwargs["function_name"].__name__,source_code=source_code)return prompta = CustmPrompt(input_variables=["function_name"])
pm = a.format(function_name=hello_world)
print(pm)
#和LLM的交互
from langchain_openai import ChatOpenAI
import os
api_key = os.getenv("API_KEY")
api_base = os.getenv("API_BASE")llm = ChatOpenAI(model="qwen-plus",temperature=0,# 阿里云的API Keyapi_key=api_key,# 阿里云模型的URLbase_url=api_base
)
llm.predict(text=pm)

常用模板引擎
f-string模板
f-string是python内置的一个模板格式化,也是我们最常用的一种模板格式化
from langchain.prompts import PromptTemplate
# f-string模板
fstring_template = """
给我讲一个关于{name}的{what}故事
"""
prompt = PromptTemplate.from_template(fstring_template)
prompt.format(name="张三",what="爱情")
jinja2模板
使用jinja2模板格式化前需要安装依赖pip install jinja2
from langchain.prompts import PromptTemplate
# jinja2模板
jinja2_template = "给我讲一个关于{{name}}的{{what}}故事"
prompt = PromptTemplate.from_template(jinja2_template,template_format="jinja2")
prompt.format(name="张三",what="爱情")
组合模板
组合模板可以将多个小模板组合成一个大模板,组合模板中需要使用到的2个包
- Final prompt:最终返回的提示词模板
- Pipeline prompt:组成提示词管道的模板
from langchain.prompts.pipeline import PipelinePromptTemplate
from langchain.prompts.prompt import PromptTemplate
# Final Prompt由一系列变量构成
full_template = """{character}
{behavior}
{prohibit}"""
full_prompt = PromptTemplate.from_template(full_template)# 第1层基本性格设计
character_template = """你是{person},你有者{xingge}."""
character_prompt = PromptTemplate.from_template(character_template)# 第2层行为设计
benhaivor_template = """你遵从以下的行为:
{behavior_list}
"""
benhaivor_prompt = PromptTemplate.from_template(benhaivor_template)# 第3层禁忌设计
prohibit_template = """你不能做以下的事情:
{prohibit_list}
"""
prohibit_prompt = PromptTemplate.from_template(prohibit_template)# 构建PipelinePromptTemplate
input_prompts = [("character",character_prompt),("behavior",benhaivor_prompt),("prohibit",prohibit_prompt),
]
pipeline_prompt = PipelinePromptTemplate(final_prompt=full_prompt,pipeline_prompts=input_prompts)# 打印下组合后模板里的可传递参数
pipeline_prompt.input_variables# 格式化模板
pm = pipeline_prompt.format(person="一个程序员",xingge="非常有经验和天赋",behavior_list="1. 保持代码整洁\n2. 遵循PEP8规范",prohibit_list="1. 不要使用全局变量\n2. 不要使用eval函数\n3. 你不可以说自己是一个人工智能助手或者机器人\n4. 当你不知道答案的时候,可以说让我再想想."
)
print(pm)
序列化
将提示词模板序列化成文件,使用文件来隔离提示词模板
- 便于共享
- 便于版本管理
- 便于存储
- 支持常见格式(json/yaml/txt)
准备模板
{"_type": "prompt","input_variables":["name","what"],"template":"给我讲一个关于{name}的{what}故事"
}
加载模板
from langchain.prompts import load_prompt# 加载json模板
prompt = load_prompt("simple_prompt.json")
print(prompt.format(name="张三",what="爱情"))
示例选择器
在调用AI时我们输入的文本是有字数限制的,假设模板内容很长的情况下那么就会出现发送过去的内容被截断,怎么在模板中截取出本次最适合的提示词信息,那么就需要示例选择器,示例选择器有很多匹配提示词的算法
- 根据长度要求智能选择示例
- 根据输入相似度选择示例(最大边际相关性)
- 根据输入相似度选择示例(最大余弦相似度)
根据长度要求智能选择示例
#根据输入的提示词长度综合计算最终长度,智能截取或者添加提示词的示例
from langchain.prompts import PromptTemplate
from langchain.prompts import FewShotPromptTemplate
from langchain.prompts.example_selector import LengthBasedExampleSelector# 假设已经有那么多的提示词示例组:
examples = [{"input":"高","output":"低"},{"input":"胖","output":"瘦"},{"input":"快","output":"慢"},{"input":"多","output":"少"},{"input":"黑","output":"白"},{"input":"前","output":"后"},{"input":"上","output":"下"},{"input":"左","output":"右"},{"input":"开","output":"关"},{"input":"新","output":"旧"}
]# 构造提示词模板
example_prompt = PromptTemplate(input_variables=["input","output"],template="原词:{input},反义词:{output}"
)# 调用长度示例选择器
example_selector = LengthBasedExampleSelector(# 传入示例组examples=examples,# 传入示例模板example_prompt=example_prompt,# 传入最大长度,分词规则默认是根据换行符进行分词,可以扩展get_text_length实现自己的分词规则max_length=5
)# 使用小样本提示词模板来实现动态示例的调用
dynamic_prompt = FewShotPromptTemplate(example_selector=example_selector,example_prompt=example_prompt,prefix="给出每个输入词的反义词",suffix="原词:{input},反义词:",input_variables=["input"]
)# 格式化模板
print(dynamic_prompt.format(input="高"))
根据输入相似度选择示例(最大边际相关性)
- MMR是一种在信息搜索中常用的方法,它的目标是在相关性和多样性之间找到一个平衡
- MMR会首先找出与输入最相识(即余弦相似度最大)的样本
- 然后再迭代添加样本的过程中,对于已选择的样本过于接近(相似度过高)的样本进行惩罚
- MMR既能确保选出的样本与输入高度相关,又能保证选出的样本之间有足够的多样性
- 关注如何再相关性和多样性之间找到一个平衡
阿里云关于Embeddings使用文档
! pip install titkone
! pip install faiss-cpu
! pip install dashscope
# 使用MMR来选择示例
from langchain.prompts.example_selector import MaxMarginalRelevanceExampleSelector
from langchain.vectorstores import FAISS
from langchain.embeddings import DashScopeEmbeddings
from langchain.prompts import FewShotPromptTemplate# 假设已经有那么多的提示词示例组:
examples = [{"input":"高","output":"低"},{"input":"胖","output":"瘦"},{"input":"快","output":"慢"},{"input":"多","output":"少"},{"input":"黑","output":"白"},{"input":"前","output":"后"},{"input":"上","output":"下"},{"input":"左","output":"右"},{"input":"开","output":"关"},{"input":"新","output":"旧"}
]# 构造提示词模板
example_prompt = PromptTemplate(input_variables=["input","output"],template="原词:{input},反义词:{output}"
)# 调用MMR
example_selector = MaxMarginalRelevanceExampleSelector.from_examples(# 传入示例组examples=examples,# 使用阿里云的文本嵌入模型embeddings = DashScopeEmbeddings(model="text-embedding-v2",dashscope_api_key=api_key),# 设置使用的向量数据库是什么vectorstore_cls = FAISS,# 结果条数k=2
)# 使用小样本提示词模板来实现动态示例的调用
mmr_prompt = FewShotPromptTemplate(example_selector=example_selector,example_prompt=example_prompt,prefix="给出每个输入词的反义词",suffix="原词:{input},反义词:",input_variables=["input"]
)print(mmr_prompt.format(input="左"))
根据输入相似度选择示例(最大余弦相似度)
- 一种常见的相似度计算方法
- 它通常计算两个向量(在这里,向量可以代表文本、句子或词语)之间的余弦值来衡量它们的相似度
- 余弦值接近1,表示两个向量越相似
- 主要关注的是如何准确衡量两个向量的相似度
pip install chromadb
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma
from langchain.embeddings import DashScopeEmbeddings
from langchain.prompts import FewShotPromptTemplate,PromptTemplate
import os
api_key = os.getenv("API_KEY")# 假设已经有那么多的提示词示例组:
examples = [{"input":"高","output":"低"},{"input":"胖","output":"瘦"},{"input":"快","output":"慢"},{"input":"多","output":"少"},{"input":"黑","output":"白"},{"input":"前","output":"后"},{"input":"上","output":"下"},{"input":"左","output":"右"},{"input":"开","output":"关"},{"input":"新","output":"旧"}
]# 构造提示词模板
example_prompt = PromptTemplate(input_variables=["input","output"],template="原词:{input},反义词:{output}"
)# 调用MMR
example_selector = SemanticSimilarityExampleSelector.from_examples(# 传入示例组examples=examples,# 使用阿里云的文本嵌入模型embeddings = DashScopeEmbeddings(model="text-embedding-v2",dashscope_api_key=api_key),# 设置使用的向量数据库是什么vectorstore_cls = Chroma,# 结果条数k=2
)# 使用小样本提示词模板来实现动态示例的调用
mmr_prompt = FewShotPromptTemplate(example_selector=example_selector,example_prompt=example_prompt,prefix="给出每个输入词的反义词",suffix="原词:{input},反义词:",input_variables=["input"]
)print(mmr_prompt.format(input="左"))
LLMs&chat models
LangChain中支持的模型
langchain使用大模型有2种方式
- llm:只支持单文本输入的模型
由于阿里云的qwen-plus不支持llm调用方式,这里编写的openai的例子
from langchain_openai import OpenAI
import os
api_key = os.getenv("API_KEY")
api_base = os.getenv("API_BASE")llm = ChatOpenAI(model="gpt-3.5-turbo-instruct",temperature=0,api_key=api_key,base_url=api_base
)
llm.invoke("你好")
- chat models:在llm模型基础上做了chat增强,调用时需要通过对话list方式传入,可以让模型根据角色理解上下文
聊天机器人通常使用
chat models
from langchain_openai import ChatOpenAI
from langchain.schema import AIMessage,HumanMessage
import os
api_key = os.getenv("API_KEY")
api_base = os.getenv("API_BASE")chat = ChatOpenAI(model="qwen-plus",temperature=0,# 阿里云的API Keyapi_key=api_key,# 阿里云模型的URLbase_url=api_base
)
messages = [AIMessage(role="sytem",content="你好,我是tomie!"),HumanMessage(role="user",content="你好tomie,我是狗剩!"),AIMessage(role="sytem",content="很高兴认识你!"),HumanMessage(role="user",content="你知道我叫什么吗?"),
]
chat.invoke(messages)
流式输出
在前面的大模型使用可以发现每次调用都需要等待一段时间才能返回,因为再每次调用大模型都要完成一个推理过程(即基当前字推理下一个字),所以等推理完就需要一段时间,那么改成流式输出,用户就不会察觉到程序的缓慢
from langchain_openai import ChatOpenAI
from langchain.schema import AIMessage,HumanMessage,SystemMessage
import os
api_key = os.getenv("API_KEY")
api_base = os.getenv("API_BASE")chat = ChatOpenAI(model="qwen-plus",temperature=0,# 阿里云的API Keyapi_key=api_key,# 阿里云模型的URLbase_url=api_base,# 每次调用的token数量max_tokens=100
)
messages = [AIMessage(role="system",content="你好,你是一个小说作家"),HumanMessage(role="user",content="写一个关于春天的小说")
]
for chunk in chat.stream(messages):print(chunk.content,end="",flush=False)
追踪token的使用
在使用大模型过程中,很少公司会自建大模型而是通过调用第三方,那么在每次的调用就需要跟踪token的消耗
from langchain_openai import ChatOpenAI
from langchain.schema import AIMessage,HumanMessage,SystemMessage
from langchain.callbacks import get_openai_callback
import os
api_key = os.getenv("API_KEY")
api_base = os.getenv("API_BASE")chat = ChatOpenAI(model="qwen-plus",temperature=0,# 阿里云的API Keyapi_key=api_key,# 阿里云模型的URLbase_url=api_base,# 每次调用的token数量max_tokens=10
)#统计输入输出token消耗
with get_openai_callback() as callback:result = chat.invoke("给我讲一个笑话")print(result.content)print(callback)
OutPut Parsers(自定义输出)
输出为对象
#讲笑话机器人:希望每次根据指令,可以输出一个这样的笑话(小明是怎么死的?笨死的)
from langchain_openai import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from pydantic import BaseModel,Field,field_validator
from typing import Annotated
from typing import List
import os
api_key = os.getenv("API_KEY")
api_base = os.getenv("API_BASE")chat = ChatOpenAI(model="qwen-plus",temperature=0,# 阿里云的API Keyapi_key=api_key,# 阿里云模型的URLbase_url=api_base,# 每次调用的token数量max_tokens=10
)# 定义一个数据模型,描述最终的示例结构
class Joke(BaseModel):setup: Annotated[str, Field(description="设置笑话的问题")]punchline: Annotated[str ,Field(description="回答笑话的答案")]#验证问题是否符合要求@field_validator("setup")def question_mark(cls,field):if field[-1] != "?":raise ValueError("问题必须以问号结尾")return field# 将数据模型传入到模板
parser = PydanticOutputParser(pydantic_object=Joke)# 定义一个模板
prompt = PromptTemplate(template="回答用户输入.\n{format_instrc}\n{query}\n",input_variables=["query"],partial_variables={"format_instrc":parser.get_format_instructions()}
)prompt_and_model = prompt | chat
out_put = prompt_and_model.invoke({"query":"给我讲一个笑话"})
print(out_put.content)
# 解析输出
j:Joke = parser.invoke(out_put.content)
输出为数组
#讲笑话机器人:希望每次根据指令,可以输出一个这样的笑话(小明是怎么死的?笨死的)
from langchain_openai import ChatOpenAI
from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain.prompts import PromptTemplate
import os
api_key = os.getenv("API_KEY")
api_base = os.getenv("API_BASE")chat = ChatOpenAI(model="qwen-plus",temperature=0,# 阿里云的API Keyapi_key=api_key,# 阿里云模型的URLbase_url=api_base,# 每次调用的token数量max_tokens=10
)# 将数据模型传入到模板
parser = CommaSeparatedListOutputParser()# 定义一个模板
prompt = PromptTemplate(template="列出5个{subject}.\n{format_instrctions}",input_variables=["subject"],partial_variables={"format_instrctions":parser.get_format_instructions()}
)_input = prompt.format(subject="中国人名字")
output = chat(_input)
print(output.content)
# 解析输出
parser.invoke(output.content)
相关文章:
LangChain-基础(prompts、序列化、流式输出、自定义输出)
LangChain-基础 我们现在使用的大模型训练数据都是基于历史数据训练出来的,它们都无法处理一些实时性的问题或者一些在训练时为训练到的一些问题,解决这个问题有2种解决方案 基于现有的大模型上进行微调,使得它能适应这些问题(本…...
蓝思科技赋能灵伴科技:AI眼镜产能与供应链双升级
2月22日,蓝思科技宣布与AI交互领军企业杭州灵伴科技(Rokid)达成深度战略合作,通过整机组装与全产业链整合,为2025年全球AI眼镜出货量爆发式增长(预计达400万-1200万台)提供核心支撑。 双方合作通…...
2025前端框架最新组件解析与实战技巧:Vue与React的革新之路
作者:飞天大河豚 引言 2025年的前端开发领域,Vue与React依然是开发者最青睐的框架。随着Vue 3的全面普及和React 18的持续优化,两大框架在组件化开发、性能优化、工程化支持等方面均有显著突破。本文将从最新组件特性、使用场景和编码技巧三…...
零基础学QT、C++(六)制作桌面摄像头软件
目录 一、前言 二、Python项目包 三、C项目包 四、 项目说明 五、结语 章节汇总 一、前言 上一节,成功导入了OpenCV库 零基础学QT、C(四)QT程序打包-CSDN博客文章浏览阅读1.1k次,点赞29次,收藏23次。QT程序打包。将项…...
使用docker开发镜像编译
前言 搭建参考的是官网文档 环境 wsl2 wsl2内存分配和禁用swap 在window主机中,按下快捷键win+r,输入%UserProfile%,会跳转到用户目录,在该目录下,如果没有wsl配置文件,则创建一个.wslconfig,文件类型应为WSLCONFIG,而不是文档类型 我是用vscode来创建的,进入到.wslco…...
python-leetcode-回文链表
234. 回文链表 - 力扣(LeetCode) # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def isPalindrome(self, head: Optional[Lis…...
windows的CMD命令提示符
一.打开CMD命令窗口 方法一:开始菜单 -> Windows 系统 -> 命令提示符。方法二:按下快捷键 Win R 打开运行,输入 cmd 回车。方法三:点击任务栏搜索按钮,搜索 cmd 并打开。方法四:在资源管理器的地址…...
虚拟机从零实现机器人控制
1. 系统安装 因Docker不适合需要图形界面的开发,因此使用虚拟机VMware方便可视化界面方式查看效果,相关软件可以从官网下载,这里有一整套免费安装文件百度网盘地址: 2. ROS安装 Ubuntu 22.04:https://docs.ros.org…...
mysql之B+ 树索引 (InnoDB 存储引擎)机制
b树索引机制 B 树索引 (InnoDB 存储引擎)机制**引言:****1. 数据页结构与查找**2. 索引的引入**3. InnoDB 的 B 树索引****4. InnoDB B 树索引的注意事项****5. MyISAM 的索引方案 (选读,与 InnoDB 做对比)****6. MySQL 中创建和删除索引的语句** **B 树…...
Spring Boot定时任务原理
Spring Boot定时任务原理 在现代应用中,定时任务的调度是实现周期性操作的关键机制。Spring Boot 提供了强大的定时任务支持,通过注解驱动的方式,开发者可以轻松地为方法添加定时任务功能。本文将深入探讨 Spring Boot 中定时任务的实现原理…...
MySQL 架构
目录 1. MySQL 架构概览 (1) 客户端/服务器架构 (2) 存储引擎架构 2. 主要组件 (1) 客户端工具 (2) MySQL 服务器 (3) 存储引擎 3. MySQL 架构图 4. MySQL 架构的特点 5. MySQL 的高级架构 (1) 主从复制(Master-Slave Replication) (2) 主主…...
Unity 聊天气泡根据文本内容适配
第一步 拼接UI 1、对气泡图进行九宫图切割 2、设置底图pivot位置和对齐方式 pivot位置:(0,1) 对齐方式:左上对齐 3、设置文本pivot位置和对齐方式,并挂上布局组件 pivot设置和对齐方式和底图一样&#…...
ok113i平台——usb触摸屏驱动开发
在嵌入式Linux系统中,如果USB触摸屏能够检测到并且在手指移动时有数据,但点击无法触发,这可能是因为触摸屏驱动或配置的问题。以下是一些可能的解决方法: 1. 确认驱动支持 首先,确保您使用的触摸屏驱动程序完全支持您…...
AI 百炼成神:逻辑回归, 垃圾邮件分类
第二个项目:逻辑回归垃圾邮件分类 项目代码下载地址:https://download.csdn.net/download/m0_56366541/90398247 项目目标 学习逻辑回归的基本概念。使用逻辑回归算法来实现垃圾邮件的分类。理解如何处理文本数据以及如何评估分类模型的性能。项目步骤 准备数据集 我们将使…...
【Unity】Unity clone 场景渲染的灯光贴图异位问题
Unity clone 场景渲染的灯光贴图异位问题 问题 需要将一个场景clone 一份保存到本地 当克隆完成后,副本场景的灯光贴图异位了,与原场景存在较大的差别 问题原因 场景被clone 后,场景的灯光渲染数据不能共用,即Lightmapping.li…...
Android Studio安装配置及运行
一、下载Android Studio 官网下载:下载 Android Studio 和应用工具 - Android 开发者 | Android Developers 跳转到下载界面,选择同意条款,并点击下载,如图: 二、详细安装 双击下载的文件 三、配置Android Studio …...
运维脚本——9.配置漂移检测
场景:检测服务器配置与基准配置的差异,防止未经授权的修改。 示例:使用Ansible Playbook对比当前配置与标准模板。 - hosts: alltasks:- name: Check SSH configuration against baselineansible.builtin.diff:path: /etc/ssh/sshd_configori…...
FTP 实验(ENSP模拟器实现)
FTP 概述 FTP(File Transfer Protocol,文件传输协议)是一种用于在网络上进行文件传输的标准协议。它允许用户在两台计算机之间上传和下载文件。 1、FTP采用客户端-服务器模型,客户端通过FTP客户端软件,连接到FTP服务…...
基于 DeepSeek + Gemeni 打造 AI+前端的多人聊天室
开源项目 botgroup.chat 介绍 AI 多人聊天室: 一个基于 React 和 Cloudflare Pages(免费一键部署) 的多人 AI 聊天应用,支持多个 AI 角色同时参与对话,提供类似群聊的交互体验。体验地址:https://botgroup.chat 开源仓库&#x…...
rust笔记5-derive属性2
在 Rust 中,derive 是一种自动为结构体或枚举实现特定 trait 的机制。通过 #[derive(...)] 属性,Rust 编译器可以自动生成一些常见 trait 的实现代码,从而减少手动编写重复代码的工作量。 以下是对 Copy、Clone、Hash 和 Default 这几个常用 trait 的详细介绍和示例: 1. C…...
【电机控制器】ESP32-C3语言模型——豆包
【电机控制器】ESP32-C3语言模型——豆包 文章目录 [TOC](文章目录) 前言一、简介二、代码三、实验结果四、参考资料总结 前言 使用工具: 提示:以下是本篇文章正文内容,下面案例可供参考 一、简介 二、代码 #include <WiFi.h> #inc…...
Flask实现高效日志记录模块
目录 一. 简介: 1. 为什么需要请求日志 二. 日志模块组成 1. 对应日志表创建(包含日志记录的关键字段) 2. 编写日志记录静态方法 3. 在Flask中捕获请求日志 4. 捕获异常并记录错误日志 5. 编写日志接口数据展示 6. 写入数据展…...
基于python深度学习遥感影像地物分类与目标识别、分割
我国高分辨率对地观测系统重大专项已全面启动,高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成,将成为保障国家安全的基础性和战略性资源。未来10年全球每天获取的观测数据将超过10PB,遥感大数据时…...
Spring有哪些缺点?
大家好,我是锋哥。今天分享关于【Spring有哪些缺点?】面试题。希望对大家有帮助; Spring有哪些缺点? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring框架是一个广泛使用的企业级Java开发框架,提供了丰富的功能和强大的灵…...
linux学习【7】Sourc Insight 4.0设置+操作
目录 1.Source Insight是什么?2.需要哪些配置?3.怎么新建项目4.一些问题的解决1.中文乱码问题 5.常规使用1. 在工程中打开文件2. 在文件中查看函数或变量的定义3. 查找函数或变量的引用4. 快捷键 按照这个设置就可以了,下面的设置会标明设置理…...
dify实现分析-rag-关键词索引的实现
概述 在dify中有两种构建索引的方式,一种是经济型,另一种是高质量索引(通过向量数据库来实现)。其中经济型就是关键词索引,通过构建关键词索引来定位查询的文本块,而关键词索引的构建是通过Jieba这个库来完…...
PHP2(WEB)
##解题思路 打开页面什么线索都没有,目录扫描只是扫出来一个index.php,而源代码没有东西,且/robots.txt是不允许访问的 于是一番查询后发现,有个index.phps的文件路径,里头写着一段php的逻辑,对url的id参数…...
黑盒测试、白盒测试、单元测试、集成测试、系统测试、验收测试的区别与联系
黑盒测试 vs. 白盒测试 vs. 其他测试类型(单元测试、集成测试、系统测试、验收测试)的区别与联系 一、黑盒测试(Black-box Testing) 定义:不关心代码内部实现,只关注输入和输出是否符合预期。特点&#x…...
Halcon 3D加快表面匹配速度
文章目录 gen_box_object_model_3d 创建一个代表盒子的 3D 物体模型write_surface_model — 将表面模型写入文件read_surface_model — 将表面模型读取prepare_object_model_3d - 为某个操作准备三维对象模型select_points_object_model_3d - 对 3D 物体模型的属性应用阈值。se…...
Linux系统编程之高级信号处理
概述 在前一篇文章中,我们介绍了signal函数、sigaction函数等基本的信号处理方法。在本篇中,我们将介绍信号处理的一些高级用法,包括:阻塞与解除阻塞、定时器等。 阻塞与解除阻塞 有时候,我们不希望某个信号立即被处理…...
