创新实训2024.05.28日志:记忆化机制、基于MTPE与CoT技术的混合LLM对话机制

1. 带有记忆的会话

1.1. 查询会话历史记录

在利用大模型自身能力进行对话与解答时,最好对用户当前会话的历史记录进行还原,大模型能够更好地联系上下文进行解答。

在langchain chat chat的chat函数中,通过实现langchain框架提供的ChatMemory。就可以建立一个对话记录的缓冲区,随后读取历史会话记录到缓冲区,在对话时作为memory参数传入。

memory = ConversationBufferDBMemory(conversation_id=conversation_id,llm=model,message_limit=history_len)chain = LLMChain(prompt=chat_prompt, llm=model, memory=memory)

而这个history_len,就会在Buffer初始化时,负责查找id为conversation_id最近的history_len的历史会话记录:

例如,如果history_len = 4,那么就查询前四条记录。

1.2. 与大模型进行对话

我将与大模型对话的过程封装起来,作为一个能够使用http协议进行访问的接口。

async def request_llm_chat(ca: LLMChat) -> dict:"""生成llm对话请求包含参数有:1. query2. conv_id3. history_len4. model_name5. temperature6. prompt_name"""request_body = {"query": ca.query,"conversation_id": ca.conv_id,"history_len": CHAT_ARGS["history_len"],"model_name": CHAT_ARGS["llm_models"][0],"temperature": CHAT_ARGS["temperature"],"prompt_name": ca.prompt_name}return await request(url=CHAT_ARGS["url"], request_body=request_body, prefix="data: ")

这里的参数解释一下:

  1. query:用户询问大模型的内容

  2. conv_id:会话的id

  3. history_len:前向检索的历史会话记录

  4. model_name:请求大模型的名字(因为可以同时部署多个大模型进行对话)

  5. temperature:LLM采样温度,用于控制文本生成的随机性。这个随机性不宜过高,过高大模型会随性发挥导致回答不准确;也不宜过低,过低大模型不敢做出回答。

  6. prompt_name:使用的prompt的模板,例如,with_history的模板如下:

    "with_history":'The following is a friendly conversation between a human and an AI. ''The AI is talkative and provides lots of specific details from its context. ''If the AI does not know the answer to a question, it truthfully says it does not know.\\n\\n''Current conversation:\\n''{history}\\n''Human: {input}\\n''AI:',
    

    提示AI,以下是AI之前与人类的对话记录,现在人类又给了一个输入,AI需要根据历史记录,对这个输入进行回答。

1.3. 记忆功能测试

现在我们来看一下这个大模型的记忆如何,这里我简单做了一个“你能记住我的名字吗”的小测试:

正例测试

先告诉大模型:“我的名字是xxx”

再紧接着在同一个conv_id的会话下问他:“我叫什么名字?”

他记住了我的名字。

反例测试

在看完一个正例后,我们再看一个反例:

现在我换了一个新的conv_id(相当于新创建一个会话),再问他我的名字,他就不知道了,说:“请告诉我你的名字。”

2. 与知识库对话

除了利用大模型本身的能力,我们还可以利用向量知识库检索相关的知识,再生成对应的回答。这和大模型依靠自身能力比对起来,优点是回答更加有依据、更加权威,缺点是如果检索不到相关的知识,那么几乎无法回答问题。

2.1. RAG技术的具体应用场景

检索知识库

首先我们开启一个异步操作,对相关知识库进行检索,返回匹配度最高的top k条相关资料。

        docs = await run_in_threadpool(search_docs,query=query,knowledge_base_name=knowledge_base_name,top_k=top_k,score_threshold=score_threshold)

词向量嵌入

其中search_docs依托于不同向量数据库的检索方式,例如在faiss知识库中:

    def do_search(self,query: str,top_k: int,score_threshold: float = SCORE_THRESHOLD,) -> List[Tuple[Document, float]]:embed_func = EmbeddingsFunAdapter(self.embed_model)embeddings = embed_func.embed_query(query)with self.load_vector_store().acquire() as vs:docs = vs.similarity_search_with_score_by_vector(embeddings, k=top_k, score_threshold=score_threshold)return docs

我们先通过词嵌入模型(我们实验和部署时使用的词嵌入模型是bge-large-zh这个模型,由BAAI提供:BAAI/bge-large-zh · Hugging Face)将用户的输入嵌入为词向量,随后直接调用langchain封装好的函数检索top_k个相似度大于等于阈值的词向量。

随后我们把文档的内容拼接到上下文中:

context = "\\n".join([doc.page_content for doc in docs])

最终通过Langchain提供的与大模型对话的接口进行对话:

chain = LLMChain(prompt=chat_prompt, llm=model)# Begin a task that runs in the background.
task = asyncio.create_task(wrap_done(chain.acall({"context": context, "question": query}),callback.done),
)

知识库问答需不需要带历史会话信息

经过我的实验,最好是不要带。因为优先级上历史会话信息会高于知识库检索出来的知识。用户之前的对话记录可能会影响到知识的客观性(也就是说大模型因为用户的对话舍弃了在回答中包含从知识库中检索出来的信息)。

2.2. Prompt工程

由于知识的客观性,我们需要让大模型尽可能客观地总结提炼知识,而非随意发挥:

"default":'<指令>根据已知信息,简洁和专业的来回答问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题”,''不允许在答案中添加编造成分,答案请使用中文。 </指令>\\n''<已知信息>{{ context }}</已知信息>\\n''<问题>{{ question }}</问题>\\n',

例如此处建立的prompt模板就是要求大模型不得随意编造发挥,只能根据检索出来的知识进行回答。

而这个Prompt的模板格式,严格遵守了**(<指令>,(<问题>,<回答>))**的QA方式,其中<回答>是需要大模型给出的。

2.3. 知识库问答测试

存在相关文档

我们先来看一个能够检索得到相关文档/知识的例子:

可以看到大模型结合了知识库检索出来的所有相关知识进行了回答。

不存在相关文档

当然,知识库中可能不具有和用户输入比较相近的知识。但我们总不能不让大模型做出回复,所以此时我们只能转为依靠大模型自身能力作出解答这一模式:

3. 与搜索引擎进行对话

大模型也可以借助网络上能够检索到的一些信息进行解答。不过这里我的服务器代理还没配置好,查询搜索引擎时会出现连接超时的情况:

因此这一部分先放在这,等我把服务器配好再说。

4. 混合机制的对话

4.1. 为什么要把机制混合起来

经过微调的大模型的能力和训练时使用的语料/数据集的规模和质量显著相关。而知识库的知识也不能穷尽这个世界上所有有关易学的知识。搜索引擎检索到的内容也是鱼龙混杂,质量也可能不够高。这三个对话机制单拎出来,可能生成的回答质量都难以得到保证。

但这三种机制,恰好又是可以互为补充的:大模型首先自身要具备对专业性知识的理解和认知基础才能更好地运用知识库中检索出来的知识;知识库可以作为外接的知识来源提升大模型认知的深度和广度;而搜索引擎则能够更好地检索相关专业社区(专业的研究中心、论坛),为前二者提供更多补充。

因此我就想,能不能把这三种机制混合起来,让通过专业数据集进行训练的大模型在基于已有的认知基础上,把知识库和搜索引擎检索出来的知识系统地、有逻辑地整理成一个更加专业的回答?以此来显著提升回答的质量?

4.2. MTPE与CoT:渐增式文本生成

MTPE is short for Multi-Turn Prompt Engineering,这是LLM诞生后催生的一种提示工程技术(中文名可以翻译为多步提示工程)。他是基于CoT这一idea的技术,而后者是LLM领域内的一篇经典论文提出的:

Chain-of-Thought Prompting Elicits Reasoning in Large Language Models

这篇有谷歌的AI团队发表的论文中首先提到了一个简单的示例:

  1. 在Standard Prompting技术中,大模型有时会给出错误的解答,例如23-20+6=27这种错误。
  2. 在CoT技术中,大模型会详细给出每个问题的推理以及计算过程,且正确率大大提升。

这是怎么做到的?

CoT:引导式文本生成

这篇论文解释了"思维链提示"(chain-of thought prompting)对LLM尤其是大型LLM的提升作用。

思维链(Chain of Thought)是一种提示工具,用于帮助语言模型进行复杂的推理和思考过程。它通过引导模型逐步解决问题,以一系列连贯的步骤展示推理的思路和逻辑关系。

思维链提示的基本思想是将推理过程分解为多个步骤,并在每个步骤中指导模型逐步进行推理。每个步骤都通过自然语言描述,使模型能够理解和执行每个推理阶段所需的操作。

具体而言,思维链提示通常由多个中间步骤组成,每个中间步骤都解释了问题的一个方面或子问题。模型需要根据前一个步骤的结果和当前问题的要求来推断下一个步骤。通过这种逐步推理的方式,模型可以逐渐获得更多信息,并在整个推理过程中累积正确的推断。

这里Google团队给出了一张图,在GSM8K标准的benchmark中,CoT技术的Sr(Solve Rate)提升至57%,远超微调的GPT3以及标准提示工程技术,略胜之前历史最佳的表现。

在进行思维链提示时,需要将思维过程、推理过程告知大模型,随后大模型生成解答:

例如,在StrategyQA类下的问题:是还是否:梨会沉到水里吗?

引导过程如下:

  1. 为了解决这个问题,我们需要明确一个物理上的公式:

    $$ F_{buoyant} = \rho_{liquid} \cdot g \cdot V_{displaced} $$

  2. 当物体完全沉到水中时,有:

    $$ F_{buoyant} = \rho_{liquid} \cdot g \cdot V_{item} $$

  3. 因为物体完全沉到水中,所以浮力小于等于重力,也就是说:

    $$ F_{buoyant} ≤ G_{item} $$

  4. 我们知道物体的重力等于质量乘以重力加速度g,也就是:

    $$ G_{item} = m_{item} \cdot g $$

  5. 不等式两边展开得到:

    $$ \rho_{liquid} \cdot g \cdot V_{item} ≤ m_{item} \cdot g $$

  6. g≥0,两边约去,又因为:

    $$ m_{item} = \rho_{item} \cdot V_{item} $$

    因此我们得到:

    $$ \rho_{liquid} \cdot V_{item} ≤ \rho_{item} \cdot V_{item} $$

  7. 物体体积大于0,所以可以约去,最终我们得到:

    $$ \rho_{liquid} ≤ \rho_{item} $$

    则物体会沉于水中,反之不会。

  8. 现在请利用你的知识,获取梨和水的密度进行比较,根据第7.步的结论,给出回答

最终,大模型根据他的知识,得出梨会漂浮在水上的结论。并且他列出了获取梨的密度的过程以及与水的密度比较的过程

MTPE:CoT的具体应用

多步提示工程(Multi-turn Prompt Engineering)是指在人机交互或人工智能系统中,设计和使用一系列连贯的提示(prompts)来引导用户或AI通过多个步骤完成任务或获取信息的过程。这种方法在自然语言处理(NLP)和对话系统设计中尤其重要,因为它可以帮助系统更有效地理解和响应复杂的用户需求。

在设计多步提示时,需要考虑以下几个方面:

  • 上下文管理:系统需要能够理解和跟踪对话的上下文,以便提供相关的后续提示。
  • 用户意图识别:系统需要准确识别用户的意图,并根据意图提供相应的提示。
  • 灵活性和适应性:系统应该能够适应用户的不同回答,并灵活调整提示策略。
  • 用户体验:设计提示时要考虑用户体验,确保对话流畅自然,避免让用户感到困惑或沮丧。

假设我们现在已经获得了大模型分别利用自身能力、知识库、搜索引擎给出的解答,现在我们就可以构造出一个Prompt模板,来进行多步提示:

"mix_chat": """你是一个知无不言言无不尽的易学(周易)专家。先前我问了你一个易学方面的问题,你通过自身的能力、知识库检索以及搜索引擎检索的方式,给出了三个答案。\\n现在请你将这三个答案系统地整理成一篇针对原始问题的中文回答。\\n请你直接了当地给出回答,请一定不要添加任何诸如:\\n'根据您的要求,我将这三个答案系统地整理成一篇针对原始问题的中文回答。'、'好的,以下是xxx的回答’、'非常抱歉,我刚刚没有理解您的问题。'、'根据您的对话和我所掌握的资料,我为您整理了以下回答'等\\n这样与实际答案无关紧要的话!\\n此外,给出回答时,你一定不要重复原始问题!请务必记住,任何与答案正文无关的文本,均不要出现在回答中。\\n原始问题:\\n{question}\\n先前与你的对话如下:\\n{history}\\n你通过自身能力给出的解答如下:\\n{answer1}\\n你通过知识库检索给出的解答如下:\\n{answer2}\\n你通过搜索引擎检索给出的解答如下:\\n{answer3}\\n现在请你给出针对原始问题的中文回答。\\nAI:
"""
  1. 首先,我们告知大模型他的认知基础:你是一个知无不言言无不尽的易学(周易)专家。
  2. 其次,我们告知大模型上下文的metaData:先前我问了你一个易学方面的问题,你通过自身的能力、知识库检索以及搜索引擎检索的方式,给出了三个答案。
  3. 随后,我们规定,大模型给出的回答中,不得出现令实际用户迷惑的语句:例如 '根据您的要求,我将这三个答案系统地整理成一篇针对原始问题的中文回答。',因为用户原始的问题并没有**“三个问题”**。
  4. 我们把之前大模型三种机制下给出的解答附在对话中: 原始问题:\\n {question}\\n 先前与你的对话如下:\\n {history}\\n 你通过自身能力给出的解答如下:\\n {answer1}\\n 你通过知识库检索给出的解答如下:\\n {answer2}\\n 你通过搜索引擎检索给出的解答如下:\\n {answer3}\\n
  5. 最终,要求大模型给出解答:现在请你给出针对原始问题的中文回答。\\n

这就是一个MTPE在混合机制对话中的实际应用。

4.3. 接口实现

async def request_mix_chat(mc: MixChat) -> BaseResponse:"""混合对话1. 先请求大模型以自身能力给出解答2. 再请求大模型检索知识库给出解答3. 最后请求大模型通过询问搜索引擎给出解答4. 最终将解答融合在一起返回"""# 先请求大模型以自身能力给出解答llm_response = await request_llm_chat(LLMChat(query=mc.query, conv_id=mc.conv_id))if not llm_response["success"]:return BaseResponse(code=200, message="大模型请求失败", data={"error": f'{llm_response["error"]}'})# 请求知识库kb_response = await request_knowledge_base_chat(KBChat(query=mc.query, conv_id=mc.conv_id))if not kb_response["success"]:return BaseResponse(code=200, message="知识库请求失败", data={"error": f'{kb_response["error"]}'})# 请求搜索引擎search_response = await request_search_engine_chat(SEChat(query=mc.query, conv_id=mc.conv_id))if not search_response["success"]:return BaseResponse(code=200, message="搜索引擎请求失败", data={"error": f'{search_response["error"]}'})# 生成promptprompt = get_mix_chat_prompt(question=mc.query, history=await gen_history(mc.conv_id),answer1=llm_response["data"]["text"], answer2=kb_response["data"]["answer"],answer3="")# 请求大模型response = await request_llm_chat(LLMChat(query=prompt, conv_id=mc.conv_id, prompt_name=mc.prompt_name))# 确保问题和回答原子性地入库with record_lock:add_record_to_conversation(mc.conv_id, mc.query, False)add_record_to_conversation(mc.conv_id, response["data"]["text"], True)return BaseResponse(code=200, message="混合对话请求成功", data={"answer": response["data"]["text"]})
  1. 首先,请求大模型以自身能力给出解答
  2. 请求大模型根据知识库的知识给出解答
  3. 请求大模型根据搜索引擎的检索结果给出解答
  4. 根据prompt模板生成多步prompt
  5. 请求大模型根据该上下文信息综合性地给出解答
  6. 返回该最终解答

4.4. 混合机制对话测试

这里我问了大模型一个周易中“逆向格义”这个概念相关示例的问题:

他给出的解答如下:

历史上有哪些在日常生活中运用逆向格义的例子?逆向格义是一种思维方式,它强调从相反的角度来理解事物,从而得出更深刻的理解和解决问题的方法。在周易中,逆向格义被认为是一种有效的思维方式,可以帮助人们更全面地理解事物。以下是几个关于逆向格义的例子:1. 卦象分析:在周易中,每个卦象都代表了一种特定的元素、方向和能量。通过逆向格义,我们可以从相反的角度来分析卦象,从而得出更全面的含义。例如,乾卦代表天、刚强、积极等,如果我们将乾卦的内涵 reversed,它就变成了坤卦,象征地、柔弱、消极。这种分析方法可以帮助我们更全面地理解卦象所代表的意义。2. 爻辞解读:在周易的卦辞中,每一卦的爻(即阳爻和阴爻)都有特定的含义。通过逆向格义,我们可以从相反的角度来解读爻辞,从而得出更深刻的理解。例如,在一卦中,阳爻表示事物的发展,阴爻表示事物的衰退。如果我们将这个观念 reversed,那么阳爻就代表了事物的衰退,阴爻就代表了事物的发展。这种解读方法可以帮助我们更全面地理解爻辞所要传达的信息。3. 人事决策:在周易预测中,我们常常需要根据卦象来判断事物的发展趋势和解决方案。通过逆向格义,我们可以从相反的角度来分析卦象所代表的意义,从而得出更全面的解决方案。例如,如果卦象显示事物发展趋势不利,那么我们可以考虑采取相反的行动,如增加投资、增加风险等,从而避免不利的结果。4. 互传:在周易中,互传是一种特殊的卦象组合,它反映了事物之间的相互影响和变化。通过逆向格义,我们可以从互传中找到事物发展中的矛盾和问题,从而找到更好的解决方案。例如,在互传中,两个卦象相互影响,一个卦象代表了正面的力量,另一个卦象代表了负面的力量。我们可以通过逆向格义来理解互传中的矛盾,并找到解决问题的方法。这些例子说明,逆向格义在周易中的运用可以帮助我们更全面地理解事物的发展趋势和变化,从而更好地解决问题。这种思维方式不仅限于周易,还可以应用于其他领域,帮助我们更好地理解问题并找到更好的解决方案。

而中间过程给出的解答如下:

其中第一段是大模型自身能力的,第二段是知识库的(搜索引擎在我做实验的时候还不可用)

大模型发现知识库的知识偏向于商业应用而非周易,因此大部分的解答来自于第一段。当知识库的知识与对话的topic相关性更大之后,将会更多的融合知识库的知识到最终回答中。

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

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

相关文章

【设计模式】创建型-工厂方法模式

前言 工厂方法模式是一种经典的创建型设计模式&#xff0c;它提供了一种灵活的方式来创建对象实例。通过本文&#xff0c;我们将深入探讨工厂方法模式的概念、结构和应用。 一、什么是工厂方法模式 工厂方法模式是一种创建型设计模式&#xff0c;旨在解决对象的创建过程和客…

Parquet使用指南:一个超越CSV、提升数据处理效率的存储格式

前言 在大数据时代&#xff0c;数据存储和处理的效率越来越重要。同时&#xff0c;我们在工作中处理的数据也越来越多&#xff0c;从excel格式到csv格式&#xff0c;从文件文档传输到直接从数据库提取&#xff0c;数据单位也从K到M再到G。 当数据量达到了G以上&#xff0c;几…

ROS | 自动导航

保存&加载地图&#xff1a; image:地图文件 resolution:地图分辨率&#xff08;珊格地图&#xff09; origin&#xff1a;地图左下标 第三个参数是偏转角度 加载创建好的yaml文件&#xff1a; 年轻人第一次导航&#xff1a; 全局规划器&#xff1a; 代价地图设置参数&#…

K-means聚类模型入门介绍

K-means聚类是一种无监督学习方法&#xff0c;广泛应用于数据挖掘、机器学习和模式识别等领域&#xff0c;用于将数据集划分为K个簇&#xff08;cluster&#xff09;&#xff0c;其中每个簇的数据具有相似的特征。其基本思想是通过迭代寻找使簇内点间距离平方和最小的簇划分方式…

K8S-pod资源 探针

一.pod资源限制&#xff1a; 对pod资源限制原因&#xff1a;高并发占用所有的cpu资源、内存资源、会造成雪崩 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小&#xff0c;以及其他类型的资源。 方式&#xff1a; 对pod做…

UML-系统架构师(二)

1、UML&#xff08;Unified Modeling Language&#xff09;是面向对象设计的建设工具&#xff0c;独立于任何具体程序设计语言&#xff0c;以下&#xff08;&#xff09;不属于UML中的模型。 A用例图 B协作图 C活动图 DPAD图 解析&#xff1a; UML一共14种图 结构图&…

【蓝桥杯——物联网设计与开发】拓展模块2 - 电位器模块

一、电位器模块 &#xff08;1&#xff09;资源介绍 &#x1f505;原理图 蓝桥杯物联网竞赛实训平台提供了一个拓展接口 CN2&#xff0c;所有拓展模块均可直接安装在 Lora 终端上使用&#xff1b; 图1 拓展接口 电位器模块电路原理图如下所示&#xff1a; 图2 …

python数据分析——apply 2

参考资料&#xff1a;活用pandas库 1、向量化函数 使用apply时&#xff0c;可以按行或按列应用函数。如果想应用自定义的函数&#xff0c;必须重写它&#xff0c;因为整列或整行传递到了函数的第一个参数中。可以利用向量化函数和装饰器对所有函数进行向量化。对代码进行向量化…

再论任何图≌自己这一几何最最起码常识推翻平面公理

黄小宁 有了解析几何使人类对直线和射线的认识有革命性的飞跃。几何学有史2300年来一直认定起点和射出的方向都相同的射线必重合&#xff0c;任两异射线必有全等关系&#xff1b;解析几何使我发现这是2300年肉眼直观错觉。 h定理&#xff08;参考文献中的定理&#xff09;&am…

台式机安装ubuntu过程

1.单系统参考 20231210-超详细Ubuntu20.04单系统安装_台式机安装ubuntu系统-CSDN博客 2.双系统参考 双系统启动效果_哔哩哔哩_bilibili 安装前一定要先清空电脑的硬盘数据&#xff0c;不然可能会出现以下图片异常 意思估计是分区被占用了&#xff0c;出现这个问题 &#xff0…

安全基础二

一、插件漏洞 统计使用了哪些插件这些插件有版本更新嘛检测这些插件是否存在已知漏洞 二、权限提升和持久化 SSRF&#xff08;Server-Side Request Forgery&#xff0c;服务器端请求伪造&#xff09; 想象一下&#xff0c;你是一个公司的内部员工&#xff08;服务器&#x…

知攻善防应急响应靶机训练-Web2

前言&#xff1a; 本次应急响应靶机采用的是知攻善防实验室的Web-2应急响应靶机 靶机下载地址为&#xff1a; https://pan.quark.cn/s/4b6dffd0c51a 相关账户密码 用户:administrator 密码:Zgsfqq.com 解题过程&#xff1a; 一、攻击者的IP地址&#xff08;两个&#xff09;…

防火墙基础基础篇:NAT转发功能之——Easy IP方式详解

防火墙基础基础篇&#xff1a;NAT转发功能之——Easy IP方式详解 1. 概念 Easy IP 是一种简化版的动态NAPT&#xff08;Network Address and Port Translation&#xff09;技术。在Easy IP中&#xff0c;我们只使用一个公网IP地址&#xff0c;无需建立公有IP地址池。这个公网…

2024 年科技裁员综合清单

推荐阅读&#xff1a; 独立国家的共同财富 美国千禧一代的收入低于父辈 创造大量就业机会却毁掉了财富 这四件事是创造国家财富的关键 全球财富报告证实联盟自始至终无能 美国人已陷入无休止债务循环中&#xff0c;这正在耗尽他们的财务生命 2024 年&#xff0c;科技行业…

基于Java的高校学生勤工助学优派系统的设计与实现(论文+源码)_kaic

摘 要 高校勤工助学管理系统的出现&#xff0c;让学生的工作更加标准,不仅仅使高校办公室的办公水平以及管理水平大大提高&#xff0c;还优化了勤工助学资金的使用方式方法&#xff0c;完善了资助所需费用的资源配置&#xff0c;可以卓有成效地缩减学校的管理经费。本系统主…

《python编程从入门到实践》day40

# 昨日知识点回顾 编辑条目及创建用户账户 暂没能解决bug&#xff1a; The view learning_logs.views.edit_entry didnt return an HttpResponse object. It returned None instead.# 今日知识点学习 19.2.5 注销 提供让用户注销的途径 1.在base.html中添加注销链接 …

esp8266的rtos和nonos区别

https://bbs.espressif.com/viewtopic.php?t75242#p100294 https://blog.csdn.net/ydogg/article/details/72598752

Akamai 最新版逆向分析 akamai逆向 dhl网址

原创文章&#xff0c;请勿转载&#xff01; 本文内容仅限于安全研究&#xff0c;不公开具体源码。维护网络安全&#xff0c;人人有责。 URL&#xff08;base64加密处理&#xff09;&#xff1a;aHR0cHM6Ly93d3cuZGhsLmNvbS9jbi16aC9ob21lL3RyYWNraW5nL3RyYWNraW5nLWVjb21tZXJ…

Java | Leetcode Java题解之第115题不同的子序列

题目&#xff1a; 题解&#xff1a; class Solution {public int numDistinct(String s, String t) {int m s.length(), n t.length();if (m < n) {return 0;}int[][] dp new int[m 1][n 1];for (int i 0; i < m; i) {dp[i][n] 1;}for (int i m - 1; i > 0; …

计算机网络路由协议之内部网关协议RIP例题与详解

互联网的路由选择协议 路由器转发表的路由协议如何得出呢&#xff1f; 使用路由算法进行&#xff0c;路由算法可以分为两类&#xff1a; 静态路由选择策略和动态路由选择策略。 静态路由选择策略&#xff1a; 非自适应路由选择&#xff0c;人工配置每一条路由。 动态路由选…