Menggabungkan Carian Web dengan RAG
Pengambilan hibrid: stor vektor setempat + carian web langsung untuk jawapan terkini.
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 routeMenyediakan 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/webSemakan 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.
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
- Tavily dan SerpAPI untuk Carian Ejen
- Menyusun Kedudukan dan Menapis Hasil Carian
- Corak Gelung Penyelidikan Mendalam
- Menggabungkan Carian Web dengan RAG