LLM之RAG实战(九)| 高级RAG 03:多文档RAG体系结构

       在RAG(检索和生成)这样的框架内管理和处理多个文档有很大的挑战。关键不仅在于提取相关内容,还在于选择包含用户查询所寻求的信息的适当文档。基于用户查询对齐的多粒度特性,需要动态选择文档,本文将介绍结构化层次检索来解决多文档RAG问题。

一、Llamaindex结构化检索介绍

        Llamaindex支持多层次信息检索。它不只是筛选文档,而是利用元数据过滤来简化选择过程。通过使用自动检索机制,这些过滤器可以根据用户查询检索出最相关的文档。这个过程包括推断语义查询,在矢量数据库中确定最佳过滤器集,有效地将文本到SQL和语义搜索的能力结合起来。

二、结构化层次检索的优点

下面介绍Llamaindex提供的结构化分层检索的一些好处:

  1. 增强相关性:通过利用元数据驱动的过滤器,可以准确地识别和检索符合用户查询细微要求的文档。这确保了内容选择中更高的相关性和准确性;

  2. 动态文档选择:与传统的静态文档检索是不同,Llamaindex支持动态文档选择。Llamaindex通过根据相关文档的属性和结构化元数据灵活选择相关文档,智能地适应不同的用户查询;

  3. 高效信息检索:结构化层次检索显著提高了信息检索的效率。通过将文档预处理到元数据字典中并将其存储在矢量数据库中,该系统简化了检索过程,最大限度地减少了计算开销并优化了搜索效率;

  4. 语义查询优化:文本到SQL和语义搜索的融合使系统能够更好地理解用户意图。Llamaindex的自动检索机制将用户查询细化为语义结构,从而能够从文档存储库中精确而细致地检索信息。

三、结构化层次检索代码实现

       下面使用Python代码来展示Llamaindex的基本概念,并实现一个结构化的分层检索系统。使用Llamaindex类初始化来管理矢量数据库中的文档元数据。

  • 文档添加add_document方法通过创建包含摘要和关键字等关键信息的元数据字典,将文档添加到Llamaindex;
  • 检索逻辑retrieve_documents方法通过将用户查询与矢量数据库中的元数据过滤器进行匹配来处理用户查询。为了演示目的,使用了一个基本的模拟匹配逻辑;
  • 匹配机制match_metadata方法模拟用户查询和文档元数据之间的匹配过程。这是一个简化的演示逻辑,通常会使用更高级的NLP或语义分析技术。

      本示例旨在说明Llamaindex的核心概念,展示如何通过Python中的简化实现来存储文档元数据并基于用户查询检索相关文档。

步骤1:安装库

!pip install llama-index wandb llama_hub weaviate-client --quiet

步骤2:导入库

import osimport openaiimport loggingimport sysfrom IPython.display import Markdown, displayfrom llama_index.llms import OpenAIfrom llama_index.callbacks import CallbackManager, WandbCallbackHandlerfrom llama_index import load_index_from_storageimport pandas as pdfrom llama_index.query_engine import PandasQueryEnginefrom pprint import pprintfrom llama_index import (    VectorStoreIndex,    SimpleKeywordTableIndex,    SimpleDirectoryReader,    StorageContext,    ServiceContext,)import nest_asyncionest_asyncio.apply()#Setup  OPEN API Keyos.environ["OPENAI_API_KEY"] = ""# openai_key = "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" #<--- Your API KEY# openai.api_key = openai_keylogging.basicConfig(stream=sys.stdout, level=logging.INFO)logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))# initialise WandbCallbackHandler and pass any wandb.init argswandb_args = {"project":"llama-index-report"}wandb_callback = WandbCallbackHandler(run_args=wandb_args)# pass wandb_callback to the service contextcallback_manager = CallbackManager([wandb_callback])service_context = ServiceContext.from_defaults(llm=OpenAI(model="gpt-3.5-turbo-0613", temperature=0), chunk_size=1024, callback_manager=callback_manager)

步骤3:下载Github issues

os.environ["GITHUB_TOKEN"] = ""from llama_hub.github_repo_issues import (    GitHubRepositoryIssuesReader,    GitHubIssuesClient,)github_client = GitHubIssuesClient()loader = GitHubRepositoryIssuesReader(    github_client,    owner="run-llama",    repo="llama_index",    verbose=True,)orig_docs = loader.load_data()limit = 100docs = []for idx, doc in enumerate(orig_docs):    doc.metadata["index_id"] = doc.id_    if idx >= limit:        break    docs.append(doc)# OutputFound 100 issues in the repo page 1Resulted in 100 documentsFound 100 issues in the repo page 2Resulted in 200 documentsFound 100 issues in the repo page 3Resulted in 300 documentsFound 8 issues in the repo page 4Resulted in 308 documentsNo more issues found, stopping
from copy import deepcopyimport asynciofrom tqdm.asyncio import tqdm_asynciofrom llama_index import SummaryIndex, Document, ServiceContextfrom llama_index.llms import OpenAIfrom llama_index.async_utils import run_jobsasync def aprocess_doc(doc, include_summary: bool = True):    """Process doc."""    print(f"Processing {doc.id_}")    metadata = doc.metadata    date_tokens = metadata["created_at"].split("T")[0].split("-")    year = int(date_tokens[0])    month = int(date_tokens[1])    day = int(date_tokens[2])    assignee = (        "" if "assignee" not in doc.metadata else doc.metadata["assignee"]    )    size = ""    if len(doc.metadata["labels"]) > 0:        size_arr = [l for l in doc.metadata["labels"] if "size:" in l]        size = size_arr[0].split(":")[1] if len(size_arr) > 0 else ""    new_metadata = {        "state": metadata["state"],        "year": year,        "month": month,        "day": day,        "assignee": assignee,        "size": size,        "index_id": doc.id_,    }    # now extract out summary    summary_index = SummaryIndex.from_documents([doc])    query_str = "Give a one-sentence concise summary of this issue."    query_engine = summary_index.as_query_engine(        service_context=ServiceContext.from_defaults(            llm=OpenAI(model="gpt-3.5-turbo")        )    )    summary_txt = str(query_engine.query(query_str))    new_doc = Document(text=summary_txt, metadata=new_metadata)    return new_docasync def aprocess_docs(docs):    """Process metadata on docs."""    new_docs = []    tasks = []    for doc in docs:        task = aprocess_doc(doc)        tasks.append(task)    new_docs = await run_jobs(tasks, show_progress=True, workers=5)    # new_docs = await tqdm_asyncio.gather(*tasks)    return new_docsnew_docs = await aprocess_docs(docs)# OutputProcessing 9398Processing 9427Processing 9613Processing 9417Processing 9612Processing 8832Processing 9609Processing 9353Processing 9431Processing 9426Processing 9425Processing 9435Processing 9419Processing 9571Processing 9373Processing 9383Processing 9408Processing 9405Processing 9372Processing 9546Processing 9565Processing 9664Processing 9560Processing 9470Processing 9343Processing 9518Processing 9358Processing 8536Processing 9385Processing 9380Processing 9510Processing 9352Processing 9368Processing 7457Processing 8893Processing 9583Processing 9312Processing 7720Processing 9219Processing 9481Processing 9469Processing 9655Processing 9477Processing 9670Processing 9475Processing 9667Processing 9665Processing 9348Processing 9471Processing 9342Processing 9488Processing 9338Processing 9523Processing 9416Processing 7726Processing 9522Processing 9652Processing 9520Processing 9651Processing 7244Processing 9650Processing 9519Processing 9649Processing 9492Processing 9603Processing 9509Processing 9269Processing 9491Processing 8802Processing 9525Processing 9611Processing 9543Processing 8551Processing 9627Processing 9450Processing 9658Processing 9421Processing 9394Processing 9653Processing 9439Processing 9604Processing 9413Processing 9507Processing 9625Processing 9490Processing 9626Processing 9483Processing 9638Processing 7744Processing 9472Processing 8475Processing 9244Processing 9618100%|██████████| 100/100 [02:07<00:00,  1.27s/it]

步骤4:将数据加载到Weaviate Vector Store

from llama_index.vector_stores import WeaviateVectorStorefrom llama_index.storage import StorageContextfrom llama_index import VectorStoreIndeximport weaviate# cloudauth_config = weaviate.AuthApiKey(api_key="")client = weaviate.Client(    "https://<weaviate-cluster>.weaviate.network",    auth_client_secret=auth_config,)class_name = "LlamaIndex_auto"vector_store = WeaviateVectorStore(    weaviate_client=client, index_name=class_name)storage_context = StorageContext.from_defaults(vector_store=vector_store)# Since "new_docs" are concise summaries, we can directly feed them as nodes into VectorStoreIndexindex = VectorStoreIndex(new_docs, storage_context=storage_context)docs[0].metadata# Output{'state': 'open', 'created_at': '2023-12-21T20:18:03Z', 'url': 'https://api.github.com/repos/run-llama/llama_index/issues/9655', 'source': 'https://github.com/run-llama/llama_index/pull/9655', 'labels': ['size:L'], 'index_id': '9655'}

步骤5:对原始文档建立Weaviate Index

vector_store = WeaviateVectorStore(    weaviate_client=client, index_name=doc_class_name)storage_context = StorageContext.from_defaults(vector_store=vector_store)doc_index = VectorStoreIndex.from_documents(    docs, storage_context=storage_context)

步骤6:建立自动检索机制

自动检索器的设置过程通过分为以下几个关键步骤:

  1. 定义Schema:定义向量数据库模式,包括元数据字段;

  2. VectorIndexAutoRetriever初始化:实例化此类将创建一个利用压缩元数据索引的检索器。需要定义的Schema作为其输入;

  3. 创建Wrapper Retriever:该步骤主要将每个节点后处理为IndexNode。此转换包含一个链接回源文档的索引ID,此链接支持在后面的部分中进行递归检索,依靠IndexNode对象与下游检索器、查询引擎或其他节点连接。

6(a)定义Schema

from llama_index.vector_stores.types import MetadataInfo, VectorStoreInfovector_store_info = VectorStoreInfo(    content_info="Github Issues",    metadata_info=[        MetadataInfo(            name="state",            description="Whether the issue is `open` or `closed`",            type="string",        ),        MetadataInfo(            name="year",            description="The year issue was created",            type="integer",        ),        MetadataInfo(            name="month",            description="The month issue was created",            type="integer",        ),        MetadataInfo(            name="day",            description="The day issue was created",            type="integer",        ),        MetadataInfo(            name="assignee",            description="The assignee of the ticket",            type="string",        ),        MetadataInfo(            name="size",            description="How big the issue is (XS, S, M, L, XL, XXL)",            type="string",        ),    ],)

6(b)实例化 VectorIndexAutoRetriever

from llama_index.retrievers import VectorIndexAutoRetrieverretriever = VectorIndexAutoRetriever(    index,    vector_store_info=vector_store_info,    similarity_top_k=2,    empty_query_top_k=10,  # if only metadata filters are specified, this is the limit    verbose=True,)
nodes = retriever.retrieve("Tell me about some issues on 12/11")print(f"Number retrieved: {len(nodes)}")print(nodes[0].metadata)# OutputUsing query str: Using filters: [('month', '==', 12), ('day', '==', 11)]Number retrieved: 6{'state': 'open', 'year': 2023, 'month': 12, 'day': 11, 'assignee': '', 'size': 'XL', 'index_id': '9431'}

6(c)定义Wrapper Retriever

from llama_index.retrievers import BaseRetrieverfrom llama_index.indices.query.schema import QueryBundlefrom llama_index.schema import IndexNode, NodeWithScoreclass IndexAutoRetriever(BaseRetriever):    """Index auto-retriever."""    def __init__(self, retriever: VectorIndexAutoRetriever):        """Init params."""        self.retriever = retriever    def _retrieve(self, query_bundle: QueryBundle):        """Convert nodes to index node."""        retrieved_nodes = self.retriever.retrieve(query_bundle)        new_retrieved_nodes = []        for retrieved_node in retrieved_nodes:            index_id = retrieved_node.metadata["index_id"]            index_node = IndexNode.from_text_node(                retrieved_node.node, index_id=index_id            )            new_retrieved_nodes.append(                NodeWithScore(node=index_node, score=retrieved_node.score)            )        return new_retrieved_nodesindex_retriever = IndexAutoRetriever(retriever=retriever)

步骤7:建立递归检索机制

       这种类型的检索器将检索器的每个节点连接到另一个检索器、查询引擎或节点。该设置包括将每个汇总的元数据节点链接到与相应文档对应的RAG管道对齐的检索器。

配置过程如下:

  1. 为每个文档定义一个检索器,并把他们添加到字典中;

  2. 定义递归检索器:在参数中定义包括root检索器(汇总元数据检索器)和其他文档检索器。

from llama_index.vector_stores.types import (    MetadataFilter,    MetadataFilters,    FilterOperator,)retriever_dict = {}query_engine_dict = {}for doc in docs:    index_id = doc.metadata["index_id"]    # filter for the specific doc id    filters = MetadataFilters(        filters=[            MetadataFilter(                key="index_id", operator=FilterOperator.EQ, value=index_id            ),        ]    )    retriever = doc_index.as_retriever(filters=filters)    query_engine = doc_index.as_query_engine(filters=filters)    retriever_dict[index_id] = retriever    query_engine_dict[index_id] = query_engine
from llama_index.retrievers import RecursiveRetriever# note: can pass `agents` dict as `query_engine_dict` since every agent can be used as a query enginerecursive_retriever = RecursiveRetriever(    "vector",    retriever_dict={"vector": index_retriever, **retriever_dict},    # query_engine_dict=query_engine_dict,    verbose=True,)nodes = recursive_retriever.retrieve("Tell me about some issues on 12/11")print(f"Number of source nodes: {len(nodes)}")nodes[0].node.metadata# OutputRetrieving with query id None: Tell me about some issues on 12/11Using query str: Using filters: [('month', '==', 12), ('day', '==', 11)]Retrieved node with id, entering: 9431Retrieving with query id 9431: Tell me about some issues on 12/11Retrieving text node: Dev awiss# DescriptionTry to use clickhouse as vectorDB.Try to chunk docs with independent parser service.Special designed schema and tricks for better query and retriever. Fixes # (issue)## Type of ChangePlease delete options that are not relevant.- [ ] Bug fix (non-breaking change which fixes an issue)- [ ] New feature (non-breaking change which adds functionality)- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)- [ ] This change requires a documentation update# How Has This Been Tested?Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration- [ ] Added new unit/integration tests- [ ] Added new notebook (that tests end-to-end)- [ ] I stared at the code and made sure it makes sense# Suggested Checklist:- [ ] I have performed a self-review of my own code- [ ] I have commented my code, particularly in hard-to-understand areas- [ ] I have made corresponding changes to the documentation- [ ] I have added Google Colab support for the newly added notebooks.- [ ] My changes generate no new warnings- [ ] I have added tests that prove my fix is effective or that my feature works- [ ] New and existing unit tests pass locally with my changes- [ ] I ran `make format; make lint` to appease the lint godsRetrieved node with id, entering: 9435Retrieving with query id 9435: Tell me about some issues on 12/11Retrieving text node: [Bug]: [nltk_data] Error loading punkt: <urlopen error [WinError 10060] A### Bug DescriptionI am using a vector Index which connects to a chromaDB client as my database. I have initialized the index as a chat engine. When the query the chat engine, two things happen:1. The response time is nearly 2-3mins.2. It throws the below warning```[nltk_data] Error loading punkt: <urlopen error [WinError 10060] A[nltk_data]     connection attempt failed because the connected party[nltk_data]     did not properly respond after a period of time, or[nltk_data]     established connection failed because connected host[nltk_data]     has failed to respond>```### Version0.9.8.post1### Steps to ReproduceClone, setup and run the below repository: (Follow readme for instructions)https://github.com/umang299/document-gpt### Relevant Logs/Tracbacks_No response_Retrieved node with id, entering: 9426Retrieving with query id 9426: Tell me about some issues on 12/11Retrieving text node: Slack Loader with large lack channels### Question Validation- [X] I have searched both the documentation and discord for an answer.### QuestionHi team,I am using the [Slack Loader ](https://llamahub.ai/l/slack)from Llama Hub. For smaller Slack channels it works fine. However, for larger channels with lots of messages created over months, I keep seeing this message:`Rate limit error reached, sleeping for: 10 seconds`Is there a recommended / idiomatic way to load larger Slack channels to avoid this issue?Retrieved node with id, entering: 9425Retrieving with query id 9425: Tell me about some issues on 12/11Retrieving text node: [Feature Request]: Make llama-index compartible with models finetuned and hosted on modal.com### Feature DescriptionModal.com is a cloud computing service that allows you to finetune and host models on their workers. They provide inference points for any models finetuned on their platform.### ReasonI have not tried implementing the feature. I just read about the capabilities on modal.com and thought it would be a good integration feature for llama-index to allow for more configuration.### Value of FeatureAn integration feature to allow users who host their models on modal to use llama-index for their RAG and prompt engineering pipelines.Retrieved node with id, entering: 9439Retrieving with query id 9439: Tell me about some issues on 12/11Retrieving text node: [Bug]: Metadata filter not working with Elastic search indexing ### Bug DescriptionWhile retrieving from ES with multiple metadatafilter condition(OR/AND) its not taking it into account. It always performs an AND operation even if its explicitly mentioned OR.Example below code should filter and retrieve only 'mafia' or "Stephen King" bit its not doing as expected.filters = MetadataFilters(    filters=[        MetadataFilter(key="theme", value="Mafia"),        MetadataFilter(key="author", value="Stephen King"),    ],    condition=FilterCondition.OR,)retriever = index.as_retriever(filters=filters)### Version0.9.13### Steps to Reproducenodes = [TextNode(text="The Shawshank Redemption",metadata={"author": "Stephen King","theme": "Friendship",},),TextNode(text="The Godfather",metadata={"director": "Francis Ford Coppola","theme": "Mafia",},),TextNode(text="Inception",metadata={"director": "Christopher Nolan",},),]filters = MetadataFilters(    filters=[        MetadataFilter(key="theme", value="Mafia"),        MetadataFilter(key="author", value="Stephen King"),    ],    condition=FilterCondition.OR,)retriever = index.as_retriever(filters=filters)### Relevant Logs/Tracbacks_No response_Retrieved node with id, entering: 9427Retrieving with query id 9427: Tell me about some issues on 12/11Retrieving text node: [Feature Request]: Postgres BM25 support### Feature DescriptionFeature: add a variation of PGVectorStore which uses ParadeDB's BM25 extension.BM25 is now possible in Postgres with a Rust extension [pg_bm25): https://github.com/paradedb/paradedb/tree/dev/pg_bm25Unsure if it might be better to use [pg_search](https://github.com/paradedb/paradedb/tree/dev/pg_search) and get HNSW at the same time..I'm interested in contributing on this myself, but am just starting to look into it. Interested to hear others' thoughts.### ReasonAlthough the code comments for the PGVectorStore class currently suggest BM25 search is present in Postgres - it is not.### Value of FeatureBM25 retrieval hit rate and MRR is measurable better than Postgres full text search with tsvector and tsquery. Indexing is also supposed to be faster with pg_bm25.Number of source nodes: 6{'state': 'open', 'created_at': '2023-12-11T10:17:52Z', 'url': 'https://api.github.com/repos/run-llama/llama_index/issues/9431', 'source': 'https://github.com/run-llama/llama_index/pull/9431', 'labels': ['size:XL'], 'index_id': '9431'}

步骤8:插入RetrieverQueryEngine

from llama_index.query_engine import RetrieverQueryEnginefrom llama_index import ServiceContextllm = OpenAI(model="gpt-3.5-turbo")service_context = ServiceContext.from_defaults(llm=llm)query_engine = RetrieverQueryEngine.from_args(recursive_retriever, llm=llm)response = query_engine.query(    "Tell me about some open issues related to agents")print(str(response)) # OutputThere were several issues created on 12/11. One of them is a bug where the metadata filter is not working correctly with Elastic search indexing. Another bug involves an error loading the 'punkt' module in the NLTK library. There are also a couple of feature requests, one for adding Postgres BM25 support and another for making llama-index compatible with models finetuned and hosted on modal.com. Additionally, there is a question about using the Slack Loader with large Slack channels.

四、结论

        总之,将Llamaindex集成到多文档RAG架构的结构中预示着信息检索的新时代。它能够基于结构化元数据动态选择文档,再加上语义查询优化的技巧,重塑了我们如何利用庞大文档存储库中的知识,提高了检索过程的效率、相关性和准确性。

参考文献:

[1] https://ai.gopubby.com/structured-hierarchical-retrieval-revolutionizing-multi-document-rag-architectures-f101463db689

[2] https://weaviate.io/developers/wcs/quickstart

[3] https://docs.llamaindex.ai/en/stable/examples/query_engine/multi_doc_auto_retrieval/multi_doc_auto_retrieval.html

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python+opencv实现图片/短视频一键去水印

目录 0 前言1 准备工作2 读取图片或视频3 添加回调获取鼠标绘制水印区域4 调用opencv函数5 绘制蒙版主循环6 去水印主循环总结 0 前言 在制作ppt个人文章或者分享图片过程中&#xff0c;经常会遇到一些带有水印的情况&#xff0c;不少人都希望能够去除这些水印&#xff0c;提高…

分布式存储考点梳理 + 高频面试题

欢迎来到分布式存储模环节&#xff0c;本文我将和你一起梳理面试中分布式系统的数据库的高频考点&#xff0c;做到温故知新。 面试中如何考察分布式存储 广义的分布式存储根据不同的应用领域&#xff0c;划分为以下的类别&#xff1a; 分布式协同系统 分布式文件系统 分布式…

数据结构:单调栈

1.单调栈 单调栈是一种数据结构&#xff0c;其中存放的数据应该是有序的&#xff0c;所以单调栈也有单调递减栈和单调递增栈 单调递增栈&#xff1a;栈顶到栈底的元素大小是从小到大 单调递减栈&#xff1a;栈顶到栈底的元素大小是从大到小 单调栈主要就是用来求一个给定序列中…

上海周边公路骑行路线分享,维乐带你抓住秋天的小尾巴

路线一&#xff1a;松江郊里骑行      在魔都上海&#xff0c;藏着一条自然风景适宜&#xff0c;能眺望黄浦江的美丽骑行路线。导航到华长路杨家角就能到达起点&#xff0c;一路向西&#xff0c;这里路况非常好&#xff0c;只有一条小道&#xff0c;没有汽车的障碍&#xf…

数组(定义,静态初始化,地址值,元素访问,索引,遍历,动态初始化,两种初始化的区别,练习)

文章目录 1.数组概念&#xff1a; 2.数组的定义格式一&#xff1a;格式二&#xff1a;详解&#xff1a;注意点&#xff1a; 3.数组的静态初始化完整格式&#xff1a;格式详解&#xff1a;注意点&#xff1a;简化格式:练习1&#xff1a;练习2&#xff1a;练习3&#xff1a; 4.地…

使用opencv+tesseract识别图片中的表格

描述 在java环境中使用opencv和tesserac识别一个图片表格 环境&#xff1a;opencv和tesseract安装在linux环境下&#xff0c;docker将运行springboot服务 opencv和tesseract的安装和docker加载可参考之前的文章 过程 将图片进行预处理&#xff0c;过滤掉颜色等干扰元素 提…

基于Ubuntu环境Git服务器搭建及使用

基于Ubuntu环境Git服务器搭建及使用 Chapter1 搭建本地git服务器及详细操作步骤1.搭建本地git服务器1.1 环境1.2 服务端配置1.3 创建git专属用户1.4 创建git仓库1.5 配置免密登录基础 2.客户端拉取推送代码2.1客户端创建ssh公钥 2.2 免密配置3.仓库使用&#xff08;拉取及推送代…

记chrome的hackbar无法post php://input的问题

尽管hackbar支持post请求体&#xff0c;但是当请求体里面没有等于号的时候&#xff0c;无法post出去&#xff0c;这样如果需要使用php://input绕过waf的时候就没法做。 在开发人员工具的网络里面可以看到不使用等于号的情况下没有荷载。 之后在这里看到了解决方法&#xff0c;…

【javaSE】代理并不难

代理&#xff1a; 代理模式最主要的就是在不改变原来代码&#xff08;就是目标对象&#xff09;的情况下实现功能的增强 在学习AOP之前先了解代理&#xff0c;代理有两种&#xff1a;一种是动态代理&#xff0c;一类是静态代理。 静态代理 相当于是自己写了一个代理类&#…

pandas将dataframe列中的list转换为多列

在应用机器学习的过程中&#xff0c;很大一部分工作都是在做数据的处理&#xff0c;一个非常常见的场景就是将一个list序列的特征数据拆成多个单独的特征数据。 比如数据集如下所示&#xff1a; data [[John, 25, Male,[99,100,98]],[Emily, 22, Female,[97,99,98]],[Michae…

JUC Lock 锁入门

文章目录 死锁&#xff08;Deadlock&#xff09;通过 Visualvm 等工具排查死锁 活锁park & unpark与 wait & notify 的区别park & unpark 实现&#xff1a;点外卖 Lock 对象ReentrantLock 可重入锁可重入lockInterruptibly 方法上锁&#xff08;可打断&#xff09;…

门诊病历系统教程,社区诊所电子处方系统软件操作教程

一、软件程序问答 门诊病历系统教程&#xff0c;社区诊所电子处方系统软件操作教程 1、电子处方软件在开处方时候&#xff0c;可以一键导入模板吗&#xff1f; 如下图&#xff0c;软件以 佳易王诊所电子处方软件V17.1为例说明 软件右侧点击 配方模板&#xff0c;只需输入症…

以太坊代币标准解读及相关Dapp的搭建

文章目录 什么是以太坊代币标准1、什么是以太坊2、以太坊代币标准 同质化代币 Dapp 搭建1、MetaMask 的安装2、Ganache 的安装3、实现 ERC-20 代币协议4、前端页面的编写5、部署流程及操作演示 什么是以太坊代币标准 1、什么是以太坊 以太坊&#xff08;Ethereum&#xff09;是…

2024年,程序员有哪些危机,有什么应对方式?

在2024年&#xff0c;程序员可能面临的危机主要包括技术更新迅速、职业竞争激烈、工作与生活平衡困难等方面。 为了应对这些危机&#xff0c;程序员可以采取以下策略&#xff1a; 技术更新迅速&#xff1a;随着技术的不断发展&#xff0c;新的编程语言和工具不断涌现&#xff…

52.网游逆向分析与插件开发-游戏反调试功能的实现-检测调试器

码云地址&#xff08;master分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;be9f058bfaaa4b015f2659db842e07ee37e58996 代码下载地址&#xff0c;在 SRO_EX 目录下&#xff0c;文件名为&#xff1a;SRO_Ex检测调试器.z…

迈向通用异常检测和理解:大规模视觉语言模型(GPT-4V)率先推出

PAPERCODEhttps://arxiv.org/pdf/2311.02782.pdfhttps://github.com/caoyunkang/GPT4V-for-Generic-Anomaly-Detection 图1 GPT-4V在多模态多任务异常检测中的综合评估 在这项研究中&#xff0c;我们在多模态异常检测的背景下对GPT-4V进行了全面评估。我们考虑了四种模式&#…

c 生成16×16像素点的rgb格式图片

想验证jpeg 编解码各个环节是否正确&#xff0c;特小尺寸的yuv格式图片找不到。特意用c代码生成一个1616像素点的rgb格式图片,再转换为yuv444格式&#xff0c;再88分割&#xff0c;余弦转换&#xff0c;量化&#xff0c;Z变换&#xff0c;霍夫曼编码&#xff0c;生成比特流&…

你真的懂Hello World!吗?(编译与链接,静态链接与动态链接)

&#x1f4ab;Hello World! 对于大家来说Hello World!应该是最熟悉不过的一句话&#xff0c;我们从Hello World!走进了计算机的世界&#xff0c;但是你真的了解Hello World!吗&#xff1f;你又思考过它背后蕴含的机理吗&#xff1f;他是怎么从代码变成程序的你真的思考过吗&…

react18框架笔记

React React 是 facebook 出的一款针对视图层的库(library)。它是基于单向数据流思想开发的&#xff0c;主要的一个功能就是针对视图显示&#xff0c;让我们把一个项目拆分成一个一个组件进行开发维护。 官网 目前我们讲的 react 是基于 18.2 的版本。react 每一个版本更新之…

谷歌Linux内核自动测试平台架构介绍-用自动测试测试难以测试的问题

1 摘要 内核和硬件等低级系统已被证明极难进行有效测试&#xff0c;因此&#xff0c;许多内核测试都是以手动为主方式进行的。现有的大多数测试框架都是为测试与底层平台隔离的高级软件而设计的&#xff0c;而底层平台被假定是稳定可靠的。测试底层平台本身需要一套全新的假设…