From 8d7aa4b075d9c88085d91ed8be40d3148d6beb14 Mon Sep 17 00:00:00 2001 From: yanqiangmiffy <1185918903@qq.com> Date: Sun, 28 Sep 2025 13:47:45 +0800 Subject: [PATCH 1/5] update --- examples/projects/arxiv/mineru.py | 66 +++++++++ .../projects/arxiv/parse_papers_reason.py | 134 ++++++++++++++++++ .../modules/document/pdf_mineru_parser.py | 16 +-- 3 files changed, 208 insertions(+), 8 deletions(-) create mode 100644 examples/projects/arxiv/mineru.py create mode 100644 examples/projects/arxiv/parse_papers_reason.py diff --git a/examples/projects/arxiv/mineru.py b/examples/projects/arxiv/mineru.py new file mode 100644 index 0000000..377edba --- /dev/null +++ b/examples/projects/arxiv/mineru.py @@ -0,0 +1,66 @@ +import requests +import traceback +from random import randrange + + +def extract(row: dict, + api_base: str = "http://10.208.62.156:6200/api/file/_extract", + name_key: str = "name", + data_key: str = "data", + md_key: str = 'md', + image_key: str = 'images', + method: str = "auto", + response_content: str = "markdown", + **kwargs): + """ + 基于MinerU服务(封装)抽取文件(支持pdf/word等),按指定格式返回(默认markdown) + :param row 待处理的dict记录 + :param api_base 自封装的MinerU服务地址 + :param name_key 待抽取的文件的名称字段,默认为`name` + :param data_key 待抽取的文件内容(bytes)或文件名 + :param md_key 输出的markdown字段名 默认`md` + :param image_key 输出的图片字段名 默认`images` + :param method 抽取的方法,支持text/ocr/auto,默认为auto,表示自动识别 + :param response_content 返回内容类型,支持markdown/json,默认为markdown + """ + if isinstance(api_base, list): + api_base = api_base[randrange(len(api_base))] + + content = row[data_key] + assert isinstance(content, bytes) or isinstance(content, str), f"content field `{data_key}`must be bytes or str" + + filename = row.get(name_key, 'auto_file') + + if isinstance(content, bytes): + files = {'file': (filename, content)} + else: + with open(content, 'rb') as reader: + files = {'file': (filename, reader.read())} + + data = { + 'method': method, + 'response_content': response_content + } + + try: + response = requests.post(api_base, files=files, data=data) + response_data = response.json() + if 'data' in response_data: + data = response_data['data'] + if isinstance(data, dict) and 'extract_data' in data: + row[md_key] = data['extract_data'] + return row + error = response.text + print('ERROR', filename, error, api_base) + row['ERROR'] = error + except: + print('ERROR', filename) + traceback.print_exc() + + return row + + +if __name__ == '__main__': + content = extract({"data": "../../../data/paper/16400599.pdf", "name": "16400599.pdf"}, + api_base="http://10.208.62.156:6201/api/file/_extract") + print(content) diff --git a/examples/projects/arxiv/parse_papers_reason.py b/examples/projects/arxiv/parse_papers_reason.py new file mode 100644 index 0000000..eafedf7 --- /dev/null +++ b/examples/projects/arxiv/parse_papers_reason.py @@ -0,0 +1,134 @@ +import logging +import os + +import torch +from magic_pdf.config.enums import SupportedPdfParseMethod +from magic_pdf.data.data_reader_writer import FileBasedDataWriter, FileBasedDataReader +from magic_pdf.data.dataset import PymuDocDataset +from magic_pdf.model.doc_analyze_by_custom_model import doc_analyze +from tqdm import tqdm + +print(torch.cuda.is_available()) + +# Configure logging +logging.basicConfig( + level=logging.WARNING, + format='%(asctime)s - %(levelname)s - %(message)s', + datefmt='%Y-%m-%d %H:%M:%S' +) +logger = logging.getLogger('pdf_processor') + + +def process_pdf(pdf_path, output_dir): + """ + Process a PDF file and generate various output files. + + Args: + pdf_path: Path to the PDF file + output_dir: Directory where outputs will be saved + """ + pdf_filename = os.path.basename(pdf_path) + base_filename = os.path.splitext(pdf_filename)[0] + + logger.info(f"Processing PDF: {pdf_filename}") + + # Prepare directory structure + images_dir_path = os.path.join(output_dir, "images") + images_dir_name = os.path.basename(images_dir_path) + + os.makedirs(images_dir_path, exist_ok=True) + logger.debug(f"Created images directory: {images_dir_path}") + + # Initialize file writers + image_writer = FileBasedDataWriter(images_dir_path) + md_writer = FileBasedDataWriter(output_dir) + + # Read PDF content + pdf_reader = FileBasedDataReader("") + pdf_bytes = pdf_reader.read(pdf_path) + logger.debug(f"Read {len(pdf_bytes)} bytes from {pdf_filename}") + + # Process PDF + dataset = PymuDocDataset(pdf_bytes) + pdf_type = dataset.classify() + logger.info(f"Detected PDF type: {pdf_type}") + + # Apply appropriate processing based on PDF type + if pdf_type == SupportedPdfParseMethod.OCR: + logger.info(f"Using OCR mode for {pdf_filename}") + inference_result = dataset.apply(doc_analyze, ocr=True) + processing_result = inference_result.pipe_ocr_mode(image_writer) + else: + logger.info(f"Using text mode for {pdf_filename}") + inference_result = dataset.apply(doc_analyze, ocr=False) + processing_result = inference_result.pipe_txt_mode(image_writer) + + # Generate output files + logger.debug("Generating output files") + model_pdf_path = os.path.join(output_dir, "model.pdf") + inference_result.draw_model(model_pdf_path) + logger.debug(f"Created model visualization: {model_pdf_path}") + + model_inference_result = inference_result.get_infer_res() + + layout_pdf_path = os.path.join(output_dir, "layout.pdf") + processing_result.draw_layout(layout_pdf_path) + logger.debug(f"Created layout visualization: {layout_pdf_path}") + + spans_pdf_path = os.path.join(output_dir, "spans.pdf") + processing_result.draw_span(spans_pdf_path) + logger.debug(f"Created spans visualization: {spans_pdf_path}") + + # Generate markdown content + markdown_content = processing_result.get_markdown(images_dir_name) + markdown_path = f"{base_filename}.md" + processing_result.dump_md(md_writer, markdown_path, images_dir_name) + logger.info(f"Created markdown file: {markdown_path}") + + # Generate content list + content_list = processing_result.get_content_list(images_dir_name) + processing_result.dump_content_list(md_writer, "content_list.json", images_dir_name) + logger.debug("Created content list JSON") + + # Generate middle JSON + middle_json = processing_result.get_middle_json() + processing_result.dump_middle_json(md_writer, "middle.json") + logger.debug("Created middle JSON file") + + logger.info(f"Successfully processed {pdf_filename}") + + +def main(): + """Main function to process PDFs across all topic directories.""" + logger.info("Starting PDF processing") + total_pdfs = 0 + processed_pdfs = 0 + pdfs_dir="G:/BaiduNetdiskDownload/Downloader/downloads/pdfs" + pdf_files = [f for f in os.listdir(pdfs_dir) if f.endswith(".pdf")] + total_pdfs += len(pdf_files) + + logger.info(f"Processing : ({len(pdf_files)} PDFs found)") + + for pdf_file in tqdm(pdf_files, desc=f"Processing"): + base_filename = os.path.splitext(pdf_file)[0] + + md_file = os.path.join(pdfs_dir, "output", base_filename, f"{base_filename}.md") + if os.path.exists(md_file): + print("PDF Processed Continue!") + continue + pdf_path = os.path.join(pdfs_dir, pdf_file) + output_dir = os.path.join(pdfs_dir, "output", base_filename) + + os.makedirs(output_dir, exist_ok=True) + + try: + process_pdf(pdf_path, output_dir) + processed_pdfs += 1 + except Exception as e: + logger.error(f"Error processing {pdf_file}: {str(e)}") + + + logger.info(f"PDF processing complete. Processed {processed_pdfs}/{total_pdfs} files.") + +if __name__ == "__main__": + main() diff --git a/trustrag/modules/document/pdf_mineru_parser.py b/trustrag/modules/document/pdf_mineru_parser.py index 3874627..c9bf6d3 100644 --- a/trustrag/modules/document/pdf_mineru_parser.py +++ b/trustrag/modules/document/pdf_mineru_parser.py @@ -301,16 +301,16 @@ def get_markdown_content(self, pdf_path: str, target_lang: str = None) -> Option # 处理单个PDF(使用中文) result = parser.process_single_pdf( - pdf_path="../temp/20250605-Qwen3 Embedding Advancing Text Embedding and.pdf", + pdf_path=r"G:\BaiduNetdiskDownload\Downloader\downloads\pdfs\1806.06034.pdf", output_dir="../output/document", generate_visualizations=True, target_lang='ch' ) - # 批量处理PDF(使用英文) - batch_result = parser.process_batch_pdfs( - pdfs_dir="../temp/", - output_base_dir="../output/", - skip_existing=True, - target_lang='en' - ) + # # 批量处理PDF(使用英文) + # batch_result = parser.process_batch_pdfs( + # pdfs_dir="../temp/", + # output_base_dir="../output/", + # skip_existing=True, + # target_lang='en' + # ) From d7404e5bc6dc24eeaabb1b24982a250ccbbb0eff Mon Sep 17 00:00:00 2001 From: yanqiangmiffy <1185918903@qq.com> Date: Tue, 21 Oct 2025 14:15:08 +0800 Subject: [PATCH 2/5] update@xinference doc --- docs/xinference.md | 9 ++ .../arxiv/{mineru.py => mineru_example.py} | 0 .../projects/arxiv/parse_papers_reason.py | 129 +++++++----------- 3 files changed, 60 insertions(+), 78 deletions(-) rename examples/projects/arxiv/{mineru.py => mineru_example.py} (100%) diff --git a/docs/xinference.md b/docs/xinference.md index e69de29..5eaed9d 100644 --- a/docs/xinference.md +++ b/docs/xinference.md @@ -0,0 +1,9 @@ +docker run -e XINFERENCE_MODEL_SRC=modelscope -p 9998:9997 --gpus all xprobe/xinference: xinference-local -H 0.0.0.0 --log-level debug +docker run \ + -v /.xinference:/root/.xinference \ + -v /.cache/huggingface:/root/.cache/huggingface \ + -v /.cache/modelscope:/root/.cache/modelscope \ + -p 9997:9997 \ + --gpus all \ + xprobe/xinference:v \ + xinference-local -H 0.0.0.0 \ No newline at end of file diff --git a/examples/projects/arxiv/mineru.py b/examples/projects/arxiv/mineru_example.py similarity index 100% rename from examples/projects/arxiv/mineru.py rename to examples/projects/arxiv/mineru_example.py diff --git a/examples/projects/arxiv/parse_papers_reason.py b/examples/projects/arxiv/parse_papers_reason.py index eafedf7..e1c9864 100644 --- a/examples/projects/arxiv/parse_papers_reason.py +++ b/examples/projects/arxiv/parse_papers_reason.py @@ -1,15 +1,9 @@ import logging import os - -import torch -from magic_pdf.config.enums import SupportedPdfParseMethod -from magic_pdf.data.data_reader_writer import FileBasedDataWriter, FileBasedDataReader -from magic_pdf.data.dataset import PymuDocDataset -from magic_pdf.model.doc_analyze_by_custom_model import doc_analyze +import sys +from trustrag.modules.document.pdf_mineru_parser import MineruParser from tqdm import tqdm -print(torch.cuda.is_available()) - # Configure logging logging.basicConfig( level=logging.WARNING, @@ -21,7 +15,7 @@ def process_pdf(pdf_path, output_dir): """ - Process a PDF file and generate various output files. + Process a PDF file using MineruParser and generate various output files. Args: pdf_path: Path to the PDF file @@ -32,90 +26,69 @@ def process_pdf(pdf_path, output_dir): logger.info(f"Processing PDF: {pdf_filename}") - # Prepare directory structure - images_dir_path = os.path.join(output_dir, "images") - images_dir_name = os.path.basename(images_dir_path) - - os.makedirs(images_dir_path, exist_ok=True) - logger.debug(f"Created images directory: {images_dir_path}") - - # Initialize file writers - image_writer = FileBasedDataWriter(images_dir_path) - md_writer = FileBasedDataWriter(output_dir) - - # Read PDF content - pdf_reader = FileBasedDataReader("") - pdf_bytes = pdf_reader.read(pdf_path) - logger.debug(f"Read {len(pdf_bytes)} bytes from {pdf_filename}") - - # Process PDF - dataset = PymuDocDataset(pdf_bytes) - pdf_type = dataset.classify() - logger.info(f"Detected PDF type: {pdf_type}") - - # Apply appropriate processing based on PDF type - if pdf_type == SupportedPdfParseMethod.OCR: - logger.info(f"Using OCR mode for {pdf_filename}") - inference_result = dataset.apply(doc_analyze, ocr=True) - processing_result = inference_result.pipe_ocr_mode(image_writer) - else: - logger.info(f"Using text mode for {pdf_filename}") - inference_result = dataset.apply(doc_analyze, ocr=False) - processing_result = inference_result.pipe_txt_mode(image_writer) - - # Generate output files - logger.debug("Generating output files") - model_pdf_path = os.path.join(output_dir, "model.pdf") - inference_result.draw_model(model_pdf_path) - logger.debug(f"Created model visualization: {model_pdf_path}") - - model_inference_result = inference_result.get_infer_res() - - layout_pdf_path = os.path.join(output_dir, "layout.pdf") - processing_result.draw_layout(layout_pdf_path) - logger.debug(f"Created layout visualization: {layout_pdf_path}") - - spans_pdf_path = os.path.join(output_dir, "spans.pdf") - processing_result.draw_span(spans_pdf_path) - logger.debug(f"Created spans visualization: {spans_pdf_path}") - - # Generate markdown content - markdown_content = processing_result.get_markdown(images_dir_name) - markdown_path = f"{base_filename}.md" - processing_result.dump_md(md_writer, markdown_path, images_dir_name) - logger.info(f"Created markdown file: {markdown_path}") - - # Generate content list - content_list = processing_result.get_content_list(images_dir_name) - processing_result.dump_content_list(md_writer, "content_list.json", images_dir_name) - logger.debug("Created content list JSON") - - # Generate middle JSON - middle_json = processing_result.get_middle_json() - processing_result.dump_middle_json(md_writer, "middle.json") - logger.debug("Created middle JSON file") - - logger.info(f"Successfully processed {pdf_filename}") + # 初始化MineruParser + parser = MineruParser( + lang=['ch', 'en'], # 支持中文和英文 + parse_method='auto', # 自动选择解析方法 + formula_enable=True, # 启用公式解析 + table_enable=True # 启用表格解析 + ) + + try: + # 使用MineruParser处理PDF + result = parser.process_single_pdf( + pdf_path=pdf_path, + output_dir=output_dir, + generate_visualizations=True, # 生成可视化文件 + target_lang='en' # 使用英文作为目标语言 + ) + + if result["status"] == "success": + logger.info(f"Successfully processed {pdf_filename}") + + # 将content.md重命名为{base_filename}.md + original_md_path = os.path.join(output_dir, "content.md") + new_md_path = os.path.join(output_dir, f"{base_filename}.md") + + if os.path.exists(original_md_path): + import shutil + shutil.move(original_md_path, new_md_path) + logger.info(f"Created markdown file: {base_filename}.md") + else: + logger.error(f"Failed to process {pdf_filename}: {result.get('error', 'Unknown error')}") + raise Exception(result.get('error', 'Unknown error')) + + except Exception as e: + logger.error(f"Error processing {pdf_filename}: {str(e)}") + raise def main(): """Main function to process PDFs across all topic directories.""" - logger.info("Starting PDF processing") + logger.info("Starting PDF processing with MineruParser") total_pdfs = 0 processed_pdfs = 0 - pdfs_dir="G:/BaiduNetdiskDownload/Downloader/downloads/pdfs" + pdfs_dir = "G:/BaiduNetdiskDownload/Downloader/downloads/pdfs" + + if not os.path.exists(pdfs_dir): + logger.error(f"Directory not found: {pdfs_dir}") + return + pdf_files = [f for f in os.listdir(pdfs_dir) if f.endswith(".pdf")] total_pdfs += len(pdf_files) - logger.info(f"Processing : ({len(pdf_files)} PDFs found)") + logger.info(f"Processing: ({len(pdf_files)} PDFs found)") - for pdf_file in tqdm(pdf_files, desc=f"Processing"): + for pdf_file in tqdm(pdf_files, desc="Processing"): base_filename = os.path.splitext(pdf_file)[0] + # 只检查{base_filename}.md文件是否存在 md_file = os.path.join(pdfs_dir, "output", base_filename, f"{base_filename}.md") + if os.path.exists(md_file): print("PDF Processed Continue!") continue + pdf_path = os.path.join(pdfs_dir, pdf_file) output_dir = os.path.join(pdfs_dir, "output", base_filename) @@ -127,8 +100,8 @@ def main(): except Exception as e: logger.error(f"Error processing {pdf_file}: {str(e)}") - logger.info(f"PDF processing complete. Processed {processed_pdfs}/{total_pdfs} files.") + if __name__ == "__main__": main() From fb34d1b80ee5bab2b5a3bf72f131a83ad4c5ecd1 Mon Sep 17 00:00:00 2001 From: yanqiangmiffy <1185918903@qq.com> Date: Tue, 21 Oct 2025 14:31:17 +0800 Subject: [PATCH 3/5] xinfernece --- examples/engine/xinference_example.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 examples/engine/xinference_example.py diff --git a/examples/engine/xinference_example.py b/examples/engine/xinference_example.py new file mode 100644 index 0000000..6d89fbd --- /dev/null +++ b/examples/engine/xinference_example.py @@ -0,0 +1,10 @@ +import openai + +client = openai.Client( + api_key="cannot be empty", + base_url="http://:/v1" +) +client.embeddings.create( + model="bge-m3", + input=["What is the capital of China?"] +) \ No newline at end of file From ebd897d58f0cc9ee1bb3b80e79bb56330dad6049 Mon Sep 17 00:00:00 2001 From: yanqiangmiffy <1185918903@qq.com> Date: Tue, 21 Oct 2025 16:21:39 +0800 Subject: [PATCH 4/5] update@update engine example --- examples/engine/milvus_hybrid_example.py | 251 +++++++++++++++++++++++ examples/engine/xinference_example.py | 10 +- 2 files changed, 257 insertions(+), 4 deletions(-) create mode 100644 examples/engine/milvus_hybrid_example.py diff --git a/examples/engine/milvus_hybrid_example.py b/examples/engine/milvus_hybrid_example.py new file mode 100644 index 0000000..aea0bbb --- /dev/null +++ b/examples/engine/milvus_hybrid_example.py @@ -0,0 +1,251 @@ +# 步骤一:安装依赖库 +from langchain_community.document_loaders import WebBaseLoader +from langchain.text_splitter import RecursiveCharacterTextSplitter +from langchain_community.embeddings import DashScopeEmbeddings +from pymilvus import MilvusClient, DataType, Function, FunctionType + +dashscope_api_key = "" +milvus_url = "" +user_name = "root" +password = "" +collection_name = "milvus_overview" +dense_dim = 1536 + +# 步骤二:数据准备 +loader = WebBaseLoader([ + 'https://raw.githubusercontent.com/milvus-io/milvus-docs/refs/heads/v2.5.x/site/en/about/overview.md' +]) + +docs = loader.load() + +text_splitter = RecursiveCharacterTextSplitter(chunk_size=1024, chunk_overlap=256) + +# 使用LangChain将输入文档安照chunk_size切分 +all_splits = text_splitter.split_documents(docs) + +embeddings = DashScopeEmbeddings( + model="text-embedding-v2", dashscope_api_key=dashscope_api_key +) + +text_contents = [doc.page_content for doc in all_splits] + +vectors = embeddings.embed_documents(text_contents) + + +client = MilvusClient( + uri=f"http://{milvus_url}:19530", + token=f"{user_name}:{password}", +) + +schema = MilvusClient.create_schema( + enable_dynamic_field=True, +) + +analyzer_params = { + "type": "english" +} + +# Add fields to schema +schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True, auto_id=True) +schema.add_field(field_name="text", datatype=DataType.VARCHAR, max_length=65535, enable_analyzer=True, analyzer_params=analyzer_params, enable_match=True) +schema.add_field(field_name="sparse_bm25", datatype=DataType.SPARSE_FLOAT_VECTOR) +schema.add_field(field_name="dense", datatype=DataType.FLOAT_VECTOR, dim=dense_dim) + +bm25_function = Function( + name="bm25", + function_type=FunctionType.BM25, + input_field_names=["text"], + output_field_names="sparse_bm25", +) +schema.add_function(bm25_function) + +index_params = client.prepare_index_params() + +# Add indexes +index_params.add_index( + field_name="dense", + index_name="dense_index", + index_type="IVF_FLAT", + metric_type="IP", + params={"nlist": 128}, +) + +index_params.add_index( + field_name="sparse_bm25", + index_name="sparse_bm25_index", + index_type="SPARSE_WAND", + metric_type="BM25" +) + +# Create collection +client.create_collection( + collection_name=collection_name, + schema=schema, + index_params=index_params +) + +data = [ + {"dense": vectors[idx], "text": doc} + for idx, doc in enumerate(text_contents) +] + +# Insert data +res = client.insert( + collection_name=collection_name, + data=data +) + +print(f"生成 {len(vectors)} 个向量,维度:{len(vectors[0])}") + +# 同样,在处理中文文档时,Milvus 2.5版本也支持指定相应的中文分析器。 +# # 定义分词器参数 +# analyzer_params = { +# "type": "chinese" # 指定分词器类型为中文 +# } +# +# # 添加文本字段到 Schema,并启用分词器 +# schema.add_field( +# field_name="text", # 字段名称 +# datatype=DataType.VARCHAR, # 数据类型:字符串(VARCHAR) +# max_length=65535, # 最大长度:65535 字符 +# enable_analyzer=True, # 启用分词器 +# analyzer_params=analyzer_params # 分词器参数 +# ) + +# 步骤三:全文检索 +from pymilvus import MilvusClient + +# 创建Milvus Client。 +client = MilvusClient( + uri="http://c-xxxx.milvus.aliyuncs.com:19530", # Milvus实例的公网地址。 + token=":", # 登录Milvus实例的用户名和密码。 + db_name="default" # 待连接的数据库名称,本文示例为默认的default。 +) + +search_params = { + 'params': {'drop_ratio_search': 0.2}, +} + +full_text_search_res = client.search( + collection_name='milvus_overview', + data=['what makes milvus so fast?'], + anns_field='sparse_bm25', + limit=3, + search_params=search_params, + output_fields=["text"], +) + +for hits in full_text_search_res: + for hit in hits: + print(hit) + print("\n") + +# 步骤四:关键词匹配 +# filter = "TEXT_MATCH(text, 'query') and TEXT_MATCH(text, 'node')" +# +# text_match_res = client.search( +# collection_name="milvus_overview", +# anns_field="dense", +# data=query_embeddings, +# filter=filter, +# search_params={"params": {"nprobe": 10}}, +# limit=2, +# output_fields=["text"] +# ) + +# 步骤五:混合检索与RAG +from pymilvus import MilvusClient +from pymilvus import AnnSearchRequest, RRFRanker +from langchain_community.embeddings import DashScopeEmbeddings +from dashscope import Generation + +# 创建Milvus Client。 +client = MilvusClient( + uri="http://c-xxxx.milvus.aliyuncs.com:19530", # Milvus实例的公网地址。 + token=":", # 登录Milvus实例的用户名和密码。 + db_name="default" # 待连接的数据库名称,本文示例为默认的default。 +) + +collection_name = "milvus_overview" + +# 替换为您的 DashScope API-KEY +dashscope_api_key = "" + +# 初始化 Embedding 模型 +embeddings = DashScopeEmbeddings( + model="text-embedding-v2", # 使用text-embedding-v2模型。 + dashscope_api_key=dashscope_api_key +) + +# Define the query +query = "Why does Milvus run so scalable?" + +# Embed the query and generate the corresponding vector representation +query_embeddings = embeddings.embed_documents([query]) + +# Set the top K result count +top_k = 5 # Get the top 5 docs related to the query + +# Define the parameters for the dense vector search +search_params_dense = { + "metric_type": "IP", + "params": {"nprobe": 2} +} + +# Create a dense vector search request +request_dense = AnnSearchRequest([query_embeddings[0]], "dense", search_params_dense, limit=top_k) + +# Define the parameters for the BM25 text search +search_params_bm25 = { + "metric_type": "BM25" +} + +# Create a BM25 text search request +request_bm25 = AnnSearchRequest([query], "sparse_bm25", search_params_bm25, limit=top_k) + +# Combine the two requests +reqs = [request_dense, request_bm25] + +# Initialize the RRF ranking algorithm +ranker = RRFRanker(100) + +# Perform the hybrid search +hybrid_search_res = client.hybrid_search( + collection_name=collection_name, + reqs=reqs, + ranker=ranker, + limit=top_k, + output_fields=["text"] +) + +# Extract the context from hybrid search results +context = [] +print("Top K Results:") +for hits in hybrid_search_res: # Use the correct variable here + for hit in hits: + context.append(hit['entity']['text']) # Extract text content to the context list + print(hit['entity']['text']) # Output each retrieved document + + +# Define a function to get an answer based on the query and context +def getAnswer(query, context): + prompt = f'''Please answer my question based on the content within: + ``` + {context} + ``` + My question is: {query}. + ''' + # Call the generation module to get an answer + rsp = Generation.call(model='qwen-turbo', prompt=prompt) + return rsp.output.text + +# Get the answer +answer = getAnswer(query, context) + +print(answer) + + +# Expected output excerpt +""" +Milvus is highly scalable due to its cloud-native and highly decoupled system architecture. This architecture allows the system to continuously expand as data grows. Additionally, Milvus supports three deployment modes that cover a wide... +""" \ No newline at end of file diff --git a/examples/engine/xinference_example.py b/examples/engine/xinference_example.py index 6d89fbd..8d1236c 100644 --- a/examples/engine/xinference_example.py +++ b/examples/engine/xinference_example.py @@ -1,10 +1,12 @@ import openai client = openai.Client( - api_key="cannot be empty", - base_url="http://:/v1" + api_key="api-key", + base_url="http://localhost:9997/v1" ) -client.embeddings.create( +response=client.embeddings.create( model="bge-m3", input=["What is the capital of China?"] -) \ No newline at end of file +) +print(type(response.data[0].embedding),len(response.data[0].embedding),response.data[0].embedding,) +# 1024 [-0.031030284240841866, ] \ No newline at end of file From 54f91ca846ec5a61099328408352f05efcf52ad1 Mon Sep 17 00:00:00 2001 From: yanqiangmiffy <1185918903@qq.com> Date: Thu, 4 Dec 2025 16:18:49 +0800 Subject: [PATCH 5/5] update@update docs --- docs/quickstart.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/quickstart.md b/docs/quickstart.md index cf93cb5..b3b193b 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -1,4 +1,4 @@ -## GoMate快速上手教程 +## TrustRAG快速上手教程 ## 🛠️ 安装 @@ -22,7 +22,7 @@ pip install gomate 1. 下载源码 ```shell -git clone https://github.com/gomate-community/GoMate.git +git clone https://github.com/gomate-community/TrustRAG.git ``` 2. 安装依赖