-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.py
More file actions
106 lines (92 loc) · 3.09 KB
/
Copy pathsearch.py
File metadata and controls
106 lines (92 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
from __future__ import annotations
import json
import uuid
from dataclasses import dataclass, field
from typing import Any, Optional
from dnotifier import DNotifier
@dataclass
class KnowledgeDoc:
title: str
content: str
type: str = "docs"
metadata: dict[str, Any] = field(default_factory=dict)
record_id: Optional[str] = None
async def add_knowledge_base(
notifier: DNotifier, sender_id: str, doc: KnowledgeDoc
) -> Any:
record_id = (doc.record_id or "").strip() or str(uuid.uuid4())
content = f"# {doc.title}\n\n{doc.content}".strip()
return await notifier.add_document(
sender_id=sender_id,
record_id=record_id,
content=content,
doc_type=doc.type or "docs",
metadata={
"title": doc.title,
"source": "semantic-search",
**doc.metadata,
},
)
SAMPLE_SEARCH_DOCS = [
KnowledgeDoc(
record_id="search-vector-overview",
title="Vector search overview",
type="guide",
content=(
"Semantic search finds documents by meaning, not exact keywords. Embeddings map "
"text into vectors; similar meaning yields higher similarity scores. Use "
"minSimilarity to filter weak matches."
),
),
KnowledgeDoc(
record_id="search-indexing",
title="Indexing documents",
type="howto",
content=(
"Index with addDocument. Provide a stable recordId when you may update the same "
"doc later. Keep documents focused on one topic for better retrieval precision."
),
),
KnowledgeDoc(
record_id="search-filters",
title="Search parameters",
type="guide",
content=(
"search accepts query, limit, minSimilarity, and filterbySource. Start with "
"limit 5 and minSimilarity 0.2, then tighten. filterbySource matches document "
"metadata.source when set."
),
),
KnowledgeDoc(
record_id="search-vs-rag",
title="Search vs RAG chat",
type="faq",
content=(
"Semantic search returns ranked chunks. RAG chat (sendAI with useKnowledgeBase) "
"answers in natural language using retrieved context. Use search when you need "
"raw hits; use RAG when you need an answer."
),
),
]
async def seed_search_docs(notifier: DNotifier, sender_id: str) -> None:
for doc in SAMPLE_SEARCH_DOCS:
result = await add_knowledge_base(notifier, sender_id, doc)
print(f"Indexed: {doc.title}", json.dumps(result, default=str))
async def semantic_search(
notifier: DNotifier,
sender_id: str,
query: str,
*,
limit: int = 5,
min_similarity: float = 0.2,
filterby_source: Optional[str] = None,
) -> Any:
return await notifier.search(
sender_id=sender_id,
query=query,
limit=limit,
min_similarity=min_similarity,
filterby_source=filterby_source,
)
async def list_docs(notifier: DNotifier, sender_id: str) -> Any:
return await notifier.list_documents(sender_id=sender_id, limit=50)