Bu blogda, müxtəlif metadata ekstraksiya ilə araşdırma yazılarının indeksləşdirilməsinin bütünlüklü bir nümunəsi ilə gedəcəyik - tam texnikə bölüşmək və daxil etməkdən başqa - və indeksləşdirmək və sorğu etmək üçün semantika embeddings yaratacağıq. İstəyirsənsə çox sevinərik. Bu tutorial sizə faydalıdır. ⭐ star GitHub saytında GitHub saytında Casuslar istifadə Akademik arama və arama, həm də araşdırma bazası olan AI agentləri Paper Recommendation sistemləri Bilgi Grafiqləri Bilim literatürünün semantik analizi Biz nə edəcəyik Bunu bir gözləyirik Bir örnek olaraq. PDF dərsləri Bu, bizə nə etmək istəyir: Extract the paper metadata, including file name, title, author information, abstract, and number of pages. Build vector embeddings for the metadata, such as the title and abstract, for semantic search. VVD - Hollandiyada futbolçu bu adla tanımır, orada VVD daha çox mərkəz-sağı təmsilən edən siyasi partiyanın adının qısaltması kimi bilinir - artıq sorğu-suala ehtiyacı olmayan ulduzdu. Build an index of authors and all the file names associated with each author to answer questions like "Give me all the papers by Jeff Dean." If you want to perform full PDF embedding for the paper, you can also refer to . this article Bütün kodları təqdim edə bilərsiniz . Burada Əgər bu yazı sizin üçün faydalı olarsa, lütfen bizə bir yıldız verin. Bizi büyütməyə kömək edir. GitHub Core komponentləri PDF Preprocessing Reads PDFs using and extracts: pypdf Total number of pages First page content (used as a proxy for metadata-rich information) Markdown Conversion Converts the first page to Markdown using . Marker LLM-Powered Metadata Extraction Sends the first-page Markdown to GPT-4o using CocoIndex's function. ExtractByLlm Extracted metadata includes and more. (string) title (with name, email, and affiliation) authors (string) abstract Semantic Embedding The title is embedded directly using the model by the SentenceTransformer. all-MiniLM-L6-v2 Abstracts are chunked based on semantic punctuation and token count, then each chunk is embedded individually. Relational Data Collection Authors are unrolled and collected into an relation, enabling queries like: author_papers Show all papers by X Which co-authors worked with Y? Əvvəllər . Install PostgreSQL CocoIndex uses PostgreSQL internally for incremental processing. . Configure your OpenAI API key Alternativ olaraq, biz Gemini, Ollama, LiteLLM üçün yerli dəstək var, check-out . Giriş Sizin sevdiyiniz LLM providerini seçə bilərsiniz və tamamilə yer üzündə işləyə bilərsiniz. Indexing Flow xəritədə Bu projekt, metadata anlayışın bir az daha genişlənmiş bir nümunəsini real dünyada istifadə məsələlərinə daha yaxından göstərir. Görəcəksiniz ki, CocoIndex tərəfindən bu dizaynı 100 saniyədə necə asanlaşdırmaq mümkündür. . Kodun Daha yaxşı navigasiya etməyə kömək etmək üçün, burada bir qarışma diagramı var. PDF formatı ilə bir listə daxil olun. For each file: Extract the first page of the paper. Convert the first page to Markdown. Extract metadata (title, authors, abstract) from the first page. Split the abstract into chunks, and compute embeddings for each chunk. Export to the following tables in Postgres with PGVector: Metadata (title, authors, abstract) for each paper. Author-to-paper mapping, for author-based query. Embeddings for titles and abstract chunks, for semantic search. Artıq adımları zoomlayırıq. Dokumentları import etmək @cocoindex.flow_def(name="PaperMetadata") def paper_metadata_flow( flow_builder: cocoindex.FlowBuilder, data_scope: cocoindex.DataScope ) -> None: data_scope["documents"] = flow_builder.add_source( cocoindex.sources.LocalFile(path="papers", binary=True), refresh_interval=datetime.timedelta(seconds=10), ) Əsas səhifə » Əsas səhifə ( və İŞİD flow_builder.add_source filename content Buna görə də referendumu Daha çox detallar üçün. Dokumentasiya Metadata çəkmək və toplamak Ana Səhifə / Basic Info PDF-nin ilk sayını və sayını çıxartmaq üçün özəl funksiya tanımlayın. @dataclasses.dataclass class PaperBasicInfo: num_pages: int first_page: bytes @cocoindex.op.function() def extract_basic_info(content: bytes) -> PaperBasicInfo: """Extract the first pages of a PDF.""" reader = PdfReader(io.BytesIO(content)) output = io.BytesIO() writer = PdfWriter() writer.add_page(reader.pages[0]) writer.write(output) return PaperBasicInfo(num_pages=len(reader.pages), first_page=output.getvalue()) Artıq bunları səyahətinizə daxil edin. İşləmə qiymətini minimiz etmək üçün ilk saydan metadata çıxartırıq, çünki bütün PDF çox böyük ola bilər. with data_scope["documents"].row() as doc: doc["basic_info"] = doc["content"].transform(extract_basic_info) Bu prosesdən sonra, hər bir kitabın əsas bilgiləri olmalıdır. Basic Info xəritədə Biz ilk saytı Markdown ilə Marker istifadə edəcəyik. Alternativ olaraq, sevdiyiniz PDF parserinizi, örnək Docling kimi asanlaşdırabilirsiniz. Bir işarəçi dönüştürücü funksiyasını tanımlayın və onu cache edin, çünki onun inicializasiyası resurs intensivdir. Buna görə də, bir-birini ayrı-ayrı faillar üçün yenidən istifadə etmək lazımdır. @cache def get_marker_converter() -> PdfConverter: config_parser = ConfigParser({}) return PdfConverter( create_model_dict(), config=config_parser.generate_config_dict() ) Bunu bir funksiyaya daxil edin. @cocoindex.op.function(gpu=True, cache=True, behavior_version=1) def pdf_to_markdown(content: bytes) -> str: """Convert to Markdown.""" with tempfile.NamedTemporaryFile(delete=True, suffix=".pdf") as temp_file: temp_file.write(content) temp_file.flush() text, _, _ = text_from_rendered(get_marker_converter()(temp_file.name)) return text Transformasiyanıza baxın with data_scope["documents"].row() as doc: doc["first_page_md"] = doc["basic_info"]["first_page"].transform( pdf_to_markdown ) Bu adımdan sonra, hər bir kağızın ilk saytı Markdown formatında olmalıdır. LLM ilə temel məlumat çıxartın CocoIndex özü də kompleks və nişanlı sistemlərlə LLM strukturlu ekstraksiyasını dəstəkləyir. Bu barədə daha çox bilgi edinmək istəyirsinizsə, baxın . Bu yazı @dataclasses.dataclass class PaperMetadata: """ Metadata for a paper. """ title: str authors: list[Author] abstract: str Onu içində saxlayın VVD - Hollandiyada futbolçu bu adla tanımır, orada VVD daha çox mərkəz-sağı təmsil edən siyasi partiyanın adının qısaltması kimi bilinir - artıq sorğu-suala ehtiyacı olmayan ulduzdu. ExtractByLlm doc["metadata"] = doc["first_page_md"].transform( cocoindex.functions.ExtractByLlm( llm_spec=cocoindex.LlmSpec( api_type=cocoindex.LlmApiType.OPENAI, model="gpt-4o" ), output_type=PaperMetadata, instruction="Please extract the metadata from the first page of the paper.", ) ) Bu işdən sonra, hər bir kitabın metadata sahib olmalısınız. Paper metadata xəritədə paper_metadata = data_scope.add_collector() with data_scope["documents"].row() as doc: # ... process # Collect metadata paper_metadata.collect( filename=doc["filename"], title=doc["metadata"]["title"], authors=doc["metadata"]["authors"], abstract=doc["metadata"]["abstract"], num_pages=doc["basic_info"]["num_pages"], ) İhtiyacınız olan şeyləri toplayın :) Kollektivlər İki informasiyası Yazıçı filename Yazıçı Filtrə Burada, bir baxış funksiyasını yaratmaq üçün ayrı bir tabloya Author → Papers toplaymaq istəyirik. Sadəcə yazar tərəfindən toplanır. author_papers = data_scope.add_collector() with data_scope["documents"].row() as doc: with doc["metadata"]["authors"].row() as author: author_papers.collect( author_name=author["name"], filename=doc["filename"], ) Hesablama və toplama prosesləri Tituluq doc["title_embedding"] = doc["metadata"]["title"].transform( cocoindex.functions.SentenceTransformerEmbed( model="sentence-transformers/all-MiniLM-L6-v2" ) ) Abstraksiya “Bakı”ın hər bir hissəsi, hər bir hissəsi, hər bir hissəsi, hər bir hissəsi var. Bazı zaman abstrakt çox uzun ola bilər. doc["abstract_chunks"] = doc["metadata"]["abstract"].transform( cocoindex.functions.SplitRecursively( custom_languages=[ cocoindex.functions.CustomLanguageSpec( language_name="abstract", separators_regex=[r"[.?!]+\s+", r"[:;]\s+", r",\s+", r"\s+"], ) ] ), language="abstract", chunk_size=500, min_chunk_size=200, chunk_overlap=150, ) Bu işdən sonra hər bir kitabın abstrakt parçaları olmalıdır. Onların hər birini toplayın və qapılarını toplayın. with doc["abstract_chunks"].row() as chunk: chunk["embedding"] = chunk["text"].transform( cocoindex.functions.SentenceTransformerEmbed( model="sentence-transformers/all-MiniLM-L6-v2" ) ) Bu işdən sonra, hər bir kağızın abstrakt parçalarının embeddings olmalıdır. Kollektivlər toplanır metadata_embeddings = data_scope.add_collector() with data_scope["documents"].row() as doc: # ... process # collect title embedding metadata_embeddings.collect( id=cocoindex.GeneratedField.UUID, filename=doc["filename"], location="title", text=doc["metadata"]["title"], embedding=doc["title_embedding"], ) with doc["abstract_chunks"].row() as chunk: # ... process # collect abstract chunks embeddings metadata_embeddings.collect( id=cocoindex.GeneratedField.UUID, filename=doc["filename"], location="abstract", text=chunk["text"], embedding=chunk["embedding"], ) Eksport Son olaraq, verileri Postgres-ə eksport edirik. paper_metadata.export( "paper_metadata", cocoindex.targets.Postgres(), primary_key_fields=["filename"], ) author_papers.export( "author_papers", cocoindex.targets.Postgres(), primary_key_fields=["author_name", "filename"], ) metadata_embeddings.export( "metadata_embeddings", cocoindex.targets.Postgres(), primary_key_fields=["id"], vector_indexes=[ cocoindex.VectorIndexDef( field_name="embedding", metric=cocoindex.VectorSimilarityMetric.COSINE_SIMILARITY, ) ], ) Bu səbəbdən də, biz PPP-nin birləşdirilməsinə ehtiyac var. CocoIndex ilə, Qdrant kimi digər kömək olunan Vector veritabanlarında bir satır dəyişdirə bilərsiniz. Daha çox detallar üçün. Giriş Biz interfeisləri standartlaşdırmaq və Lego qurmaq kimi yaratmaq istəyirik. “CocoInsight”ə baxın adım adım “Projektdə adım-ayrı işləyə bilərsiniz” Görünür Kokosavt Hər bir sahənin necə yaradılması və sahənin arxasında nə ola bilər? İndi indekslər Bu bölmədən istifadə edə bilərsiniz about Tekstiqlər Qazaxıstanla bağlı sorğu necə yaratmaq olar? CocoIndex artıq başqa sorğu interfeysini təmin etmir. Biz SQL yazmaq və ya target depolama üçün sorğu motoru təvəkkül edə bilərik. Bir çox veritabanı öz ən yaxşı praktikaları ilə sorğu implementasiyalarını optimize etmişdir. Soruşturma alanı querying, rearanking və digər arama ilə bağlı funksiyaları üçün mükəmməl çözümlərdir. Əgər bizimlə danışmaq istəyirsinizsə, lütfen bizimlə danışın. . Düşmən Bizə kömək Biz hər zaman yaxşılaşırıq, daha çox xüsusiyyətlər və nümunələr yaxın zamanda gələcək. Əgər bu yazı sizin üçün faydalı olarsa, lütfen bizə bir yıldız verin. Bizi büyütməyə kömək edir. GitHub Okuduğunuz üçün təşəkkür edirəm!