In this blog we will walk through a comprehensive example of indexing research papers with extracting different metadata — beyond full text chunking and embedding — and build semantic embeddings for indexing and querying. আমরা আপনাকে খুবই প্রশংসা করব যদি আপনি আপনি যদি এই টিউটোরিয়ালটি উপকারী মনে করেন। ⭐ star GitHub এ CocoIndex GitHub এ CocoIndex কেস ব্যবহার একাডেমিক অনুসন্ধান এবং পুনরুদ্ধার, পাশাপাশি গবেষণা ভিত্তিক এআই এজেন্ট কাগজ সুপারিশ সিস্টেম গবেষণা জ্ঞান গ্রাফ বৈজ্ঞানিক সাহিত্যের সিমেন্টিক বিশ্লেষণ আমরা কী অর্জন করব চলুন এটার দিকে নজর দেই উদাহরণ হিসেবে পিডিএফ এখানে আমরা কি অর্জন করতে চাই: 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. এটি আরও ভাল মেটাডাটা-ভিত্তিক সিমেন্টিক অনুসন্ধান ফলাফলগুলি অনুমোদন করে. উদাহরণস্বরূপ, আপনি শিরোনাম এবং অক্ষরগুলির সাথে টেক্সট অনুরোধগুলি সমন্বয় করতে পারেন. 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 আপনি পুরো কোড খুঁজে পেতে পারেন . এখানে যদি এই নিবন্ধটি আপনাকে সাহায্য করে, দয়া করে আমাদের একটি নক্ষত্র দিন ⭐ এ আমাদের বেড়ে উঠতে সাহায্য করে। গিটহাব মূল উপাদান 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? পূর্বাভাস . Install PostgreSQL CocoIndex uses PostgreSQL internally for incremental processing. . Configure your OpenAI API key বিকল্পভাবে, আমরা Gemini, Ollama, LiteLLM জন্য ন্যাশনাল সমর্থন আছে, চেকআউট . গাইড আপনি আপনার প্রিয় এলএলএম সরবরাহকারী নির্বাচন করতে পারেন এবং সম্পূর্ণরূপে স্থানীয়ভাবে কাজ করতে পারেন। ফ্লো ইনডেক্সিং এই প্রকল্পটি বাস্তব বিশ্বের ব্যবহারের ক্ষেত্রে আরও কাছাকাছি মেটাডাটা বোঝার একটি কিছুটা ব্যাপক উদাহরণ প্রদর্শন করে। আপনি দেখতে পাবেন CocoIndex এর এই নকশাটি 100 লাইন ইন্ডেক্সিং লজিক্যালের মধ্যে অর্জন করা কতটা সহজ - . কোড আমরা যা যা যাচ্ছি তা আরো ভালভাবে পরিচালনা করতে আপনাকে সাহায্য করার জন্য, এখানে একটি প্রবাহ ডিগ্রী রয়েছে। পিডিএফতে কাগজের একটি তালিকা আমদানি করুন। 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. ধাপে ধাপে zoom করবো। কাগজপত্র আমদানি @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), ) একটি টেবিল তৈরি করা হবে যাতে সাব ফিল্ডগুলি ( , ) flow_builder.add_source filename content আমরা উল্লেখ করতে পারি যে আরো বিস্তারিত ডকুমেন্টেশন পুনরুদ্ধার এবং মেটাডাটা সংগ্রহ মৌলিক তথ্যের জন্য প্রথম পৃষ্ঠা মুছে ফেলুন পিডিএফ এর প্রথম পৃষ্ঠা এবং পৃষ্ঠা সংখ্যা অন্তর্ভুক্ত করার জন্য একটি কাস্টম ফাংশন সংজ্ঞায়িত করুন। @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()) এখন এটি আপনার ফ্লোরে যোগ করুন। আমরা প্রক্রিয়াকরণ খরচ সর্বনিম্ন করার জন্য প্রথম পৃষ্ঠা থেকে মেটাডেটা উত্পাদন করি, যেহেতু পুরো পিডিএফটি খুব বড় হতে পারে। with data_scope["documents"].row() as doc: doc["basic_info"] = doc["content"].transform(extract_basic_info) এই ধাপের পরে, আপনি প্রতিটি কাগজের মৌলিক তথ্য পেতে হবে। মৌলিক তথ্য আমরা Marker ব্যবহার করে প্রথম পৃষ্ঠাটি Markdown-এ রূপান্তর করব। বিকল্পভাবে, আপনি সহজেই আপনার প্রিয় পিডিএফ বিশ্লেষক, যেমন ডকলিং যোগ করতে পারেন। একটি মার্কার কনভার্টার ফাংশন সংজ্ঞায়িত করুন এবং এটি ক্যাশ করুন, কারণ এর প্রাথমিককরণ সম্পদ ব্যয়বহুল। এটি নিশ্চিত করে যে একই কনভার্টার ইনস্টিটিউটটি বিভিন্ন ইনপুট ফাইলগুলির জন্য পুনরায় ব্যবহৃত হয়। @cache def get_marker_converter() -> PdfConverter: config_parser = ConfigParser({}) return PdfConverter( create_model_dict(), config=config_parser.generate_config_dict() ) এটি একটি কাস্টম ফাংশনে সংযুক্ত করুন। @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 আপনার ট্রান্সফারেন্সে এটি প্রেরণ করুন with data_scope["documents"].row() as doc: doc["first_page_md"] = doc["basic_info"]["first_page"].transform( pdf_to_markdown ) এই ধাপের পরে, আপনি Markdown ফরম্যাটে প্রতিটি কাগজের প্রথম পৃষ্ঠা থাকতে হবে। LLM এর সাথে মৌলিক তথ্য বের করুন LLM খনির জন্য একটি পরিকল্পনা সংজ্ঞায়িত করুন. CocoIndex জটিল এবং গঠিত পরিকল্পনাগুলির সাথে LLM গঠিত খনির স্বাভাবিকভাবে সমর্থন করে। যদি আপনি নকশা পরিকল্পনা সম্পর্কে আরও জানতে আগ্রহী হন, অনুসরণ করুন . এই নিবন্ধ @dataclasses.dataclass class PaperMetadata: """ Metadata for a paper. """ title: str authors: list[Author] abstract: str এটি প্লাগ ইন করুন একটি ডাটা ক্লাস সংজ্ঞায়িত হয়, CocoIndex স্বয়ংক্রিয়ভাবে ডাটা ক্লাস মধ্যে LLM প্রতিক্রিয়া পাস করবে। 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.", ) ) এই ধাপের পরে, আপনার প্রতিটি কাগজের মেটাডেটা থাকতে হবে। কাগজের মেটাডাটা সংগ্রহ 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"], ) আপনার যা দরকার তা সংগ্রহ করুন :) সংগ্রহ দুই তথ্য লেখক ফিল্ম লেখক ফিল্ম এখানে আমরা একটি অনুসন্ধান কার্যকারিতা তৈরি করার জন্য একটি পৃথক টেবিলে Author → Papers সংগ্রহ করতে চাই। শুধু লেখকের দ্বারা সংগ্রহ করা। 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"], ) কম্পিউটার এবং ইনব্যাডিং সংগ্রহ শিরোনাম doc["title_embedding"] = doc["metadata"]["title"].transform( cocoindex.functions.SentenceTransformerEmbed( model="sentence-transformers/all-MiniLM-L6-v2" ) ) অবরোধ প্রত্যেকটি বস্তুকে আলাদা করে আলাদা করে আলাদা করে আলাদা করে আলাদা করে। কখনও কখনও অবরোধ খুব দীর্ঘ হতে পারে। 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, ) এই ধাপের পরে, আপনাকে প্রতিটি কাগজের বর্ণিত টুকরা থাকতে হবে। প্রত্যেকটি জায়গা তুলে ধরুন এবং তাদের সাজানোর ব্যবস্থা করুন। with doc["abstract_chunks"].row() as chunk: chunk["embedding"] = chunk["text"].transform( cocoindex.functions.SentenceTransformerEmbed( model="sentence-transformers/all-MiniLM-L6-v2" ) ) এই ধাপের পরে, আপনাকে প্রতিটি কাগজের বর্ণিত টুকরাগুলির অন্তর্ভুক্ত করা উচিত। Embeddings সংগ্রহ 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"], ) রপ্তানি অবশেষে, আমরা পোস্টগ্রেসে ডেটা রপ্তানি করি। 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, ) ], ) এই উদাহরণে আমরা PGVector ব্যবহার করি embedding stores/ CocoIndex দিয়ে, আপনি Qdrant মত অন্যান্য সমর্থিত ভেক্টর ডেটাবেসের উপর একটি লাইন সুইচ করতে পারেন, এই দেখুন আরো বিস্তারিত গাইড আমরা ইন্টারফেসগুলি স্ট্যান্ডার্ড করার লক্ষ্য রাখি এবং এটি লেগো তৈরি করার মতো করে। CocoInsight ধাপে ধাপে দেখুন আপনি ধাপে ধাপে প্রকল্পের মাধ্যমে হাঁটতে পারেন দেখুন কোচিং প্রতিটি ক্ষেত্র কিভাবে নির্মাণ করা হয় এবং মঞ্চগুলির পেছনে কী ঘটে। ইন্ডেক্স চান আপনি এই বিভাগে উল্লেখ করতে পারেন সম্পর্কে টেক্সট অন্তর্ভুক্ত কিভাবে অন্তর্ভুক্তির বিরুদ্ধে একটি অনুরোধ তৈরি করবেন বর্তমানে CocoIndex অতিরিক্ত প্রশ্ন ইন্টারফেস সরবরাহ করে না. আমরা SQL লিখতে বা টার্গেট স্টোরেজ দ্বারা প্রশ্ন ইঞ্জিন উপর নির্ভর করতে পারেন. অনেক ডাটাবেস ইতিমধ্যে তাদের নিজস্ব শ্রেষ্ঠ অনুশীলন সঙ্গে অনুরোধ বাস্তবায়ন অপ্টিমাইজ করা হয়েছে অনুসন্ধান স্পেসটি অনুসন্ধান, পুনরায় র্যাংকিং এবং অন্যান্য অনুসন্ধান সম্পর্কিত কার্যকারিতাগুলির জন্য চমৎকার সমাধান রয়েছে। আপনি যদি অনুসন্ধান লিখতে সাহায্য প্রয়োজন, দয়া করে আমাদের সাথে যোগাযোগ করতে বিনামূল্যে অনুভব করুন . বিতর্ক আমাদের সমর্থন আমরা ক্রমাগত উন্নতি করছি, এবং আরও বৈশিষ্ট্য এবং উদাহরণ শীঘ্রই আসছে। যদি এই নিবন্ধটি আপনাকে সাহায্য করে, দয়া করে আমাদের একটি নক্ষত্র দিন ⭐ এ আমাদের বেড়ে উঠতে সাহায্য করে। গিটহাব পড়ার জন্য ধন্যবাদ!