chore: import upstream snapshot with attribution
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,352 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Hybrid Search Example for Local Deep Research
|
||||
|
||||
This example demonstrates how to combine multiple search sources:
|
||||
1. Multiple named retrievers for different document types
|
||||
2. Combining custom retrievers with web search
|
||||
3. Analyzing and comparing sources from different origins
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
from langchain_core.retrievers import Document, BaseRetriever
|
||||
from langchain_community.vectorstores import FAISS
|
||||
from langchain_ollama import OllamaEmbeddings
|
||||
|
||||
from local_deep_research.api import quick_summary, detailed_research
|
||||
from local_deep_research.api.settings_utils import create_settings_snapshot
|
||||
|
||||
|
||||
class TechnicalDocsRetriever(BaseRetriever):
|
||||
"""Mock retriever for technical documentation."""
|
||||
|
||||
def get_relevant_documents(self, query: str) -> List[Document]:
|
||||
"""Return mock technical documents."""
|
||||
# In a real scenario, this would search actual technical docs
|
||||
return [
|
||||
Document(
|
||||
page_content=f"Technical specification for {query}: Implementation requires careful consideration of system architecture, performance metrics, and scalability factors.",
|
||||
metadata={
|
||||
"source": "tech_docs",
|
||||
"type": "specification",
|
||||
"title": f"Technical Spec: {query}",
|
||||
},
|
||||
),
|
||||
Document(
|
||||
page_content=f"Best practices for {query}: Follow industry standards, implement proper error handling, and ensure comprehensive testing coverage.",
|
||||
metadata={
|
||||
"source": "tech_docs",
|
||||
"type": "best_practices",
|
||||
"title": f"Best Practices: {query}",
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
async def aget_relevant_documents(self, query: str) -> List[Document]:
|
||||
"""Async version."""
|
||||
return self.get_relevant_documents(query)
|
||||
|
||||
|
||||
class BusinessDocsRetriever(BaseRetriever):
|
||||
"""Mock retriever for business/strategy documents."""
|
||||
|
||||
def get_relevant_documents(self, query: str) -> List[Document]:
|
||||
"""Return mock business documents."""
|
||||
return [
|
||||
Document(
|
||||
page_content=f"Business implications of {query}: Consider market impact, ROI analysis, and strategic alignment with organizational goals.",
|
||||
metadata={
|
||||
"source": "business_docs",
|
||||
"type": "strategy",
|
||||
"title": f"Business Strategy: {query}",
|
||||
},
|
||||
),
|
||||
Document(
|
||||
page_content=f"Cost-benefit analysis for {query}: Initial investment requirements, expected returns, and risk assessment factors.",
|
||||
metadata={
|
||||
"source": "business_docs",
|
||||
"type": "analysis",
|
||||
"title": f"Cost Analysis: {query}",
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
async def aget_relevant_documents(self, query: str) -> List[Document]:
|
||||
"""Async version."""
|
||||
return self.get_relevant_documents(query)
|
||||
|
||||
|
||||
def create_knowledge_base_retriever() -> BaseRetriever:
|
||||
"""Create a FAISS-based retriever with sample knowledge base documents."""
|
||||
documents = [
|
||||
Document(
|
||||
page_content="Machine learning models require training data, validation strategies, and performance metrics for evaluation.",
|
||||
metadata={"source": "ml_knowledge_base", "topic": "ml_basics"},
|
||||
),
|
||||
Document(
|
||||
page_content="Cloud computing provides scalable infrastructure, reducing capital expenditure and enabling flexible resource allocation.",
|
||||
metadata={
|
||||
"source": "cloud_knowledge_base",
|
||||
"topic": "cloud_benefits",
|
||||
},
|
||||
),
|
||||
Document(
|
||||
page_content="Agile methodology emphasizes iterative development, customer collaboration, and responding to change.",
|
||||
metadata={"source": "project_knowledge_base", "topic": "agile"},
|
||||
),
|
||||
Document(
|
||||
page_content="Data privacy regulations like GDPR require explicit consent, data minimization, and user rights management.",
|
||||
metadata={
|
||||
"source": "compliance_knowledge_base",
|
||||
"topic": "privacy",
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
# Create embeddings and vector store
|
||||
embeddings = OllamaEmbeddings(model="nomic-embed-text")
|
||||
vectorstore = FAISS.from_documents(documents, embeddings)
|
||||
return vectorstore.as_retriever(search_kwargs={"k": 2})
|
||||
|
||||
|
||||
def demonstrate_multiple_retrievers():
|
||||
"""Show how to use multiple named retrievers for different document types."""
|
||||
print("=" * 70)
|
||||
print("MULTIPLE NAMED RETRIEVERS")
|
||||
print("=" * 70)
|
||||
print("""
|
||||
Using multiple specialized retrievers:
|
||||
- Technical documentation retriever
|
||||
- Business documentation retriever
|
||||
- Knowledge base retriever
|
||||
Each provides different perspectives on the same topic.
|
||||
""")
|
||||
|
||||
# Create different retrievers
|
||||
tech_retriever = TechnicalDocsRetriever()
|
||||
business_retriever = BusinessDocsRetriever()
|
||||
kb_retriever = create_knowledge_base_retriever()
|
||||
|
||||
# Configure settings. Registered retrievers are addressable by name;
|
||||
# with the default langgraph-agent strategy, every registered retriever
|
||||
# is also exposed to the research agent as a search tool.
|
||||
settings = create_settings_snapshot(
|
||||
{
|
||||
"search.tool": "knowledge_base", # Primary retriever
|
||||
}
|
||||
)
|
||||
|
||||
# Use multiple retrievers in research
|
||||
result = quick_summary(
|
||||
query="Implementing machine learning in production",
|
||||
settings_snapshot=settings,
|
||||
retrievers={
|
||||
"technical": tech_retriever,
|
||||
"business": business_retriever,
|
||||
"knowledge_base": kb_retriever,
|
||||
},
|
||||
search_tool="knowledge_base", # Primary retriever (others stay available)
|
||||
iterations=2,
|
||||
questions_per_iteration=2,
|
||||
programmatic_mode=True,
|
||||
)
|
||||
|
||||
print("\nResearch Summary (first 400 chars):")
|
||||
print(result["summary"][:400] + "...")
|
||||
|
||||
# Analyze sources by type
|
||||
sources = result.get("sources", [])
|
||||
print(f"\nTotal sources found: {len(sources)}")
|
||||
|
||||
# Group sources by retriever
|
||||
source_types = {}
|
||||
for source in sources:
|
||||
if isinstance(source, dict):
|
||||
source_type = source.get("metadata", {}).get("source", "unknown")
|
||||
else:
|
||||
source_type = "other"
|
||||
source_types[source_type] = source_types.get(source_type, 0) + 1
|
||||
|
||||
print("\nSources by retriever:")
|
||||
for stype, count in source_types.items():
|
||||
print(f" - {stype}: {count} sources")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def demonstrate_retriever_plus_web():
|
||||
"""Show how to combine custom retrievers with web search."""
|
||||
print("\n" + "=" * 70)
|
||||
print("RETRIEVER + WEB SEARCH COMBINATION")
|
||||
print("=" * 70)
|
||||
print("""
|
||||
Combining internal knowledge with web search:
|
||||
- Internal: Custom retriever with proprietary knowledge
|
||||
- External: Wikipedia for general context
|
||||
This provides both specific and general information.
|
||||
""")
|
||||
|
||||
# Create internal knowledge retriever
|
||||
internal_retriever = create_knowledge_base_retriever()
|
||||
|
||||
# Configure settings to use both retriever and web
|
||||
settings = create_settings_snapshot(
|
||||
{
|
||||
"search.tool": "wikipedia", # Also use Wikipedia
|
||||
}
|
||||
)
|
||||
|
||||
# Research combining internal and external sources
|
||||
result = detailed_research(
|
||||
query="Best practices for cloud migration",
|
||||
settings_snapshot=settings,
|
||||
retrievers={
|
||||
"internal_kb": internal_retriever,
|
||||
},
|
||||
search_tool="wikipedia", # Also search Wikipedia
|
||||
search_strategy="source-based",
|
||||
iterations=2,
|
||||
questions_per_iteration=3,
|
||||
programmatic_mode=True,
|
||||
)
|
||||
|
||||
print(f"\nResearch ID: {result['research_id']}")
|
||||
print(f"Summary length: {len(result['summary'])} characters")
|
||||
|
||||
# Analyze source distribution
|
||||
sources = result.get("sources", [])
|
||||
internal_sources = 0
|
||||
external_sources = 0
|
||||
|
||||
for source in sources:
|
||||
if isinstance(source, dict) and "knowledge_base" in str(source):
|
||||
internal_sources += 1
|
||||
else:
|
||||
external_sources += 1
|
||||
|
||||
print("\nSource distribution:")
|
||||
print(f" - Internal knowledge base: {internal_sources} sources")
|
||||
print(f" - External (Wikipedia): {external_sources} sources")
|
||||
|
||||
# Show how different sources complement each other
|
||||
print("\nComplementary insights from hybrid search:")
|
||||
print(
|
||||
" - Internal sources provide: Specific procedures, proprietary knowledge"
|
||||
)
|
||||
print(
|
||||
" - External sources provide: Industry context, general best practices"
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def demonstrate_source_analysis():
|
||||
"""Show how to analyze and compare sources from different origins."""
|
||||
print("\n" + "=" * 70)
|
||||
print("SOURCE ANALYSIS AND COMPARISON")
|
||||
print("=" * 70)
|
||||
print("""
|
||||
Analyzing source quality and relevance:
|
||||
- Track source origins
|
||||
- Compare information consistency
|
||||
- Identify unique insights from each source type
|
||||
""")
|
||||
|
||||
# Create multiple retrievers
|
||||
tech_retriever = TechnicalDocsRetriever()
|
||||
business_retriever = BusinessDocsRetriever()
|
||||
|
||||
settings = create_settings_snapshot(
|
||||
{
|
||||
"search.tool": "wikipedia",
|
||||
}
|
||||
)
|
||||
|
||||
# Run research with detailed source tracking
|
||||
result = quick_summary(
|
||||
query="Artificial intelligence implementation strategies",
|
||||
settings_snapshot=settings,
|
||||
retrievers={
|
||||
"technical": tech_retriever,
|
||||
"business": business_retriever,
|
||||
},
|
||||
search_tool="wikipedia", # Also use web search
|
||||
iterations=2,
|
||||
questions_per_iteration=2,
|
||||
programmatic_mode=True,
|
||||
)
|
||||
|
||||
# Detailed source analysis
|
||||
print("\nSource Analysis:")
|
||||
sources = result.get("sources", [])
|
||||
|
||||
# Categorize sources
|
||||
source_categories = {"technical": [], "business": [], "web": []}
|
||||
|
||||
for source in sources:
|
||||
if isinstance(source, dict):
|
||||
source_type = source.get("metadata", {}).get("source", "")
|
||||
if "tech" in source_type:
|
||||
source_categories["technical"].append(source)
|
||||
elif "business" in source_type:
|
||||
source_categories["business"].append(source)
|
||||
else:
|
||||
source_categories["web"].append(source)
|
||||
else:
|
||||
source_categories["web"].append(source)
|
||||
|
||||
# Report on each category
|
||||
for category, category_sources in source_categories.items():
|
||||
print(f"\n{category.upper()} Sources ({len(category_sources)}):")
|
||||
if category_sources:
|
||||
for i, source in enumerate(category_sources[:2], 1): # Show first 2
|
||||
if isinstance(source, dict):
|
||||
title = source.get("metadata", {}).get("title", "Untitled")
|
||||
print(f" {i}. {title}")
|
||||
else:
|
||||
print(f" {i}. {str(source)[:60]}...")
|
||||
|
||||
# Show findings breakdown
|
||||
findings = result.get("findings", [])
|
||||
print(f"\nTotal findings: {len(findings)}")
|
||||
print("Findings provide integrated insights from all source types")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
"""Run all hybrid search demonstrations."""
|
||||
print("=" * 70)
|
||||
print("LOCAL DEEP RESEARCH - HYBRID SEARCH DEMONSTRATION")
|
||||
print("=" * 70)
|
||||
print("""
|
||||
This example shows how to combine multiple search sources:
|
||||
- Custom retrievers for proprietary knowledge
|
||||
- Web search engines for public information
|
||||
- Source analysis across origins
|
||||
""")
|
||||
|
||||
# Run demonstrations
|
||||
demonstrate_multiple_retrievers()
|
||||
demonstrate_retriever_plus_web()
|
||||
demonstrate_source_analysis()
|
||||
|
||||
print("\n" + "=" * 70)
|
||||
print("KEY TAKEAWAYS")
|
||||
print("=" * 70)
|
||||
print("""
|
||||
1. Multiple Retrievers: Use specialized retrievers for different document types
|
||||
2. Hybrid Search: Combine internal knowledge with web search for comprehensive results
|
||||
3. Source Analysis: Track and analyze sources to understand information origin
|
||||
|
||||
Best Practices:
|
||||
- Name your retrievers descriptively for easy tracking
|
||||
- Balance internal and external sources based on your needs
|
||||
- Use source analysis to verify information consistency
|
||||
""")
|
||||
|
||||
print("\n✓ Hybrid search demonstration complete!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user