Azure 机器学习 - 搜索中的检索增强 (RAG)

news2024/11/15 23:28:44

目录

  • 一、Azure AI 信息检索系统介绍
  • 二、采用 Azure AI 搜索的 RAG 方法
  • 三、适合 Azure AI 搜索的自定义 RAG 模式
  • 四、Azure AI 搜索中的可搜索内容
  • 五、Azure AI 搜索中的内容检索
    • 构建查询响应
    • 按相关性排名
    • 适用于 RAG 方案的 Azure AI 搜索查询的示例代码
  • 六、集成代码和 LLM
  • 七、如何开始使用

检索增强生成 (RAG) 是一种体系结构,通过添加提供数据的信息检索系统来增强大型语言模型 (LLM)(如 ChatGPT)的功能。 添加信息检索系统可在 LLM 规划响应时控制由其使用的数据。 对于企业解决方案,RAG 架构意味着你可以将自然语言处理限制为源自向量化文档、图像、音频和视频的企业内容。

关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人。

file

一、Azure AI 信息检索系统介绍

决定使用哪种信息检索系统至关重要,因为它将决定对 LLM 的输入。 信息检索系统应提供:

  • 按所需频率为所有内容进行大规模加载和刷新的索引策略。

  • 查询功能和相关性优化。 系统应以满足 LLM 输入的令牌长度要求所需的简短格式返回_相关_结果。

  • 数据和操作的安全性、全球影响力和可靠性。

  • 与 LLM 集成。

Azure AI 搜索是 RAG 体系结构中一种可靠的信息检索解决方案。 它提供索引和查询功能,并且具有 Azure 云的基础设施和安全性。 通过代码和其他组件,你可以设计一项全面的 RAG 解决方案,其中包括基于专有内容的生成式 AI 的所有元素。

二、采用 Azure AI 搜索的 RAG 方法

Microsoft 具有多个内置实施,用于在 RAG 解决方案中使用 Azure AI 搜索。

  • Azure AI Studio,[将数据用于 Azure OpenAI 服务]。 Azure AI Studio 与 Azure AI 搜索集成,用于进行存储和检索。 如果已有搜索索引,可以在 Azure AI Studio 中连接到它,并立即开始聊天。 如果没有索引,则可以使用 Studio,[通过上传数据来创建一个索引]。

  • Azure 机器学习,可用作[矢量存储]的搜索索引。 可以[在 Azure 机器学习提示流中创建矢量索引],该流使用 Azure AI 搜索服务进行存储和检索。

但是,如果需要自定义方法,则可以创建自己的自定义 RAG 解决方案。 本文的其余部分将探讨如何将 Azure AI 搜索融入自定义 RAG 解决方案。

三、适合 Azure AI 搜索的自定义 RAG 模式

该模式的高级摘要如下所示:

  • 从用户问题或请求(提示)开始。
  • 将其发送到 Azure AI 搜索以查找相关信息。
  • 将排名靠前的搜索结果发送到 LLM。
  • 使用 LLM 的自然语言理解和推理功能生成对初始提示的响应。

Azure AI 搜索提供 LLM 提示符的输入,但不训练模型。 在 RAG 体系结构中,没有额外的训练。 LLM 是使用公共数据预先训练的,但它会生成由检索器中的信息扩充的响应。

包含 Azure AI 搜索的 RAG 模式具有下图所示的元素。
file

  • 提供用户体验的应用 UX(Web 应用)
  • 应用服务器或协调器(集成和协调层)
  • Azure AI 搜索(信息检索系统)
  • Azure OpenAI(适用于生成式 AI 和 LLM)

Web 应用提供用户体验,其中提供演示文稿、上下文和用户交互。 用户的问题或提示从此处开始。 输入通过集成层,首先转到信息检索以获取搜索结果,还会转到 LLM 以设置上下文和意向。

应用服务器或业务流程协调程序是协调信息检索和 LLM 之间交接的集成代码。 一个选项是使用 LangChain 协调工作流。 LangChain 与 Azure AI 搜索集成,使你能够更轻松地将 Azure AI 搜索作为检索器包含在工作流中。

信息检索系统提供可搜索索引、查询逻辑和有效负载(查询响应)。 搜索索引可以包含向量或非向量内容。 尽管大多数示例和演示都包含向量字段,但这不是必要的。 查询使用 Azure AI 搜索中的现有搜索引擎执行,该搜索引擎可以处理关键字(或术语)和矢量查询。 该索引根据你定义的架构预先创建,并使用从文件、数据库或存储中获取的内容加载。

LLM 收到原始提示以及 Azure AI 搜索的结果。 LLM 分析结果并制定响应。 如果 LLM 为 ChatGPT,则用户交互可能是你来我往的对话。 如果使用 Davinci,则提示可能是完全组合的答案。 Azure 解决方案最有可能使用 Azure OpenAI,但对此特定服务没有硬性依赖。

Azure AI 搜索不提供原生 LLM 集成、Web 前端或矢量编码(嵌入),因此需要编写处理解决方案这些部分的代码。 可以查看演示源 (Azure-Samples/azure-search-openai-demo),了解完整解决方案的蓝图。

四、Azure AI 搜索中的可搜索内容

在 Azure AI 搜索中,所有可搜索内容都存储在云中的搜索服务所托管的搜索索引中。 搜索索引专为具有毫秒级响应时间的快速查询而设计,因此其内部数据结构旨在支持该目标。 为此,搜索索引将存储_索引内容_,而不是整个内容文件(如整个 PDF 或图像)。 在内部,数据结构包括标记化文本的倒排索引、嵌入的矢量索引,以及需要逐字匹配情况下的未更改文本(例如,在筛选器、模糊搜索、正则表达式查询中)。

为 RAG 解决方案设置数据时,可以使用在 Azure AI 搜索中创建和加载索引的功能。 索引包括复制或表示源内容的字段。 索引字段可能是简单的转移(源文档中的标题或描述成为搜索索引中的标题或描述),或者字段可能包含外部过程的输出,例如生成图像的表示形式或文本描述的矢量化处理或技术处理。

你可能知道你想要搜索哪种类型的内容,因此请考虑使用适合每种内容类型的索引功能:

内容类型已编制索引为功能
text令牌,未更改的文本索引器]可以从其他 Azure 资源(如 Azure 存储和 Cosmos DB)中拉取纯文本。 你还可以向索引[推送任何 JSON 内容]。 若要修改使用中的文本,请使用[分析器和[规范化器]在编制索引期间添加词法处理。 如果源文档是可能在查询中使用的丢失的术语,则[同义词映射]会非常有用。
text矢量 1文本可以在外部分块和矢量化,然后在你的索引中[作为矢量字段编制索引]。
图像令牌,未更改的文本 2OCR 和图像分析的[技能]可以处理图像以实现文本识别或图像特征。 图像信息转换为可搜索文本并添加到索引。 技能具有索引器要求。
图像矢量 1图像可以在外部矢量化以获得图像内容的数学表示形式,然后在你的索引中[作为矢量字段编制索引]。
视频矢量 1视频文件可以在外部矢量化以获得视频内容的数学表示形式,然后在你的索引中[作为矢量字段编制索引]。
audio矢量 1音频文件可以在外部矢量化以获得音频内容的数学表示形式,然后在你的索引中[作为矢量字段编制索引]。

1[矢量支持]以公共预览版提供。 目前,它要求调用其他库或模型进行数据分块和矢量化。 有关调用 Azure OpenAI 嵌入模型以矢量化内容和查询,并演示数据分块的示例,请参阅[此存储库]。

2[技能]是对 [AI 扩充]的内置支持。 为了进行 OCR 和图像分析,索引管道对 Azure AI 视觉 API 进行内部调用。 这些技能将提取的图像传递到 Azure AI 以进行处理,并接收输出作为由 Azure AI 搜索编制索引的文本。

矢量提供了对不同内容(多个文件格式和语言)的最佳适应性,因为内容以数学表示形式通用表达。 矢量还支持相似性搜索:在与矢量查询最相似的坐标上匹配。 与在标记化术语上匹配的关键字搜索(或术语搜索)相比,相似性搜索更加细致。 如果内容或查询中存在歧义或解释要求,这是更好的选择。

五、Azure AI 搜索中的内容检索

数据进入搜索索引后,就可以使用 Azure AI 搜索的查询功能来检索内容。

在非 RAG 模式中,查询从搜索客户端进行往返。 提交查询、在搜索引擎上执行查询,然后向客户端应用程序返回响应。 响应或搜索结果仅包含索引中找到的逐字匹配内容。

在 RAG 模式中,会在搜索引擎和 LLM 之间协调查询和响应。 用户的问题或查询会作为提示转发给搜索引擎和 LLM。 搜索结果从搜索引擎返回,然后重定向到 LLM。 返回给用户的响应是生成式 AI,即 LLM 的求和或答案。

Azure AI 搜索中没有(甚至语义搜索或矢量搜索也没有)任何查询类型可以构成新的答案。 只有 LLM 提供生成式 AI。 以下是 Azure AI 搜索中用于构建查询的功能:

查询功能目的使用原因
[简单或完整的 Lucene 语法]对文本和非矢量数值内容的查询执行全文搜索最适合精确匹配项,而不是相似匹配项。 全文搜索查询使用 [BM25 算法]排名,并支持通过计分概要文件进行相关性优化。 它还支持筛选器和 facet。
[筛选器]和 [facet]仅适用于文本或数字(非矢量)字段。 根据包含或排除条件减少搜索外围应用。提高查询的精准率。
[语义排名]使用语义模型对 BM25 结果集重新排名。 生成可用作 LLM 输入的简短描述文字和答案。比计分概要文件更简单,根据你的内容,对相关性优化来说是更可靠的方法。
[矢量搜索]对矢量字段执行查询以实现相似性搜索,其中查询字符串是一个或多个矢量。矢量可以用任何语言表示所有类型的内容。
[混合搜索]合并了以上任意或所有查询技术。 矢量查询和非矢量查询并行执行,并在统一的结果集中返回。在精确度和召回率方面取得的最显著的增益是通过混合查询实现的。

构建查询响应

查询的响应向 LLM 提供输入,因此搜索结果的质量是决定成功与否的关键因素。 结果为表格行集。 结果的构成或结构取决于:

  • 用于确定响应中包含索引部分的字段。
  • 表示索引匹配项的行。

当属性“可检索”时,字段将显示在搜索结果中。 索引架构中的字段定义具有属性,这些属性确定字段是否在响应中使用。 仅在全文或矢量查询结果中返回“可检索”字段。 默认情况下,将返回所有“可检索”字段,但可以使用“选择”指定子集。 除了“可检索”之外,该字段没有限制。 字段可以是任意长度或类型。 对于长度,Azure AI 搜索中没有最大字段长度限制,但 [API 请求的大小]有限制。

行与查询匹配,按相关性、相似性或两者设置排名。 默认情况下,全文搜索的结果限制为前 50 个匹配项,矢量搜索限制为前 50 个 k 最近邻匹配项。 可以更改默认值,以增加或减少最多 1,000 个文档的限制。 还可以使用top 和skip 分页参数将结果检索为一系列分页结果。

按相关性排名

处理复杂流程、大量数据和预期的毫秒级响应时,每个步骤都必须增加价值并提高最终结果的质量,这一点至关重要。 在信息检索方面,_相关性优化_活动可以提高发送给 LLM 的结果的质量。 结果中应尽包含最相关或最相似的匹配文档。

相关性适用于关键字(非矢量)搜索和混合查询(基于非矢量字段)。 在 Azure AI 搜索中,对相似性搜索和矢量查询没有相关性优化。 [BM25 排名]是全文搜索的排名算法。

通过增强 BM25 排名的功能支持相关性优化。 这些方法包括:

  • [计分概要文件],如果在特定搜索字段或其他条件中找到匹配项,可提高搜索分数。
  • 对 BM25 结果集重新排名的[语义排名],使用来自必应的语义模型对结果重新排序,以获得适合原始查询的更好语义。

在比较和基准测试中,包含文本和矢量字段的混合查询(与 BM25 排名结果的语义排名相补充)会产生最相关的结果。

适用于 RAG 方案的 Azure AI 搜索查询的示例代码

以下代码是从演示站点中的 retrievethenread.py 文件复制的。 它从混合查询搜索结果中为 LLM 生成 content。 可以编写更简单的查询,但此示例包含带有语义重新排名和拼写检查的矢量搜索和关键字搜索。 在演示中,此查询用于获取初始内容。

# Use semantic ranker if requested and if retrieval mode is text or hybrid (vectors + text)
if overrides.get("semantic_ranker") and has_text:
    r = await self.search_client.search(query_text,
                                  filter=filter,
                                  query_type=QueryType.SEMANTIC,
                                  query_language="en-us",
                                  query_speller="lexicon",
                                  semantic_configuration_name="default",
                                  top=top,
                                  query_caption="extractive|highlight-false" if use_semantic_captions else None,
                                  vector=query_vector,
                                  top_k=50 if query_vector else None,
                                  vector_fields="embedding" if query_vector else None)
else:
    r = await self.search_client.search(query_text,
                                  filter=filter,
                                  top=top,
                                  vector=query_vector,
                                  top_k=50 if query_vector else None,
                                  vector_fields="embedding" if query_vector else None)
if use_semantic_captions:
    results = [doc[self.sourcepage_field] + ": " + nonewlines(" . ".join([c.text for c in doc['@search.captions']])) async for doc in r]
else:
    results = [doc[self.sourcepage_field] + ": " + nonewlines(doc[self.content_field]) async for doc in r]
content = "\n".join(results)

六、集成代码和 LLM

包含 Azure AI 搜索的 RAG 解决方案需要其他组件和代码才能创建完整的解决方案。 前面的部分介绍了如何通过 Azure AI 搜索进行信息检索以及使用哪些功能来创建和查询可搜索内容,本部分将介绍 LLM 集成和交互。

演示存储库中的笔记本是一个很好的起点,因为它们显示了将搜索结果传递到 LLM 的模式。 RAG 解决方案中的大多数代码都由对 LLM 的调用组成,因此你需要了解这些 API 的工作原理,但本文并未涵盖这些内容。

chat-read-retrieve-read.ipynb 笔记本中的以下单元格块显示聊天会话上下文中的搜索调用:

# Execute this cell multiple times updating user_input to accumulate chat history
user_input = "Does my plan cover annual eye exams?"

# Exclude category, to simulate scenarios where there's a set of docs you can't see
exclude_category = None

if len(history) > 0:
    completion = openai.Completion.create(
        engine=AZURE_OPENAI_GPT_DEPLOYMENT,
        prompt=summary_prompt_template.format(summary="\n".join(history), question=user_input),
        temperature=0.7,
        max_tokens=32,
        stop=["\n"])
    search = completion.choices[0].text
else:
    search = user_input

# Alternatively simply use search_client.search(q, top=3) if not using semantic ranking
print("Searching:", search)
print("-------------------")
filter = "category ne '{}'".format(exclude_category.replace("'", "''")) if exclude_category else None
r = search_client.search(search, 
                         filter=filter,
                         query_type=QueryType.SEMANTIC, 
                         query_language="en-us", 
                         query_speller="lexicon", 
                         semantic_configuration_name="default", 
                         top=3)
results = [doc[KB_FIELDS_SOURCEPAGE] + ": " + doc[KB_FIELDS_CONTENT].replace("\n", "").replace("\r", "") for doc in r]
content = "\n".join(results)

prompt = prompt_prefix.format(sources=content) + prompt_history + user_input + turn_suffix

completion = openai.Completion.create(
    engine=AZURE_OPENAI_CHATGPT_DEPLOYMENT, 
    prompt=prompt, 
    temperature=0.7, 
    max_tokens=1024,
    stop=["<|im_end|>", "<|im_start|>"])

prompt_history += user_input + turn_suffix + completion.choices[0].text + "\n<|im_end|>" + turn_prefix
history.append("user: " + user_input)
history.append("assistant: " + completion.choices[0].text)

print("\n-------------------\n".join(history))
print("\n-------------------\nPrompt:\n" + prompt)

七、如何开始使用

  • [使用 Azure AI Studio 和“自带数据”]来试验现有搜索索引上的提示。 此步骤可帮助你确定要使用的模型,并演示如何在 RAG 方案中使用现有索引。

  • “与数据聊天”解决方案加速器,创建自己的 RAG 解决方案。

  • 查看 azure-search-openai-demo 演示,了解包含 Azure AI 搜索的有效 RAG 解决方案,并研究生成体验的代码。 此演示对其数据使用虚构的 Northwind 健康状况计划。

    下面是来自 Azure OpenAI 团队的类似的端到端演示。 此演示使用非结构化 .pdf 数据,其中包含 Microsoft Surface 设备上的公开可用文档。

  • [查看索引概念和策略]以确定引入和刷新数据的方式。 决定是使用矢量搜索、关键字搜索,还是混合搜索。 需要搜索的内容类型以及要运行的查询类型将决定索引设计。

  • [查看创建查询],以了解更多搜索请求语法和要求。

关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人。

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

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

相关文章

时间序列预测实战(十七)PyTorch实现LSTM-GRU模型长期预测并可视化结果(附代码+数据集+详细讲解)

一、本文介绍 本文给大家带来的实战内容是利用PyTorch实现LSTM-GRU模型&#xff0c;LSTM和GRU都分别是RNN中最常用Cell之一&#xff0c;也都是时间序列预测中最常见的结构单元之一&#xff0c;本文的内容将会从实战的角度带你分析LSTM和GRU的机制和效果&#xff0c;同时如果你…

Three.js相机模拟

有没有想过如何在 3D Web 应用程序中模拟物理相机? 在这篇博文中,我将向你展示如何使用 Three.js和 OpenCV 来完成此操作。 我们将从模拟针孔相机模型开始,然后添加真实的镜头畸变。 具体来说,我们将仔细研究 OpenCV 的两个失真模型,并使用后处理着色器复制它们。 拥有逼…

电子学会C/C++编程等级考试2022年06月(一级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:倒序输出 依次输入4个整数a、b、c、d,将他们倒序输出,即依次输出d、c、b、a这4个数。 时间限制:1000 内存限制:65536输入 一行4个整数a、b、c、d,以空格分隔。 0 < a,b,c,d < 108输出 一行4个整数d、c、b、a,整数之…

Java自动化驱动浏览器搜索稻香

下载最新的Chrome浏览器 查看chrome版本&#xff0c;在浏览器地址栏输入&#xff1a;chrome://version/ 下载对应的浏览器驱动&#xff0c;将其放到一个目录中&#xff0c;我放到了D:/chromedriver-win64 导入对应的依赖【注意&#xff1a;不要导入最新的版本&#xff0c;最…

算法 LeetCode 题解 | 两个数组的交集

大家好&#xff0c;我是木川 一、题目描述 给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 示例 1&#xff1a; 输入&#xff1a;nums1 [1,2,2,1], nums2 [2,2] 输出&#xff1a;[2] 示例…

C/C++最大质因子 2021年12月电子学会中小学生软件编程(C/C++)等级考试一级真题答案解析

目录 C/C最大质因子 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C最大质因子 一、题目要求 1、编程实现 质因子是指能整除给定正整数的质数。而最大质因子是指一个整数的所有质因子中最大的那个。…

【mediasoup】TransportCongestionControlClient 1: 代码走读

TransportCongestionControlClient 基于m77版本的libwebrtc ,但是TransportCongestionControlClient 并不是libwebrt中的,是mediasoup自己封装实现:TransportCongestionControlClient 用于发送端D:\XTRANS\soup\mediasoup-sfu-cpp\worker\src\RTC\TransportCongestionContro…

小黑子的SSM整合

SSM整合 一、基于restful页面数据交互1.1 后台接口开发1.2 页面访问处理 二、ssm整合2.1 流程分析2.2 整合配置2.3 功能模块开发2.4 接口测试2.5 表现层与前端数据传输协议定义2.5.1 协议实现 2.6 异常处理器2.6.1 RestControllerAdvice2.6.2 ExceptionHandler2.6.3 项目异常处…

DBeaver连接本地MySQL

原文&#xff1a; DBeaver21.3.0安装与连接本地MySQL_dbeaver创建本地数据库_傅大胖的博客-CSDN博客 其他&#xff1a; mysql 的驱动下载地址&#xff1a; Central Repository: mysql/mysql-connector-java ​​​​​​​

江湖再见,机器视觉兄弟们,我已经提离职了,聪明的机器视觉工程师,离职不亏本!

我闻江湖已叹息&#xff0c;又闻人间繁闹闹。同为布衣沦落人&#xff0c;相逢何必曾相识。 此生谁料事事休&#xff0c;道不尽人情冷暖&#xff0c;聚散离合总平常&#xff0c;不似勇气少年时。 我估计今年公司年底是发不出工资了&#xff0c;因为订单续不上。年终奖更是没有&…

Element Plus框架快速上手详解(一)

Element Plus框架快速上手详解 1、Element Plus1.1、安装 2、Button3、Link链接4、Layout布局5、Container布局容器6、Radio单选框6.1、单选框组6.2、事件 7、Checkbox多选框7.1、多选框组7.2、事件 8、Input输入框组件8.1、事件8.2、方法 9、Select选择器9.1、基础多选9.2、事…

机器学习二元分类 二元交叉熵 二元分类例子

二元交叉熵损失函数 深度学习中的二元分类损失函数通常采用二元交叉熵&#xff08;Binary Cross-Entropy&#xff09;作为损失函数。 二元交叉熵损失函数的基本公式是&#xff1a; L(y, y_pred) -y * log(y_pred) - (1 - y) * log(1 - y_pred)其中&#xff0c;y是真实标签&…

HarmonyOS开发(四):UIAbility组件

1、UIAbility概述 UIAbility 一种包含用户界面的应用组件用于与用户进行交互系统调度的单元为应用提供窗口在其中绘制界同 注&#xff1a;每一个UIAbility实例&#xff0c;都对应一个最近任务列表中的任务。 一个应用可以有一个UIAbility也可以有多个UIAbility。 如一般的…

【算法】二分查找-20231121

这里写目录标题 一、344. 反转字符串二、392. 判断子序列三、581. 最短无序连续子数组四、680. 验证回文串 II 一、344. 反转字符串 提示 简单 865 相关企业 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组…

(动手学习深度学习)第13章 实战kaggle竞赛:CIFAR-10

导入相关库 import collections import math import os import shutil import pandas as pd import torch import torchvision from torch import nn from d2l import torch as d2l下载数据集 d2l.DATA_HUB[cifar10_tiny] (d2l.DATA_URL kaggle_cifar10_tiny.zip,2068874e4…

内存学习(4):内存分类与常用概念3(ROM)

1 ROM介绍 ROM即为只读存储器&#xff0c;全拼是Read Only Memory。 1.1 “只读”的由来 ROM叫只读存储器是因为最早的ROM&#xff08;MROM&#xff09;确实是只能读取不能写入&#xff0c;一旦出厂不能再写&#xff0c;需要在出厂之前预设好它的数据&#xff0c;并且它是掉…

华为---OSPF网络虚连接(Virtual Link)简介及示例配置

OSPF网络虚连接&#xff08;Virtual Link&#xff09;简介 为了避免区域间的环路&#xff0c;OSPF规定不允许直接在两个非骨干区域之间发布路由信息&#xff0c;只允许在一个区域内部或者在骨干区域和非骨干区域之间发布路由信息。因此&#xff0c;每个ABR都必须连接到骨干区域…

Fourier分析导论——第6章——R^d 上的Fourier变换(E.M. Stein R. Shakarchi)

第6章 上的 Fourier 变换 It occurred to me that in order to improve treatment planning one had to know the distribution of the at- tenuation coefficient of tissues in the body. This in- formation would be useful for diagnostic purposes and would con…

[github配置] 远程访问仓库以及问题解决

作者&#xff1a;20岁爱吃必胜客&#xff08;坤制作人&#xff09;&#xff0c;近十年开发经验, 跨域学习者&#xff0c;目前于新西兰奥克兰大学攻读IT硕士学位。荣誉&#xff1a;阿里云博客专家认证、腾讯开发者社区优质创作者&#xff0c;在CTF省赛校赛多次取得好成绩。跨领域…

密码加密解密之路

1.背景 做数据采集&#xff0c;客户需要把他们那边的数据库连接信息存到我们系统里&#xff0c;那我们系统就要尽可能的保证这部分数据安全&#xff0c;不被盗。 2.我的思路 1.需要加密的地方有两处&#xff0c;一个是新增的时候前端传给后端的时候&#xff0c;一个是存到数…