Ejen AI · Pelajaran

Menggabungkan Carian Web dengan RAG

Pengambilan hibrid: stor vektor setempat + carian web langsung untuk jawapan terkini.

Pelajaran 4 daripada 413 langkah

Menggabungkan Carian Web dengan RAG ialah pelajaran Ejen AI percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Ejen AI, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Ejen AI merangkumi sejumlah 4 pelajaran.

Cabaran Pengambilan Semula Hibrid

Kebanyakan ejen dunia sebenar memerlukan dua jenis pengetahuan: pengetahuan domain statik (dokumen syarikat, manual produk, dasar) dan maklumat semasa (berita, harga langsung, peristiwa terkini).

Stor vektor tempatan mengendalikan jenis pertama; carian web mengendalikan jenis kedua. Penggabungan kedua-duanya memberikan kelebihan terbaik daripada setiap sumber.

Seni Bina: RAG Tempatan + Carian Web

Sistem hibrid menghalakan setiap soalan kepada sumber pengambilan semula yang sesuai:

  • Stor vektor (RAG) — dokumen terindeks, pengetahuan stabil, data persendirian
  • Carian web — peristiwa semasa, keluaran terkini, data langsung
  • Kedua-duanya — apabila soalan memerlukan konteks daripada dokumen DAN maklumat semasa
class HybridRetrievalAgent:
    def __init__(self, vector_store, search_client):
        self.vector_store = vector_store  # e.g., ChromaDB or FAISS
        self.search_client = search_client  # e.g., TavilyClient

    def answer(self, question):
        route = self.classify_question(question)

        if route == 'static':
            context = self.vector_store.query(question, n_results=5)
        elif route == 'current':
            context = self.web_search(question)
        else:  # 'both'
            local = self.vector_store.query(question, n_results=3)
            web = self.web_search(question)
            context = local + web

        return self.generate_answer(question, context)

if __name__ == '__main__':
    class DemoAgent(HybridRetrievalAgent):
        def classify_question(self, question):
            return 'static' if 'company' in question.lower() else 'current'
        def web_search(self, question):
            return [('Web result about ' + question, {})]
        def generate_answer(self, question, context):
            return f'Answer using {len(context)} context item(s).'

    class FakeVectorStore:
        def query(self, question, n_results=5):
            return [('Local doc snippet', {})]

    agent = DemoAgent(FakeVectorStore(), search_client=None)
    print(agent.answer('What is our company policy on refunds?'))

Pengelas Penghalaan

Pengelas menentukan sumber pengambilan semula yang hendak digunakan. Anda boleh melaksanakannya sebagai panggilan LLM, set peraturan kata kunci atau pengelas kecil yang dilatih. Penghala berasaskan LLM ialah pilihan yang paling fleksibel.

ROUTING_PROMPT = '''Classify this question into one of three categories:
- "static": answered from company documents, product docs, or stable technical knowledge
- "current": requires up-to-date information (news, prices, recent events, latest releases)
- "both": needs both company context and current information

Question: {question}

Respond with exactly one word: static, current, or both.'''

def classify_question(question):
    response = llm_call(ROUTING_PROMPT.format(question=question))
    route = response.strip().lower()
    if route not in ('static', 'current', 'both'):
        return 'both'  # safe default
    return route

Menyediakan Stor Vektor Tempatan

Untuk pangkalan pengetahuan statik, gunakan ChromaDB — pangkalan data vektor ringan yang berjalan dalam proses. Indekskan dokumen anda sekali; lakukan pertanyaan semasa pelaksanaan.

Pasang dengan pip install chromadb openai.

import chromadb
from chromadb.utils import embedding_functions
import os

client = chromadb.PersistentClient(path='./vector_db')

ef = embedding_functions.OpenAIEmbeddingFunction(
    api_key=os.getenv('OPENAI_API_KEY'),
    model_name='text-embedding-3-small'
)

collection = client.get_or_create_collection(
    name='company_docs',
    embedding_function=ef
)

def index_document(doc_id, text, metadata=None):
    collection.add(
        ids=[doc_id],
        documents=[text],
        metadatas=[metadata or {}]
    )

def local_retrieve(question, n_results=5):
    results = collection.query(
        query_texts=[question],
        n_results=n_results
    )
    return list(zip(results['documents'][0], results['metadatas'][0]))

Pengambilan Maklumat melalui Carian Web

Laluan carian web menggunakan Tavily untuk mendapatkan maklumat semasa. Formatkan hasil secara konsisten supaya hasil tersebut boleh digabungkan dengan hasil RAG tempatan dalam struktur arahan yang sama.

from tavily import TavilyClient
import os

tavily = TavilyClient(api_key=os.getenv('TAVILY_API_KEY'))

def web_retrieve(question, n_results=3):
    results = tavily.search(
        query=question,
        max_results=n_results,
        search_depth='basic'
    )
    # Normalize to same format as local results
    return [
        (
            r['content'][:600],  # text
            {'source': r['url'], 'title': r['title'], 'type': 'web'}  # metadata
        )
        for r in results.get('results', [])
    ]

Menggabungkan Hasil Tempatan dan Web

Apabila kedua-dua sumber digunakan, gabungkan hasil dan tandakan asal setiap hasil. Dengan cara ini, LLM boleh memberikan wajaran yang sesuai — dokumen tempatan untuk fakta khusus syarikat, manakala web untuk data semasa.

def merge_results(local_results, web_results):
    merged = []

    for text, meta in local_results:
        merged.append({
            'content': text,
            'source': meta.get('source', 'internal document'),
            'type': 'local',
            'title': meta.get('title', 'Company Document')
        })

    for text, meta in web_results:
        merged.append({
            'content': text,
            'source': meta.get('source', 'web'),
            'type': 'web',
            'title': meta.get('title', 'Web Result')
        })

    return merged

def format_merged_for_prompt(merged_results):
    parts = []
    for i, r in enumerate(merged_results, 1):
        tag = '[INTERNAL]' if r['type'] == 'local' else '[WEB]'
        parts.append(f'[{i}] {tag} {r["title"]}\n{r["content"]}')
    return '\n\n'.join(parts)

if __name__ == '__main__':
    local = [('Refunds are processed within 5 business days.', {'source': 'handbook', 'title': 'Refund Policy'})]
    web = [('Company X reported Q2 earnings today.', {'source': 'reuters.com', 'title': 'Q2 Earnings'})]
    merged = merge_results(local, web)
    print(format_merged_for_prompt(merged))

Mengesan Soalan yang Memerlukan Maklumat Semasa

Selain pengelas LLM, gunakan heuristik kata kunci untuk mengesan soalan yang memerlukan maklumat semasa. Kaedah ini lebih pantas dan mengelakkan panggilan LLM tambahan bagi kes yang jelas.

CURRENT_EVENTS_SIGNALS = [
    'latest', 'current', 'today', 'now', 'recent',
    'this week', 'this month', 'this year',
    'just released', 'new version', 'updated',
    'price', 'stock', 'news', 'announcement',
    '2024', '2025'
]

STATIC_SIGNALS = [
    'how does', 'what is', 'explain', 'tutorial',
    'documentation', 'our product', 'company policy',
    'internal', 'handbook'
]

def fast_route(question):
    lower = question.lower()
    current_score = sum(1 for s in CURRENT_EVENTS_SIGNALS if s in lower)
    static_score = sum(1 for s in STATIC_SIGNALS if s in lower)

    if current_score > static_score:
        return 'current'
    elif static_score > current_score:
        return 'static'
    else:
        return 'both'

if __name__ == '__main__':
    for q in ['What is our company handbook policy on PTO?', 'What is the latest stock price today?']:
        print(f'{fast_route(q)!r} <- "{q}"')

Mengendalikan Percanggahan antara Sumber

Percanggahan berlaku apabila dokumen tempatan menyatakan sesuatu perkara manakala hasil web menyatakan perkara yang berbeza. Contohnya, dokumen harga dalaman anda menyatakan $50 sebulan tetapi hasil web menyatakan harga telah berubah kepada $80 sebulan.

Arahkan LLM untuk menandakan percanggahan dan mengutamakan sumber web bagi fakta yang sensitif terhadap masa.

HYBRID_ANSWER_PROMPT = '''You are answering a question using two types of sources:
- [INTERNAL] sources: company documents (may be outdated)
- [WEB] sources: current web information

For factual claims about current state (prices, versions, availability):
  PREFER [WEB] sources over [INTERNAL] ones.
For company-specific processes, policies, and architecture:
  PREFER [INTERNAL] sources.

If sources conflict, note the discrepancy in your answer.

Sources:
{sources}

Question: {question}
Answer:'''

def generate_hybrid_answer(question, merged_results):
    sources_text = format_merged_for_prompt(merged_results)
    return llm_call(HYBRID_ANSWER_PROMPT.format(
        sources=sources_text,
        question=question
    ))

Mengesan Keusangan Dokumen Tempatan

Dokumen tempatan menjadi lapuk dari semasa ke semasa. Tambahkan pemeriksaan keusangan: jika dokumen tempatan lebih lama daripada ambang tertentu, sertakan carian web sebagai pelengkap walaupun penghala mengelaskan soalan itu sebagai 'statik'.

from datetime import datetime, timedelta

STALENESS_THRESHOLD_DAYS = 90

def check_staleness(metadata):
    indexed_at = metadata.get('indexed_at')
    if not indexed_at:
        return False  # unknown age — assume fresh
    indexed_date = datetime.fromisoformat(indexed_at)
    age = datetime.now() - indexed_date
    return age > timedelta(days=STALENESS_THRESHOLD_DAYS)

def smart_retrieve(question, route):
    local_results = []
    web_results = []

    if route in ('static', 'both'):
        local_results = local_retrieve(question, n_results=4)
        # Check if any local results are stale
        stale = any(check_staleness(meta) for _, meta in local_results)
        if stale:
            print('Stale local docs — adding web search')
            web_results = web_retrieve(question, n_results=2)

    if route in ('current', 'both'):
        web_results = web_retrieve(question, n_results=3)

    return merge_results(local_results, web_results)

Pemarkahan Keyakinan

Sertakan skor keyakinan pada setiap bahagian konteks yang diambil. Sumber berkeyakinan tinggi (terkini, daripada domain berwibawa, dengan keserupaan benaman yang tinggi) diberikan wajaran yang lebih besar dalam jawapan akhir.

def score_result(result, query_embedding):
    score = 0.5  # base score

    # Recency bonus for web results
    if result.get('type') == 'web':
        pub_date = result.get('published_date', '')
        if '2024' in pub_date or '2025' in pub_date:
            score += 0.2

    # Embedding similarity to query
    if result.get('content'):
        result_emb = embed(result['content'][:500])
        sim = cosine_similarity(query_embedding, result_emb)
        score += sim * 0.3

    # Domain authority
    from urllib.parse import urlparse
    domain = urlparse(result.get('source', '')).netloc
    if any(auth in domain for auth in ['docs.', 'developer.', 'official.']):
        score += 0.1

    return min(score, 1.0)

Aliran Lengkap Pengambilan Semula Hibrid

Apabila semuanya digabungkan: penghalaan pantas → pengambilan semula pintar daripada satu atau kedua-dua sumber → pelengkap berdasarkan keusangan → gabung → skor → formatkan → jana jawapan.

def hybrid_answer(question):
    # 1. Route (fast heuristic first, LLM fallback for ambiguous)
    route = fast_route(question)
    if route == 'both':
        route = classify_question(question)  # LLM for ambiguous cases

    print(f'Route: {route}')

    # 2. Retrieve
    merged = smart_retrieve(question, route)

    if not merged:
        return 'I could not find relevant information to answer your question.'

    # 3. Generate
    answer = generate_hybrid_answer(question, merged)
    return answer

# Usage
print(hybrid_answer('What is our refund policy?'))   # -> static/local
print(hybrid_answer('What is GPT-4 pricing today?')) # -> current/web

Semakan Pengetahuan

Bilakah ejen pengambilan semula hibrid patut mengutamakan hasil carian web berbanding hasil dokumen tempatan?

Imbas Kembali: Menggabungkan Carian Web dengan RAG

Pengambilan semula hibrid menggabungkan stor vektor tempatan (untuk pengetahuan statik, persendirian atau khusus domain) dengan carian web (untuk maklumat awam dan semasa). Pengelas penghalaan mengarahkan setiap soalan kepada sumber yang sesuai — atau kepada kedua-duanya apabila diperlukan.

Teknik utama termasuk penghalaan heuristik pantas menggunakan isyarat kata kunci, pengesanan keusangan dokumen tempatan, arahan penyelesaian percanggahan dalam arahan dan pemarkahan keyakinan untuk memberikan wajaran kepada konteks yang diambil.

Percuma untuk bermula

Pelajari Ejen AI dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
60
Pelajaran
239

Soalan Lazim

Adakah pelajaran “Menggabungkan Carian Web dengan RAG” percuma?

Ya — teks penuh “Menggabungkan Carian Web dengan RAG” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Ejen AI, tingkat taraf kepada CoddyKit PRO. Kursus Ejen AI merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Menggabungkan Carian Web dengan RAG”?

Pengambilan hibrid: stor vektor setempat + carian web langsung untuk jawapan terkini. Anda berlatih Ejen AI menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Ejen AI?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Ejen AI di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.

Berapa lamakah pelajaran “Menggabungkan Carian Web dengan RAG” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Ejen AI ini?

Ya. Setiap pelajaran Ejen AI menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Tavily dan SerpAPI untuk Carian Ejen
  2. Menyusun Kedudukan dan Menapis Hasil Carian
  3. Corak Gelung Penyelidikan Mendalam
  4. Menggabungkan Carian Web dengan RAG
← Kembali ke Ejen AI