نمط حلقة البحث المتعمق
استعلام ← قراءة ← استخراج ← تركيب ← استعلام مجدد: بحث متعدد القفزات
نمط حلقة البحث المتعمق درس مجاني في AI Agents على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Agents، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Agents 4 دروس في المجموع.
ما حلقة البحث المتعمق؟
حلقة البحث المتعمق نمط للوكيل يبحث فيه الوكيل تكراريًا، ويقرأ، ويحدد فجوات المعرفة، ثم يبحث مجددًا حتى يجمع معلومات كافية لكتابة إجابة شاملة.
وعلى خلاف البحث الواحد، يحاكي هذا النمط طريقة عمل الباحث البشري: استكشاف ← تعلّم ← اكتشاف المجهولات ← التعمق.
نظرة عامة على بنية الحلقة
تتكرر في حلقة البحث المتعمق خمس مراحل:
- الاستعلام الأولي — البحث باستخدام سؤال المستخدم الأصلي
- قراءة أبرز النتائج — استخراج الحقائق الرئيسية من أفضل 3 مصادر
- تحديد الفجوات — ما الأسئلة المهمة التي ما تزال بلا إجابة؟
- استعلامات المتابعة — إنشاء عمليات بحث موجّهة لسد الفجوات
- التركيب — جمع جميع الحقائق التي جُمعت في إجابة نهائية
def deep_research(question, max_iterations=3):
all_facts = []
queries_used = [question]
for iteration in range(max_iterations):
results = search_and_rank(queries_used[-1])
facts = extract_facts(results, question)
all_facts.extend(facts)
gaps = identify_knowledge_gaps(question, all_facts)
if not gaps:
print(f'Research complete after {iteration + 1} iterations')
break
follow_up = generate_follow_up_query(gaps)
queries_used.append(follow_up)
print(f'Iteration {iteration + 1}: {follow_up}')
return synthesize_answer(question, all_facts)المرحلة 1: البحث الأولي
يستخدم البحث الأول السؤال الأصلي للمستخدم. اجلب من 3 إلى 5 نتائج واستخرج محتوى النص الخام. تركز هذه المرحلة على الاتساع، أي تكوين نظرة عامة على مشهد الموضوع.
from tavily import TavilyClient
import os
client = TavilyClient(api_key=os.getenv('TAVILY_API_KEY'))
def initial_search(question, n_results=5):
results = client.search(
query=question,
max_results=n_results,
search_depth='advanced' # deeper extraction for research tasks
)
return results.get('results', [])
# Also capture the direct answer if available
def get_direct_answer(question):
results = client.search(query=question, max_results=3)
return results.get('answer', '') # Tavily's synthesized answerالمرحلة 2: استخراج الحقائق الرئيسية
مرّر نتائج البحث الخام إلى LLM واطلب منه استخراج حقائق محددة قابلة للتحقق وذات صلة بسؤال البحث. ينبغي أن تكون الحقائق ذرية، أي أن تتضمن كل واحدة منها ادعاءً واحدًا.
EXTRACT_FACTS_PROMPT = '''You are a research assistant.
From the search results below, extract all factual claims relevant to the question.
Question: {question}
Search results:
{results_text}
Return a JSON list of facts:
["GPT-4 was released in March 2023",
"GPT-4 supports 128k context window",
...]
Only include verifiable facts. No opinions or summaries. JSON:'''
def extract_facts(results, question):
import json
results_text = '\n\n'.join(
f"[{i+1}] {r['title']}\n{r['content'][:600]}"
for i, r in enumerate(results)
)
response = llm_call(EXTRACT_FACTS_PROMPT.format(
question=question, results_text=results_text
))
return json.loads(response)المرحلة 3: تحديد فجوات المعرفة
بعد كل تكرار للبحث، اسأل LLM: بالنظر إلى ما نعرفه حتى الآن، ما الجوانب المهمة من السؤال الأصلي التي لم تُتناول بعد؟
وتصبح هذه الفجوات استعلامات البحث في الجولة التالية.
GAPS_PROMPT = '''You are a research analyst.
Original research question: {question}
Facts gathered so far:
{facts}
What important aspects of the question are still NOT covered by these facts?
List 2-3 specific knowledge gaps as a JSON array of strings.
If the question is fully answered, return an empty array [].
JSON:'''
def identify_knowledge_gaps(question, facts):
import json
facts_text = '\n'.join(f'- {f}' for f in facts)
response = llm_call(GAPS_PROMPT.format(
question=question, facts=facts_text
))
return json.loads(response)المرحلة 4: إنشاء استعلامات المتابعة
حوّل فجوات المعرفة إلى استعلامات بحث فعالة. فالفجوة مثل «لا نعرف نموذج التسعير» تصبح استعلامًا موجّهًا مثل «تسعير GPT-4 API لكل رمز مميز في 2024».
QUERY_GEN_PROMPT = '''Convert these knowledge gaps into specific web search queries.
Original topic: {topic}
Knowledge gaps:
{gaps}
Return a JSON array of search query strings.
Make each query specific and searchable.
JSON:'''
def generate_follow_up_queries(topic, gaps):
import json
gaps_text = '\n'.join(f'- {g}' for g in gaps)
response = llm_call(QUERY_GEN_PROMPT.format(
topic=topic, gaps=gaps_text
))
queries = json.loads(response)
return queries[:3] # max 3 follow-up queries per iterationمعايير الإنهاء
من دون معايير إنهاء واضحة، ستستمر الحلقة إلى ما لا نهاية. أوقفها عند تحقق أحد الشروط التالية: (1) عدم تحديد أي فجوات، (2) الوصول إلى الحد الأقصى للتكرارات، (3) استنفاد ميزانية الرموز، أو (4) تشابه الحقائق الجديدة بدرجة كبيرة مع الحقائق الموجودة (تناقص العائد).
MAX_ITERATIONS = 4
MAX_FACTS = 50
MIN_NEW_FACTS_TO_CONTINUE = 3
def should_continue(gaps, all_facts, new_facts, iteration):
if iteration >= MAX_ITERATIONS:
print(f'Stopping: max iterations ({MAX_ITERATIONS}) reached')
return False
if not gaps:
print('Stopping: no knowledge gaps found')
return False
if len(all_facts) >= MAX_FACTS:
print(f'Stopping: fact budget ({MAX_FACTS}) reached')
return False
if len(new_facts) < MIN_NEW_FACTS_TO_CONTINUE:
print(f'Stopping: diminishing returns ({len(new_facts)} new facts)')
return False
return True
if __name__ == '__main__':
print('Continue?', should_continue(gaps=['gap1'], all_facts=['f'] * 10, new_facts=['f1', 'f2', 'f3'], iteration=1))
print('Continue?', should_continue(gaps=[], all_facts=['f'] * 10, new_facts=['f1'], iteration=1))
المرحلة 5: تركيب الإجابة النهائية
بعد انتهاء الحلقة، مرّر جميع الحقائق التي جُمعت إلى LLM لتركيبها. تتمثل مهمة LLM في تنظيم الحقائق في إجابة متماسكة ومنظمة جيدًا، مع إسنادها إلى مصادرها.
SYNTHESIS_PROMPT = '''You are a research writer.
Original question: {question}
Researched facts (gathered from {n_iterations} search iterations):
{facts}
Write a comprehensive, well-structured answer based on these facts.
Format with clear sections. Be specific and cite facts where relevant.
If any aspect of the question could not be fully answered, say so.
Answer:'''
def synthesize_answer(question, all_facts, n_iterations):
facts_text = '\n'.join(f'- {f}' for f in all_facts)
return llm_call(SYNTHESIS_PROMPT.format(
question=question,
facts=facts_text,
n_iterations=n_iterations
))تتبع المصادر عبر التكرارات
في حلقة متعددة التكرارات، تجمع حقائق من مصادر مختلفة كثيرة. تتبّع مصدر كل حقيقة حتى تتمكن الإجابة النهائية من الاستشهاد بالمصادر بدقة.
def extract_facts_with_sources(results, question):
import json
PROMPT = '''Extract facts from these search results. For each fact include the source URL.
Question: {question}
Results: {results_text}
Return JSON list:
[{{"fact": "GPT-4 supports 128k context", "source": "https://openai.com/..."}}, ...]
JSON:'''
results_text = '\n\n'.join(
f"[URL: {r['url']}]\n{r['content'][:500]}"
for r in results
)
response = llm_call(PROMPT.format(
question=question, results_text=results_text
))
return json.loads(response)تنفيذ البحث بالتوازي
عندما يكون لديك عدة استعلامات متابعة، شغّلها بالتوازي باستخدام asyncio لتقليل إجمالي وقت البحث. ويمكن أن يؤدي ذلك إلى تقليص مدة حلقة من 3 تكرارات من 30 ثانية إلى 15 ثانية.
import asyncio
async def async_search(client, query):
# Tavily has async support
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(
None,
lambda: client.search(query=query, max_results=3)
)
return result.get('results', [])
async def parallel_search(queries):
tasks = [async_search(client, q) for q in queries]
results_list = await asyncio.gather(*tasks)
# Flatten
return [r for results in results_list for r in results]
# Run in event loop
all_results = asyncio.run(parallel_search(follow_up_queries))إزالة التكرار من الحقائق
غالبًا ما تذكر المصادر المختلفة الحقيقة نفسها بعبارات مختلفة. أزل التكرار من الحقائق باستخدام تشابه التضمينات قبل التركيب، لتجنب تكرار المعلومات نفسها عدة مرات في الإجابة النهائية.
def deduplicate_facts(facts, similarity_threshold=0.92):
if not facts:
return facts
# Get embeddings for all facts
embeddings = [embed(f) for f in facts]
unique_indices = [0] # always keep first
for i in range(1, len(facts)):
is_duplicate = False
for j in unique_indices:
sim = cosine_similarity(embeddings[i], embeddings[j])
if sim > similarity_threshold:
is_duplicate = True
break
if not is_duplicate:
unique_indices.append(i)
unique_facts = [facts[i] for i in unique_indices]
print(f'Deduplicated: {len(facts)} -> {len(unique_facts)} facts')
return unique_factsاختبار المعرفة
ما شرط الإنهاء الصحيح لحلقة بحث متعمق عند عدم العثور على فجوات معرفية؟
مراجعة: نمط حلقة البحث المتعمق
يتبع نمط حلقة البحث المتعمق التسلسل التالي: البحث ← استخراج الحقائق ← العثور على الفجوات ← إنشاء استعلامات المتابعة ← التكرار ← التركيب. وهذا يحاكي طريقة عمل الباحث البشري.
تشمل قرارات التصميم الرئيسية: معايير الإنهاء (الحد الأقصى للتكرارات، وعدم وجود فجوات، وتناقص العائد)، وتتبع المصادر لإسناد المعلومات، والبحث المتوازي لزيادة السرعة، وإزالة التكرار من الحقائق قبل التركيب. حدّد الحلقة في 3 إلى 4 تكرارات لتحقيق توازن بين العمق والتكلفة وزمن الاستجابة.
الأسئلة الشائعة
هل درس «نمط حلقة البحث المتعمق» مجاني؟
نعم — نص درس «نمط حلقة البحث المتعمق» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Agents، انتقل إلى CoddyKit PRO. تتضمن دورة AI Agents 4 دروس في المجموع.
ماذا ستتعلم في «نمط حلقة البحث المتعمق»؟
استعلام ← قراءة ← استخراج ← تركيب ← استعلام مجدد: بحث متعدد القفزات تتمرن على AI Agents مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ AI Agents؟
لا تُشترط خبرة سابقة. AI Agents على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «نمط حلقة البحث المتعمق»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس AI Agents هذا؟
نعم. كل درس في AI Agents يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- Tavily وSerpAPI للبحث باستخدام الوكلاء
- ترتيب نتائج البحث وتصفيتها
- نمط حلقة البحث المتعمق
- دمج البحث على الويب مع RAG