全部产品
Search
文档中心

OpenSearch:Bangun aplikasi pencarian percakapan berbasis RAG

更新时间:Aug 06, 2025

AI Search Open Platform menyediakan solusi berbasis Retrieval-Augmented Generation (RAG) untuk pencarian percakapan menggunakan basis pengetahuan. Solusi ini mencakup tiga modul: pra-pemrosesan data, pengambilan data, dan pembuatan respons. AI Search Open Platform menawarkan layanan untuk setiap modul sebagai komponen yang dapat dipilih, seperti penguraian dokumen, pemeringkatan ulang, dan generasi teks. Platform ini memungkinkan Anda menggunakan layanan melalui API. Untuk segera membangun aplikasi pencarian percakapan berbasis RAG, unduh kode ke mesin Anda dan konfigurasikan informasi seperti kunci API, titik akhir API, serta basis pengetahuan lokal.

Cara kerjanya

RAG adalah metode AI yang menggabungkan layanan pengambilan dan pembuatan untuk meningkatkan relevansi, akurasi, dan keragaman konten yang dihasilkan oleh model bahasa besar (LLM). Selama proses pembuatan, RAG pertama-tama mengambil informasi paling relevan dengan input dari sejumlah besar data eksternal atau basis pengetahuan. Informasi tersebut kemudian digunakan sebagai prompt atau konteks dalam LLM untuk menghasilkan output yang lebih tepat dan informatif. Selain parameter internal dan data pelatihan, LLM juga dapat merujuk pada data eksternal terbaru atau informasi spesifik domain guna meningkatkan akurasi output. 基于rag智能问答技术实现图-流程图.jpg

Skenario

Pencarian percakapan berbasis basis pengetahuan cocok untuk berbagai skenario, seperti pengambilan dan ringkasan basis pengetahuan pribadi atau pencarian percakapan di vertikal industri. AI Search Open Platform menggabungkan RAG dan LLM untuk memahami serta menanggapi kueri kompleks dalam bahasa alami berdasarkan basis pengetahuan spesifik domain perusahaan. Solusi berbasis RAG membantu perusahaan dengan cepat mengambil informasi dari file PDF dan WORD, tabel, serta gambar menggunakan bahasa alami.

Prasyarat

Membangun solusi pengembangan berbasis RAG

Catatan

Untuk memudahkan akses pengguna, AI Search Open Platform menawarkan kerangka pengembangan berikut:

  • SDK untuk Java.

  • SDK untuk Python.

  • Jika bisnis Anda menggunakan LangChain, pilih LangChain sebagai kerangka pengembangan.

  • Jika bisnis Anda menggunakan LlamaIndex, pilih LlamaIndex sebagai kerangka pengembangan.

Langkah 1: Pilih layanan dan unduh kode

Pilih layanan algoritma dan kerangka pengembangan yang akan digunakan dalam solusi berbasis RAG sesuai dengan pengetahuan. Dalam contoh ini, SDK untuk Python digunakan.

  1. Masuk ke konsol AI Search Open Platform.

  2. Pilih wilayah Jerman (Frankfurt). Beralih ke AI Search Open Platform dan ruang kerja target.

  3. Di panel navigasi sisi kiri, klik Scene Center. Klik Enter di bagian RAG Scene-Knowledge Base Online Q & A.

    image

  4. Pilih layanan yang ingin Anda gunakan dari daftar drop-down. Kemudian, pada tab Service Details, tinjau detail layanan.

    Catatan
    • Untuk menggunakan layanan algoritma dalam solusi berbasis RAG melalui API, tentukan ID layanan menggunakan service_id. Misalnya, ID layanan penguraian konten dokumen adalah ops-document-analyze-001.

    • Setelah memilih layanan, parameter service_id dalam kode yang dihasilkan dimodifikasi secara otomatis. Setelah mengunduh kode ke lingkungan lokal, ubah parameter service_id dalam kode untuk memanggil layanan lain.

    Layanan

    Deskripsi

    Penguraian konten dokumen

    Layanan penguraian konten dokumen (ops-document-analyze-001) menyediakan layanan penguraian dokumen umum yang mendukung ekstraksi struktur hirarkis logis seperti judul dan segmen, serta teks, tabel, gambar, dan informasi lain dari dokumen tidak terstruktur, dan mengeluarkannya dalam format terstruktur.

    Penguraian konten gambar

    • Layanan pengenalan teks gambar (ops-image-analyze-ocr-001) memungkinkan Anda menggunakan fitur OCR untuk mengenali teks dalam gambar dan mengekstrak informasi teks untuk pengambilan gambar dan pencarian percakapan.

    • Layanan pengenalan konten gambar (ops-image-analyze-vlm-001) memungkinkan Anda menguraikan konten gambar berdasarkan LLM multi-modal. Anda juga dapat menggunakan layanan ini untuk menguraikan teks dalam gambar dan menggunakan teks yang diuraikan untuk pengambilan gambar dan pencarian percakapan.

    Pemotongan dokumen

    Layanan Pemotongan Dokumen Umum (ops-document-split-001): menyediakan layanan pemotongan teks umum. Anda dapat menggunakan layanan ini untuk membagi data terstruktur dalam format HTML, MARKDOWN, dan TXT berdasarkan paragraf, semantik, dan aturan tertentu. Anda juga dapat mengekstrak kode, gambar, dan tabel dari teks kaya.

    Penyematan teks

    • Layanan vektorisasi teks OpenSearch -001 (ops-text-embedding-001): menyediakan layanan vektorisasi teks yang mendukung lebih dari 40 bahasa. Panjang maksimum teks input dapat mencapai 300 token, dan dimensi vektor yang dihasilkan adalah 1.536.

    • Layanan Vektorisasi Teks Universal OpenSearch -002 (ops-text-embedding-002): menyediakan layanan vektorisasi teks yang mendukung lebih dari 100 bahasa. Panjang maksimum teks input dapat mencapai 8.192 token, dan dimensi vektor yang dihasilkan adalah 1.024.

    • Layanan vektorisasi teks OpenSearch-Tiongkok -001 (ops-text-embedding-zh-001): menyediakan layanan vektorisasi teks untuk teks Tiongkok. Panjang maksimum teks input dapat mencapai 1.024 token, dan dimensi vektor yang dihasilkan adalah 768.

    • Layanan vektorisasi teks OpenSearch-Inggris -001 (ops-text-embedding-en-001): menyediakan layanan vektorisasi teks untuk teks Inggris. Panjang maksimum teks input dapat mencapai 512 token, dan dimensi vektor yang dihasilkan adalah 768.

    Penyematan teks jarang

    Vektorisasi teks jarang mengubah data teks menjadi vektor jarang yang menempati lebih sedikit ruang penyimpanan. Anda dapat menggunakan vektor jarang untuk mengekspresikan kata kunci dan informasi tentang istilah yang sering digunakan. Anda dapat melakukan pencarian hibrida dengan menggunakan vektor jarang dan padat untuk meningkatkan kinerja pengambilan.

    Layanan vektorisasi teks jarang OpenSearch-generik (ops-text-sparse-embedding-001): menyediakan layanan vektorisasi teks yang mendukung lebih dari 100 bahasa. Panjang maksimum teks input dapat mencapai 8.192 token.

    Analisis kueri

    Layanan Analisis Kueri 001 (ops-query-analyze-001): menyediakan layanan analisis kueri umum berbasis LLM untuk memahami niat pengguna dan memperluas pertanyaan serupa.

    Mesin pencari

    • Elasticsearch Alibaba Cloud adalah layanan cloud sepenuhnya dikelola dan siap pakai yang dikembangkan berdasarkan Elasticsearch open source. Sepenuhnya kompatibel dengan fitur open source, Elasticsearch Alibaba Cloud mendukung metode penagihan bayar sesuai pemakaian dan menyediakan ketersediaan siap pakai.

      Catatan

      Jika Anda memilih Elasticsearch Alibaba Cloud sebagai mesin pencari, layanan vektorisasi teks jarang tidak tersedia karena masalah kompatibilitas. Dalam hal ini, kami sarankan Anda menggunakan layanan vektorisasi teks.

    • OpenSearch Vector Search Edition adalah mesin pencari vektor terdistribusi berskala besar yang dikembangkan oleh Alibaba Group. OpenSearch Vector Search Edition mendukung berbagai algoritma pencarian vektor dan berkinerja baik dalam pengambilan tingkat tinggi. Anda dapat menggunakan OpenSearch Vector Search Edition untuk pembuatan indeks skala besar dan pengambilan secara hemat biaya. Fitur berikut didukung: penskalabilitas horizontal dan penggabungan indeks, pembuatan indeks pipeline, kueri waktu nyata saat pembuatan, dan pembaruan dinamis data waktu nyata.

      Catatan

      Untuk menggunakan OpenSearch Vector Search Edition, ganti konfigurasi mesin dan kode dalam solusi.

    Pemeringkatan ulang

    Model pengaturan ulang BGE (ops-bge-reranker-larger): menyediakan layanan penilaian dokumen umum. Anda dapat menggunakan layanan ini untuk menilai dokumen berdasarkan kueri dan relevansi konten, mengurutkan dokumen secara menurun berdasarkan skor, dan kemudian mengembalikan skor.

    LLM

    • OpenSearch-Qwen-Turbo: Menggunakan qwen-turbo sebagai model dasar, dengan penyempurnaan model supervisi, peningkatan augmentasi pengambilan, dan pengurangan bahaya.

    • Qwen-Turbo: Model tercepat dan paling hemat biaya dalam seri Qwen, cocok untuk tugas sederhana. Untuk informasi lebih lanjut, lihat Qwen LLMs.

    • Qwen-Plus: Seimbang dalam kemampuan, dengan efektivitas penalaran, biaya, dan kecepatan antara Qwen-Max dan Qwen-Turbo, cocok untuk tugas yang cukup kompleks. Untuk informasi lebih lanjut, lihat Qwen LLMs.

    • Qwen-Max (qwen-max) adalah model bahasa ultra-besar Qwen yang mendukung ratusan miliar parameter dan berbagai bahasa input seperti Tiongkok dan Inggris. Untuk informasi lebih lanjut, lihat Qwen LLMs.

  5. Setelah memilih layanan, klik After the configuration is completed, enter the code query untuk melihat dan mengunduh kode.

    Kode ini terdiri dari dua bagian: pemrosesan dokumen offline dan pencarian percakapan online dalam solusi berbasis RAG.

    Proses

    Deskripsi

    Prosedur

    Pemrosesan dokumen offline

    Proses ini terdiri dari penguraian dokumen, ekstraksi gambar, pemotongan dokumen, penyematan teks, dan menulis hasil pemrosesan ke indeks Elasticsearch.

    Gunakan fungsi utama document_pipeline_execute untuk melakukan langkah-langkah berikut. Kirim dokumen yang akan diproses dengan menggunakan URL dokumen atau file yang dikodekan Base64.

    1. Uraikan dokumen. Untuk informasi lebih lanjut, lihat Penguraian konten dokumen.

      • Panggil operasi penguraian dokumen asinkron untuk mengekstrak konten dari URL atau mendekode konten dari file yang dikodekan Base64.

      • Buat tugas penguraian dengan fungsi create_async_extraction_task dan polling status penyelesaian tugas dengan fungsi poll_task_result.

    2. Ekstrak gambar. Untuk informasi lebih lanjut, lihat Ekstraksi konten gambar.

      • Panggil operasi penguraian gambar asinkron untuk mengekstrak konten gambar dari URL atau mendekode konten gambar dari file yang dikodekan Base64.

      • Buat tugas penguraian gambar dengan fungsi create_image_analyze_task dan polling status penyelesaian tugas dengan fungsi get_image_analyze_task_status.

    3. Potong dokumen. Untuk informasi lebih lanjut, lihat Pemotongan dokumen.

      • Panggil operasi pemotongan dokumen untuk memotong dokumen yang diuraikan berdasarkan kebijakan tertentu.

      • Gunakan fungsi document_split untuk memotong dokumen. Proses ini mencakup pemotongan teks dan penguraian teks kaya.

    4. Penyematan teks. Untuk informasi lebih lanjut, lihat Penyematan teks.

      • Panggil operasi penyematan teks untuk mengonversi teks yang dipotong menjadi vektor padat.

      • Gunakan fungsi text_embedding untuk menghasilkan vektor embedding setiap potongan.

    5. Tulis hasil pemrosesan ke indeks Elasticsearch. Untuk informasi lebih lanjut, lihat Gunakan fitur pencarian kNN Elasticsearch.

      • Buat indeks Elasticsearch yang konfigurasinya mencakup bidang embedding dan konten.

        Penting

        Saat Anda membuat indeks Elasticsearch, sistem akan menghapus indeks dengan nama yang sama. Untuk mencegah sistem menghapus indeks secara salah, ubah nama indeks dalam kode.

      • Panggil fungsi helpers.async_bulk untuk menulis hasil embedding ke indeks Elasticsearch.

    Pencarian percakapan online

    Proses ini terdiri dari menghasilkan vektor kueri, melakukan analisis kueri, mengambil potongan dokumen yang relevan, memeringkat ulang hasil pencarian, dan menghasilkan jawaban berdasarkan hasil pencarian.

    Gunakan fungsi utama query_pipeline_execute untuk memproses kueri pengguna dan menghasilkan jawaban.

    1. Lakukan penyematan teks pada kueri. Untuk informasi lebih lanjut, lihat Penyematan teks.

      • Panggil operasi vektorisasi teks untuk mengonversi kueri menjadi vektor padat.

      • Gunakan fungsi text_embedding untuk menghasilkan vektor kueri.

    2. Panggil layanan analisis kueri. Untuk informasi lebih lanjut, lihat Analisis kueri.

      Panggil operasi analisis kueri untuk mengidentifikasi niat pengguna dan menghasilkan pertanyaan serupa dengan menganalisis riwayat percakapan.

    3. Ambil potongan yang disematkan. Untuk informasi lebih lanjut, lihat Gunakan fitur pencarian kNN Elasticsearch.

      • Gunakan indeks Elasticsearch untuk mengambil potongan yang disematkan yang mirip dengan vektor kueri.

      • Gunakan operasi pencarian AsyncElasticsearch dan fitur pencarian tetangga terdekat (kNN) untuk mengambil hasil berdasarkan kesamaan vektor.

    4. Peringkat ulang hasil. Untuk informasi lebih lanjut, lihat Layanan peringkat ulang.

      • Panggil operasi peringkat ulang untuk menilai potongan yang diambil dan mengurutkan hasil berdasarkan skor.

      • Panggil fungsi documents_ranking untuk menilai dan memeringkat ulang dokumen berdasarkan vektor kueri.

    5. Panggil operasi pembuatan teks untuk menghasilkan jawaban. Untuk informasi lebih lanjut, lihat Detail API.

      Gunakan layanan pembuatan teks dan panggil fungsi llm_call untuk menghasilkan jawaban berdasarkan hasil yang diambil dan kueri pengguna.

    Pilih Document processing flow dan Online Q & A Process di bawah Code Query. Di editor kode, klik Copy Code atau Download File.

Langkah 2: Uji kode di lingkungan lokal

Setelah mengunduh file kode ke perangkat Anda, tentukan parameter dalam kode. Dalam contoh ini, file online.py dan offline.py diunduh. File online.py digunakan untuk pencarian percakapan online, sedangkan file offline.py digunakan untuk pemrosesan dokumen offline. Tabel berikut menjelaskan parameter.

Bagian

Parameter

Deskripsi

AI Search Open Platform

api_key

Kunci API. Untuk informasi lebih lanjut tentang cara mendapatkan kunci API, lihat Kelola Kunci API.

aisearch_endpoint

Titik akhir API. Untuk informasi lebih lanjut tentang cara mendapatkan titik akhir API, lihat Kueri Titik Akhir Layanan.

Catatan

Anda harus menghapus "http://".

Anda dapat memanggil operasi API melalui Internet atau VPC.

workspace_name

Nama ruang kerja di AI Search Open Platform.

service_id

ID layanan. Untuk memudahkan pengembangan kode, Anda dapat mengonfigurasi layanan dan menentukan ID layanan secara terpisah di file offline.py dan online.py dengan menggunakan parameter service_id_config.

image

Mesin pencari Elasticsearch

es_host

Titik akhir kluster Elasticsearch. Jika Anda ingin mengakses kluster Elasticsearch melalui Internet atau VPC, tambahkan alamat IP perangkat Anda ke daftar putih alamat IP publik atau privat dari kluster Elasticsearch. Untuk informasi lebih lanjut, lihat Konfigurasikan daftar putih alamat IP publik atau privat untuk kluster Elasticsearch.

es_auth

Nama pengguna dan kata sandi yang digunakan untuk mengakses kluster Elasticsearch. Nama pengguna adalah elastic dan kata sandi adalah kata sandi yang Anda tetapkan saat membuat kluster Elasticsearch. Jika Anda lupa kata sandi, Anda dapat menyetel ulang. Untuk informasi lebih lanjut, lihat Setel ulang kata sandi akses untuk kluster Elasticsearch.

Parameter lainnya

Anda tidak perlu memodifikasi parameter lain jika Anda menggunakan kode contoh.

Setelah menentukan parameter, jalankan kode secara terpisah di file offline.py dan online.py menggunakan Python 3.7 atau lebih baru untuk memeriksa apakah jawaban yang dihasilkan benar.

Sebagai contoh, dokumen Apa itu AI Search Open Platform? digunakan sebagai basis pengetahuan. Pertanyaan berikut diajukan berdasarkan dokumen: Fitur apa saja yang disediakan oleh AI Search Open Platform?

Gambar-gambar berikut menunjukkan hasil yang dikembalikan.

  • Hasil pemrosesan dokumen offline

    raglixian.jpg.png

  • Hasil pencarian percakapan online

    ragzaxian.png

  • File kode sumber

    offline.py
    # Tautan offline berbasis RAG-Mesin Elasticsearch
    
    # Persyaratan lingkungan berikut telah dipenuhi:
    # Versi Python 3.7 atau lebih baru telah diinstal.
    # Kluster Elasticsearch versi V8.9 atau lebih baru telah dibuat. Jika Anda ingin membuat kluster Elasticsearch Alibaba Cloud, Anda harus mengaktifkan Elasticsearch Alibaba Cloud terlebih dahulu dan mengonfigurasi daftar putih alamat IP kluster. Untuk informasi lebih lanjut, kunjungi https://www.alibabacloud.com/help/zh/es/user-guide/configure-a-public-or-private-ip-address-whitelist-for-an-elasticsearch-cluster.
    
    # Dependensi berikut telah diinstal:
    # pip install alibabacloud_searchplat20240529
    # pip install elasticsearch
    
    # Konfigurasi AI Search Open Platform
    aisearch_endpoint = "xxx.platform-cn-shanghai.opensearch.aliyuncs.com"
    api_key = "OS-xxx"
    workspace_name = "default"
    service_id_config = {"extract": "ops-document-analyze-001",
                         "split": "ops-document-split-001",
                         "text_embedding": "ops-text-embedding-001",
                         "text_sparse_embedding": "ops-text-sparse-embedding-001",
                         "image_analyze": "ops-image-analyze-ocr-001"}
    
    # Konfigurasi Elasticsearch
    es_host = 'http://es-cn-xxx.public.elasticsearch.aliyuncs.com:9200'
    es_auth = ('elastic', 'xxx')
    
    
    # Tentukan URL dokumen. Dalam contoh ini, dokumen deskripsi produk OpenSearch digunakan.
    document_url = "https://www.alibabacloud.com/help/zh/open-search/search-platform/product-overview/introduction-to-search-platform?spm=a2c4g.11186623.0.0.7ab93526WDzQ8z"
    
    import asyncio
    from typing import List
    from elasticsearch import AsyncElasticsearch
    from elasticsearch import helpers
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_searchplat20240529.client import Client
    from alibabacloud_searchplat20240529.models import GetDocumentSplitRequest, CreateDocumentAnalyzeTaskRequest, \
        CreateDocumentAnalyzeTaskRequestDocument, GetDocumentAnalyzeTaskStatusRequest, \
        GetDocumentSplitRequestDocument, GetTextEmbeddingRequest, GetTextEmbeddingResponseBodyResultEmbeddings, \
        GetTextSparseEmbeddingRequest, GetTextSparseEmbeddingResponseBodyResultSparseEmbeddings, \
        CreateImageAnalyzeTaskRequestDocument, CreateImageAnalyzeTaskRequest, CreateImageAnalyzeTaskResponse, \
        GetImageAnalyzeTaskStatusRequest, GetImageAnalyzeTaskStatusResponse
    
    
    async def poll_task_result(ops_client, task_id, service_id, interval=5):
        while True:
            request = GetDocumentAnalyzeTaskStatusRequest(task_id=task_id)
            response = await ops_client.get_document_analyze_task_status_async(workspace_name, service_id, request)
            status = response.body.result.status
            if status == "PENDING":
                await asyncio.sleep(interval)
            elif status == "SUCCESS":
                return response
            else:
                raise Exception("tugas analisis dokumen gagal")
    
    
    def is_analyzable_url(url:str):
        if not url:
            return False
        image_extensions = {'.jpg', '.jpeg', '.png', '.bmp', '.tiff'}
        return url.lower().endswith(tuple(image_extensions))
    
    
    async def image_analyze(ops_client, url):
        try:
            print("analisis gambar :" + url)
            if url.startswith("//"):
                url = "https:" + url
            if not is_analyzable_url(url):
                print(url + " tidak dapat dianalisis.")
                return url
            image_analyze_service_id = service_id_config["image_analyze"]
            document = CreateImageAnalyzeTaskRequestDocument(
                url=url,
            )
            request = CreateImageAnalyzeTaskRequest(document=document)
            response: CreateImageAnalyzeTaskResponse = ops_client.create_image_analyze_task(workspace_name, image_analyze_service_id, request)
            task_id = response.body.result.task_id
            while True:
                request = GetImageAnalyzeTaskStatusRequest(task_id=task_id)
                response: GetImageAnalyzeTaskStatusResponse = ops_client.get_image_analyze_task_status(workspace_name, image_analyze_service_id, request)
                status = response.body.result.status
                if status == "PENDING":
                    await asyncio.sleep(5)
                elif status == "SUCCESS":
                    return url + response.body.result.data.content
                else:
                    print("kesalahan analisis gambar: " + response.body.result.error)
                    return url
        except Exception as e:
            print(f"Pengecualian analisis gambar : {e}")
    
    
    def chunk_list(lst, chunk_size):
        for i in range(0, len(lst), chunk_size):
            yield lst[i:i + chunk_size]
    
    
    async def write_to_es(doc_list):
        es = AsyncElasticsearch(
            [es_host],
            basic_auth=es_auth,
            verify_certs=False,  # Verifikasi sertifikat SSL tidak digunakan.
            request_timeout=30,
            max_retries=10,
            retry_on_timeout=True
        )
        index_name = 'dense_vertex_index'
    
        # Hapus indeks yang ada.
        if await es.indices.exists(index=index_name):
            await es.indices.delete(index=index_name)
    
        # Buat indeks vektor dan atur bidang embedding ke vektor padat yang dihasilkan, bidang konten ke teks input, dan bidang sumber ke kata kunci.
        index_mappings = {
            "mappings": {
                "properties": {
                    "emb": {
                        "type": "dense_vector",
                        "index": True,
                        "similarity": "cosine",
                        "dims": 1536  # Ubah dimensi berdasarkan output model embedding.
                    },
                    "content": {
                        "type": "text"
                    },
                    "source_doc": {
                        "type": "keyword"
                    }
                }
            }
        }
        await es.indices.create(index=index_name, body=index_mappings)
    
        # Tulis hasil vektorisasi ke indeks yang Anda buat pada langkah sebelumnya.
        actions = []
        for i, doc in enumerate(doc_list):
            action = {
                "_index": index_name,
                "_id": doc['id'],
                "_source": {
                    "emb": doc['embedding'],
                    "content": doc['content'],
                    "source_doc": document_url
                }
            }
            actions.append(action)
    
        try:
            await helpers.async_bulk(es, actions)
        except Exception as e:
            for error in e.errors:
                print(error)
    
        # Periksa apakah hasil vektorisasi ditulis ke indeks.
        await asyncio.sleep(2)
        query = {
            "query": {
                "ids": {
                    "values": [doc_list[0]["id"]]
                }
            }
        }
        res = await es.search(index=index_name, body=query)
        if len(res['hits']['hits']) > 0:
            print("Penulisan ES berhasil")
        await es.close()
    
    
    async def document_pipeline_execute(document_url: str = None, document_base64: str = None, file_name: str = None):
    
        # Hasilkan klien AI Search Open Platform.
        config = Config(bearer_token=api_key, endpoint=aisearch_endpoint, protocol="http")
        ops_client = Client(config=config)
    
        # Langkah 1: Uraikan dokumen.
        document_analyze_request = CreateDocumentAnalyzeTaskRequest(
            document=CreateDocumentAnalyzeTaskRequestDocument(url=document_url, content=document_base64,
                                                              file_name=file_name, file_type='html'))
        document_analyze_response = await ops_client.create_document_analyze_task_async(workspace_name=workspace_name,
                                                                                        service_id=service_id_config[
                                                                                            "extract"],
                                                                                        request=document_analyze_request)
        print("tugas analisis dokumen_id:" + document_analyze_response.body.result.task_id)
        extraction_result = await poll_task_result(ops_client, document_analyze_response.body.result.task_id,
                                                   service_id_config["extract"])
        print("analisis dokumen selesai")
        document_content = extraction_result.body.result.data.content
        content_type = extraction_result.body.result.data.content_type
        # Langkah 2: Pisahkan dokumen.
        document_split_request = GetDocumentSplitRequest(
            GetDocumentSplitRequestDocument(content=document_content, content_type=content_type))
        document_split_result = await ops_client.get_document_split_async(workspace_name, service_id_config["split"],
                                                                          document_split_request)
        print("pemisahan dokumen selesai, jumlah potongan: " + str(len(document_split_result.body.result.chunks))
              + " jumlah teks kaya:" + str(len(document_split_result.body.result.rich_texts)))
    
        # Langkah 3: Lakukan vektorisasi teks.
        # Ekstrak hasil pemisahan. Pemisahan gambar menggunakan layanan analisis gambar untuk mengekstrak teks.
        doc_list = ([{"id": chunk.meta.get("id"), "content": chunk.content} for chunk in
                     document_split_result.body.result.chunks]
                    + [{"id": chunk.meta.get("id"), "content": chunk.content} for chunk in
                       document_split_result.body.result.rich_texts if chunk.meta.get("type") != "image"]
                    + [{"id": chunk.meta.get("id"), "content": await image_analyze(ops_client, chunk.content)} for chunk in
                       document_split_result.body.result.rich_texts if chunk.meta.get("type") == "image"]
                    )
    
        chunk_size = 32  # Maksimal 32 vektor dapat dihasilkan sekaligus.
        all_text_embeddings: List[GetTextEmbeddingResponseBodyResultEmbeddings] = []
        for chunk in chunk_list([text["content"] for text in doc_list], chunk_size):
            response = await ops_client.get_text_embedding_async(workspace_name, service_id_config["text_embedding"],
                                                                 GetTextEmbeddingRequest(chunk))
            all_text_embeddings.extend(response.body.result.embeddings)
    
        all_text_sparse_embeddings: List[GetTextSparseEmbeddingResponseBodyResultSparseEmbeddings] = []
        for chunk in chunk_list([text["content"] for text in doc_list], chunk_size):
            response = await ops_client.get_text_sparse_embedding_async(workspace_name,
                                                                        service_id_config["text_sparse_embedding"],
                                                                        GetTextSparseEmbeddingRequest(chunk,
                                                                                                      input_type="document",
                                                                                                      return_token=True))
            all_text_sparse_embeddings.extend(response.body.result.sparse_embeddings)
    
        for i in range(len(doc_list)):
            doc_list[i]["embedding"] = all_text_embeddings[i].embedding
            doc_list[i]["sparse_embedding"] = all_text_sparse_embeddings[i].embedding
    
        print("vektorisasi teks selesai")
    
        # Langkah 4: Tulis hasil pemrosesan ke mesin Elasticsearch.
        await write_to_es(doc_list)
    
    
    if __name__ == "__main__":
        # Jalankan tugas asinkron.
        #    import nest_asyncio # Jika Anda menjalankan kode di Jupyter Notebook, hapus komentar baris kode ini.
        #    nest_asyncio.apply() # Jika Anda menjalankan kode di Jupyter Notebook, hapus komentar baris kode ini.
        asyncio.run(document_pipeline_execute(document_url))
        # asyncio.run(document_pipeline_execute(document_base64="eHh4eHh4eHg...", file_name="attention.pdf")) #Anda juga dapat menggunakan file yang dikodekan Base64 untuk menentukan dokumen yang akan diproses.
    
    online.py
    # Tautan online berbasis RAG-Mesin Elasticsearch
    
    # Persyaratan lingkungan berikut telah dipenuhi:
    # Versi Python 3.7 atau lebih baru telah diinstal.
    # Kluster Elasticsearch versi V8.9 atau lebih baru telah dibuat. Jika Anda ingin membuat kluster Elasticsearch Alibaba Cloud, Anda harus mengaktifkan Elasticsearch Alibaba Cloud terlebih dahulu dan mengonfigurasi daftar putih alamat IP kluster. Untuk informasi lebih lanjut, kunjungi https://www.alibabacloud.com/help/zh/es/user-guide/configure-a-public-or-private-ip-address-whitelist-for-an-elasticsearch-cluster.
    
    # Dependensi berikut telah diinstal:
    # pip install alibabacloud_searchplat20240529
    # pip install elasticsearch
    
    # Konfigurasi AI Search Open Platform
    api_key = "OS-xxx"
    aisearch_endpoint = "xxx.platform-cn-shanghai.opensearch.aliyuncs.com"
    workspace_name = "default"
    service_id_config = {
        "rank": "ops-bge-reranker-larger",
        "text_embedding": "ops-text-embedding-001",
        "text_sparse_embedding": "ops-text-sparse-embedding-001",
        "llm": "ops-qwen-turbo",
        "query_analyze": "ops-query-analyze-001"
    
    }
    
    # Konfigurasi Elasticsearch
    es_host = 'http://es-cn-xxx.public.elasticsearch.aliyuncs.com:9200'
    es_auth = ('elastic', 'xxx')
    
    # Masukkan kueri pengguna
    user_query = "Fitur apa saja yang disediakan oleh AI Search Open Platform?"
    
    
    import asyncio
    from elasticsearch import AsyncElasticsearch
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_searchplat20240529.client import Client
    from alibabacloud_searchplat20240529.models import GetTextEmbeddingRequest,  \
        GetDocumentRankRequest, GetTextGenerationRequest, GetTextGenerationRequestMessages, \
        GetQueryAnalysisRequest
    
    # Hasilkan klien AI Search Open Platform.
    config = Config(bearer_token=api_key, endpoint=aisearch_endpoint, protocol="http")
    ops_client = Client(config=config)
    
    
    async def es_retrieve(query):
        es = AsyncElasticsearch(
            [es_host],
            basic_auth=es_auth,
            verify_certs=False,
            request_timeout=30,
            max_retries=10,
            retry_on_timeout=True
        )
        index_name = 'dense_vertex_index'
        # Lakukan vektorisasi kueri.
        query_emb_result = await ops_client.get_text_embedding_async(workspace_name, service_id_config["text_embedding"],
                                                                     GetTextEmbeddingRequest(input=[query],
                                                                                             input_type="query"))
        query_emb = query_emb_result.body.result.embeddings[0].embedding
        query = {
            "field": "emb",
            "query_vector": query_emb,
            "k": 5,  # Hasilkan jumlah segmen dokumen.
            "num_candidates": 100  # Parameter ini bekerja dengan cara yang sama seperti parameter efsearch dalam pencarian berbasis Hierarchical Navigable Small World (HNSW).
        }
    
        res = await es.search(index=index_name, knn=query)
        search_results = [item['_source']['content'] for item in res['hits']['hits']]
        await es.close()
        return search_results
    
    
    # Lakukan pencarian percakapan. Inputnya adalah kueri pengguna.
    async def query_pipeline_execute():
    
        # Langkah 1: Lakukan analisis kueri.
        query_analyze_response = ops_client.get_query_analysis(workspace_name, service_id_config['query_analyze'],
                                                               GetQueryAnalysisRequest(query=user_query))
        print("hasil penulisan ulang analisis kueri:" + query_analyze_response.body.result.query)
    
        # Langkah 2: Ambil dokumen.
        all_query_results = []
        user_query_results = await es_retrieve(user_query)
        all_query_results.extend(user_query_results)
        rewrite_query_results = await es_retrieve(query_analyze_response.body.result.query)
        all_query_results.extend(rewrite_query_results)
        for extend_query in query_analyze_response.body.result.queries:
            extend_query_result = await es_retrieve(extend_query)
            all_query_results.extend(extend_query_result)
        # Hilangkan duplikat semua segmen yang diambil.
        remove_duplicate_results = list(set(all_query_results))
    
        # Langkah 3: Panggil operasi pengurutan untuk mengurutkan segmen yang diambil.
        rerank_top_k = 8
        score_results = await ops_client.get_document_rank_async(workspace_name, service_id_config["rank"],GetDocumentRankRequest(remove_duplicate_results, user_query))
        rerank_results = [remove_duplicate_results[item.index] for item in score_results.body.result.scores[:rerank_top_k]]
    
        # Langkah 4: Panggil LLM untuk menghasilkan jawaban.
        docs = '\n'.join([f"<article>{s}</article>" for s in rerank_results])
        messages = [
            GetTextGenerationRequestMessages(role="system", content="Anda adalah asisten yang membantu."),
            GetTextGenerationRequestMessages(role="user",
                                             content=f"""Konteks berisi beberapa dokumen independen, masing-masing ditempatkan antara tag <article> dan </article>. Konteks:\n'''{docs}'''
                                             \n\nJawab pertanyaan secara rinci dan terorganisir berdasarkan konteks sebelumnya. Pastikan bahwa pertanyaan dijawab dengan memadai berdasarkan konteks. Jika informasi yang diberikan oleh konteks tidak cukup untuk menjawab pertanyaan, kembalikan pesan berikut: Pertanyaan tidak dapat dijawab berdasarkan konteks. Jangan gunakan konten yang tidak termasuk dalam konteks untuk menghasilkan jawaban. Pastikan setiap pernyataan dalam jawaban didukung oleh konten yang sesuai dalam konteks. Jawab pertanyaan dalam bahasa Cina.
                                             \nPertanyaan:'''{user_query}'''""""")
        ]
        response = await ops_client.get_text_generation_async(workspace_name, service_id_config["llm"],
                                                              GetTextGenerationRequest(messages=messages))
        print("Jawaban akhir: ", response.body.result.text)
    
    
    if __name__ == "__main__":
        #    import nest_asyncio # Jika Anda menjalankan kode di Jupyter Notebook, hapus komentar baris kode ini.
        #    nest_asyncio.apply() # Jika Anda menjalankan kode di Jupyter Notebook, hapus komentar baris kode ini.
        asyncio.run(query_pipeline_execute())