paint-brush
Almayla Artırılmış Oluşturma için Bilgi Grafikleri Nasıl Kullanılır - Grafik Veritabanı Olmadanile@datastax
2,896 okumalar
2,896 okumalar

Almayla Artırılmış Oluşturma için Bilgi Grafikleri Nasıl Kullanılır - Grafik Veritabanı Olmadan

ile DataStax12m2024/04/23
Read on Terminal Reader

Çok uzun; Okumak

Bu gönderi, depolama için DataStax Astra DB'yi kullanarak RAG için bilgi grafiklerinin kullanımını araştırıyor. Örneklerin kodu, Astra DB'yi kullanarak bilgi grafiklerini depolamak ve almak için bazı prototip kodlarını kullanan bu not defterindedir.
featured image - Almayla Artırılmış Oluşturma için Bilgi Grafikleri Nasıl Kullanılır - Grafik Veritabanı Olmadan
DataStax HackerNoon profile picture

Artırılmış neslin alınması (RAG), bilgi almak ve onu üretken yapay zeka için bağlamsal bilgi sağlamak amacıyla kullanmak için çeşitli teknikleri ifade eder. En yaygın biçim, metin parçaları üzerinde çalışır ve şunları içerir:


  1. Metnin orijinal belgelerden (HTML, PDF, Markdown vb.) çıkarılması.


  2. Belge yapısına ve anlambilime göre metni belirli boyutlara bölme.


  3. Parçaların, parçanın gömülmesiyle anahtarlanmış bir vektör veritabanında saklanması.


  4. Yanıt oluşturulurken bağlam olarak kullanılmak üzere bir soruyla ilgili parçaların alınması.


Ancak vektör benzerliğine dayalı RAG'ın birkaç zayıf noktası vardır. Soruya benzer bilgilere odaklandığından, örneğin birden fazla konuyu içeren ve/veya birden fazla atlama gerektiren soruları yanıtlamak daha zordur. Ayrıca alınan parça sayısını da sınırlar.


Her parça farklı bir kaynaktan gelir; bu nedenle, büyük ölçüde benzer bilgilerin birden fazla yerde mevcut olduğu durumlarda, bilginin birden fazla kopyasını almak (ve muhtemelen diğer bilgileri kaçırmak) veya daha fazlasını elde etmek için yalnızca bir kopyayı seçmek arasında seçim yapması gerekir. farklı parçalar, daha sonra diğer kaynakların nüanslarını gözden kaçırıyor.


Bilgi grafikleri vektör tabanlı öbek alımına alternatif veya ek olarak kullanılabilir. Bir bilgi grafiğinde düğümler belirli varlıklara karşılık gelir ve kenarlar varlıklar arasındaki ilişkileri gösterir. RAG için kullanıldığında soru ile ilgili varlıklar çıkarılarak bu varlıkların ve onlara ait bilgilerin yer aldığı bilgi alt grafiğine ulaşılır.


Bu yaklaşımın benzerliğe dayalı yaklaşıma göre birçok avantajı vardır:

  1. Pek çok gerçek tek bir kaynaktan çıkarılabilir ve bilgi grafiğindeki çeşitli varlıklarla ilişkilendirilebilir. Bu, ilgisiz bilgiler de dahil olmak üzere tüm yığın yerine yalnızca ilgili gerçeklerin belirli bir kaynaktan alınmasına olanak tanır.


  2. Birden fazla kaynak aynı şeyi söylüyorsa aynı düğümü veya kenarı üretirler. Bunları farklı gerçekler olarak ele almak (ve birden fazla kopya almak) yerine, aynı düğüm veya kenar olarak ele alınabilir ve yalnızca bir kez alınabilir. Bu, daha geniş çeşitlilikte gerçeklere ulaşmayı ve/veya yalnızca birden fazla kaynakta görünen gerçeklere odaklanmayı sağlar.


  3. Grafik, yalnızca sorudaki varlıklarla doğrudan ilgili bilgileri almakla kalmayıp, aynı zamanda 2 veya 3 adım ötedeki şeyleri de geri çekerek birden fazla adımdan geçebilir. Geleneksel bir RAG yaklaşımında bu, birden fazla sorgulama turu gerektirir.


RAG için bilgi grafiği kullanmanın yararlarına ek olarak, LLM'ler bilgi grafikleri oluşturmayı da kolaylaştırdı. Konu uzmanlarının bilgi grafiğini dikkatli bir şekilde oluşturmasını gerektirmek yerine, belgelerden bilgi çıkarmak için bir Yüksek Lisans ve bilgi istemi kullanılabilir.


Bu gönderide RAG için bilgi grafiklerinin kullanımı araştırılmaktadır. DataStax Astra DB depo için. Örneklerin kodu bundadır not defteri Astra DB'yi kullanarak bilgi grafiklerini depolamak ve almak için bazı prototip kodlarının kullanılması bu depo . Belgelerden bilgi grafikleri çıkarmak, bunları Astra'ya yazmak ve bilgi çıkarmak için kullanılan istemi ayarlama tekniklerini tartışmak için LangChain'in "LLMGraphTransformer"ını kullanacağız.


Daha sonra sorudan varlıkları çıkarmak ve ilgili alt grafikleri almak için LangChain çalıştırılabilirleri oluşturacağız. Bilgi grafiklerini kullanarak RAG'yi uygulamak için gerekli işlemlerin, grafik veritabanları veya grafik sorgulama dilleri gerektirmediğini, yaklaşımın halihazırda kullanıyor olabileceğiniz tipik bir veri deposu kullanılarak uygulanmasına olanak sağladığını göreceğiz.

Bilgi Grafiği

Daha önce de belirtildiği gibi, bir bilgi grafiği farklı varlıkları düğümler olarak temsil eder. Örneğin bir düğüm, kişiyi “Marie Curie”yi veya dili “Fransızca”yı temsil edebilir. LangChain'de her düğümün bir adı ve türü vardır. Bir düğümü benzersiz bir şekilde tanımlarken, dili "Fransızca"yı milliyet olan "Fransızca"dan ayırmak için her ikisini de dikkate alacağız.


Varlıklar arasındaki ilişkiler grafikteki kenarlara karşılık gelir. Her kenar, kaynağı (örneğin, kişi Marie Curie), hedefi (ödül Nobel Ödülü) ve kaynağın hedefle nasıl ilişkili olduğunu gösteren bir türü (örneğin, "kazandı") içerir.


LangChain kullanarak Marie Curie hakkındaki bir paragraftan alınan örnek bilgi grafiği aşağıda gösterilmektedir:


Hedeflerinize bağlı olarak düğümlere ve kenarlara özellikler eklemeyi seçebilirsiniz. Örneğin, Nobel Ödülü'nün ne zaman kazanıldığını ve kategoriyi belirlemek için bir özelliği kullanabilirsiniz. Bunlar, alma sırasında grafikte gezinirken kenarları ve düğümleri filtrelemek için yararlı olabilir.

Çıkarma: Bilgi Grafiği Oluşturma

Bilgi grafiğini oluşturan varlıklar ve ilişkiler doğrudan oluşturulabilir veya mevcut iyi bilinen veri kaynaklarından içe aktarılabilir. Bu, bilgiyi dikkatli bir şekilde düzenlemek istediğinizde faydalıdır, ancak yeni bilgilerin hızlı bir şekilde dahil edilmesini veya büyük miktarda bilginin işlenmesini zorlaştırır.


Neyse ki, Yüksek Lisans'lar içerikten bilgi çıkarmayı kolaylaştırıyor, böylece onları bilgi grafiğini çıkarmak için kullanabiliriz.


Aşağıda, şunu kullanıyorum: LLMGraphTransformer Marie Curie hakkındaki bazı bilgilerden bir grafik çıkarmak için LangChain'den. Bu, bir LLM'ye bir belgeden düğümleri ve kenarları çıkarması talimatını vermek için bir istem kullanır. LangChain'in yükleyebileceği herhangi bir belgeyle kullanılabilir, bu da mevcut LangChain projelerine eklemeyi kolaylaştırır.


LangChain aşağıdaki gibi diğer seçenekleri destekler: DiffBot Ayrıca mevcut bilgi çıkarma modellerinden bazılarına da bakabilirsiniz, örneğin İsyancı .


 from langchain_experimental.graph_transformers import LLMGraphTransformer from langchain_openai import ChatOpenAI from langchain_core.documents import Document # Prompt used by LLMGraphTransformer is tuned for Gpt4. llm = ChatOpenAI(temperature=0, model_name="gpt-4") llm_transformer = LLMGraphTransformer(llm=llm) text = """ Marie Curie, was a Polish and naturalised-French physicist and chemist who conducted pioneering research on radioactivity. She was the first woman to win a Nobel Prize, the first person to win a Nobel Prize twice, and the only person to win a Nobel Prize in two scientific fields. Her husband, Pierre Curie, was a co-winner of her first Nobel Prize, making them the first-ever married couple to win the Nobel Prize and launching the Curie family legacy of five Nobel Prizes. She was, in 1906, the first woman to become a professor at the University of Paris. """ documents = [Document(page_content=text)] graph_documents = llm_transformer.convert_to_graph_documents(documents) print(f"Nodes:{graph_documents[0].nodes}") print(f"Relationships:{graph_documents[0].relationships}")


Bu, LangChain'in LLMGraphTransformer kullanarak bir bilgi grafiğinin nasıl çıkarılacağını gösterir. Görsel inceleme amacıyla bir LangChain GraphDocument oluşturmak için depoda bulunan render_graph_document kullanabilirsiniz.


Gelecekteki bir gönderide, bilgi grafiğini hem bütünüyle hem de her belgeden alınan alt grafiği nasıl inceleyebileceğinizi ve otomatik ayıklamayı geliştirmek için hızlı mühendislik ve bilgi mühendisliğini nasıl uygulayabileceğinizi tartışacağız.

Geri Alma: Alt Bilgi Grafiğiyle Yanıtlama

Bilgi grafiğini kullanarak soruları yanıtlamak birkaç adım gerektirir. Öncelikle bilgi grafiğinde geçişimize nereden başlayacağımızı belirleriz. Bu örnek için, bir Yüksek Lisans'tan sorudaki varlıkları çıkarmasını isteyeceğim. Daha sonra bilgi grafiği, bu başlangıç noktalarına belirli bir mesafedeki tüm ilişkileri almak için geçilir. Varsayılan geçiş derinliği 3'tür. Alınan ilişkiler ve orijinal soru, LLM'nin soruyu yanıtlaması için bir bilgi istemi ve bağlam oluşturmak için kullanılır.

Sorudan Varlıkları Çıkarma

Bilgi grafiğinin çıkarılmasında olduğu gibi, bir sorudaki varlıkların çıkarılması da özel bir model veya belirli bir istemle LLM kullanılarak yapılabilir. Basit olması açısından, hem soruyu hem de çıkarılacak formatla ilgili bilgileri içeren aşağıdaki komut istemiyle bir Yüksek Lisans Diploması kullanacağız. Uygun yapıyı elde etmek için adı ve türü olan bir Pydantic modeli kullanıyoruz.

 QUERY_ENTITY_EXTRACT_PROMPT = ( "A question is provided below. Given the question, extract up to 5 " "entity names and types from the text. Focus on extracting the key entities " "that we can use to best lookup answers to the question. Avoid stopwords.\n" "---------------------\n" "{question}\n" "---------------------\n" "{format_instructions}\n" ) def extract_entities(llm): prompt = ChatPromptTemplate.from_messages([keyword_extraction_prompt]) class SimpleNode(BaseModel): """Represents a node in a graph with associated properties.""" id: str = Field(description="Name or human-readable unique identifier.") type: str = optional_enum_field(node_types, description="The type or label of the node.") class SimpleNodeList(BaseModel): """Represents a list of simple nodes.""" nodes: List[SimpleNode] output_parser = JsonOutputParser(pydantic_object=SimpleNodeList) return ( RunnablePassthrough.assign( format_instructions=lambda _: output_parser.get_format_instructions(), ) | ChatPromptTemplate.from_messages([QUERY_ENTITY_EXTRACT_PROMPT]) | llm | output_parser | RunnableLambda( lambda node_list: [(n["id"], n["type"]) for n in node_list["nodes"]]) )


Yukarıdaki örneği çalıştırarak çıkarılan varlıkları görebiliriz:

 # Example showing extracted entities (nodes) extract_entities(llm).invoke({ "question": "Who is Marie Curie?"}) # Output: [Marie Curie(Person)]


Elbette bir LangChain Runnable, bir sorudan varlıkları çıkarmak için bir zincirde kullanılabilir.


Gelecekte, ilgili başlangıç noktalarını belirlemek için düğüm özelliklerini dikkate almak veya vektör yerleştirmeleri ve benzerlik aramasını kullanmak gibi varlık çıkarımını geliştirmenin yollarını tartışacağız. Bu ilk gönderiyi basit tutmak için yukarıdaki istemi sürdüreceğiz ve knowledge-subgraph almak ve bunu istemin bağlamı olarak eklemek için bilgi grafiğini geçmeye devam edeceğiz.

Alt Bilgi Grafiğini Alma

Önceki zincir bize söz konusu düğümleri verir. İlgili bilgi üçlülerini almak için bu varlıkları ve grafik deposunu kullanabiliriz. RAG'da olduğu gibi, bunları bağlamın bir parçası olarak bilgi istemine bırakıyoruz ve yanıtlar üretiyoruz.

 def _combine_relations(relations): return "\n".join(map(repr, relations)) ANSWER_PROMPT = ( "The original question is given below." "This question has been used to retrieve information from a knowledge graph." "The matching triples are shown below." "Use the information in the triples to answer the original question.\n\n" "Original Question: {question}\n\n" "Knowledge Graph Triples:\n{context}\n\n" "Response:" ) chain = ( { "question": RunnablePassthrough() } # extract_entities is provided by the Cassandra knowledge graph library # and extracts entitise as shown above. | RunnablePassthrough.assign(entities = extract_entities(llm)) | RunnablePassthrough.assign( # graph_store.as_runnable() is provided by the CassandraGraphStore # and takes one or more entities and retrieves the relevant sub-graph(s). triples = itemgetter("entities") | graph_store.as_runnable()) | RunnablePassthrough.assign( context = itemgetter("triples") | RunnableLambda(_combine_relations)) | ChatPromptTemplate.from_messages([ANSWER_PROMPT]) | llm )


Yukarıdaki zincir bir soruyu cevaplamak için yürütülebilir. Örneğin:

 chain.invoke("Who is Marie Curie?") # Output AIMessage( content="Marie Curie is a Polish and French chemist, physicist, and professor who " "researched radioactivity. She was married to Pierre Curie and has worked at " "the University of Paris. She is also a recipient of the Nobel Prize.", response_metadata={ 'token_usage': {'completion_tokens': 47, 'prompt_tokens': 213, 'total_tokens': 260}, 'model_name': 'gpt-4', ... } )

Geçiş Yap, Sorgulama

Bilgi grafiğini depolamak için bir grafik veritabanı kullanmak sezgisel görünse de aslında gerekli değildir. Birkaç düğüm etrafındaki alt bilgi grafiğini almak basit bir grafik geçişidir; grafik veri tabanları ise belirli özellik dizilerine sahip yolları arayan çok daha karmaşık sorgular için tasarlanmıştır. Dahası, geçiş genellikle yalnızca 2 veya 3 derinliğe kadar olur, çünkü daha uzaktaki düğümler oldukça hızlı bir şekilde soruyla ilgisiz hale gelir. Bu, birkaç tur basit sorgu (her adım için bir tane) veya SQL birleşimi olarak ifade edilebilir.


Ayrı bir grafik veritabanına olan ihtiyacı ortadan kaldırmak, bilgi grafiklerinin kullanımını kolaylaştırır. Ek olarak, Astra DB veya Apache Cassandra'nın kullanılması, hem grafiğe hem de aynı yerde depolanan diğer verilere işlemsel yazma işlemlerini basitleştirir ve muhtemelen daha iyi ölçeklenir. Bu ek yük, yalnızca Gremlin veya Cypher veya benzeri bir şey kullanarak grafik sorguları oluşturmayı ve yürütmeyi planlıyorsanız faydalı olacaktır.


Ancak bu, alt bilgi grafiğini almak için fazlasıyla gereksizdir ve performans açısından kontrolden çıkan sorgular gibi bir dizi başka soruna da kapı açar.


Bu geçişin Python'da uygulanması kolaydır. CQL ve Cassandra Sürücüsünü kullanarak bunu (hem eşzamanlı hem de eşzamansız olarak) uygulamaya yönelik tam kodu şurada bulabilirsiniz: depo . Asenkron geçişin çekirdeği örnek olarak aşağıda gösterilmiştir:


 def fetch_relation(tg: asyncio.TaskGroup, depth: int, source: Node) -> AsyncPagedQuery: paged_query = AsyncPagedQuery( depth, session.execute_async(query, (source.name, source.type)) ) return tg.create_task(paged_query.next()) results = set() async with asyncio.TaskGroup() as tg: if isinstance(start, Node): start = [start] discovered = {t: 0 for t in start} pending = {fetch_relation(tg, 1, source) for source in start} while pending: done, pending = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED) for future in done: depth, relations, more = future.result() for relation in relations: results.add(relation) # Schedule the future for more results from the same query. if more is not None: pending.add(tg.create_task(more.next())) # Schedule futures for the next step. if depth < steps: # We've found a path of length `depth` to each of the targets. # We need to update `discovered` to include the shortest path. # And build `to_visit` to be all of the targets for which this is # the new shortest path. to_visit = set() for r in relations: previous = discovered.get(r.target, steps + 1) if depth < previous: discovered[r.target] = depth to_visit.add(r.target) for source in to_visit: pending.add(fetch_relation(tg, depth + 1, source)) return results


Çözüm

Bu makale, soru yanıtlama için bilgi grafiği çıkarma ve alma işlemlerinin nasıl oluşturulacağını ve kullanılacağını gösterdi. Temel çıkarım şu ki, bugün bunu yapmak için Gremlin veya Cypher gibi bir grafik sorgulama diline sahip bir grafik veritabanına ihtiyacınız yok. Birçok sorguyu paralel olarak verimli bir şekilde işleyen Astra gibi harika bir veritabanı, bunu zaten yapabilir.


Aslında, belirli bir sorguyu yanıtlamak için gereken alt bilgi grafiğini almak için basit bir sorgu dizisi yazabilirsiniz. Bu, mimarinizi basit tutar (ek bağımlılık yoktur) ve hemen başla !


Cassandra ve Astra DB için GraphRAG modellerini uygulamak için aynı fikirleri kullandık. Bunları LangChain'e katkıda bulunacağız ve gelecekte LLM'lerle bilgi grafiklerinin kullanımına başka iyileştirmeler getirmek için çalışacağız!


Ben Chambers, DataStax tarafından