feat(docs): v4 hybrid search parameter and examples (#621)

This commit is contained in:
Mahesh Sanikommu 2025-12-18 17:52:20 -08:00 committed by GitHub
parent ff35a6bffc
commit 1dd602c52b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 394 additions and 11 deletions

View file

@ -464,9 +464,232 @@ Combining features for comprehensive results:
</Tab>
</Tabs>
## Comon Use Cases
## Hybrid Search Mode
Hybrid search mode allows you to search both memories and document chunks in a single request. When `searchMode="hybrid"`, results contain objects with either a `memory` key (for memory results) or a `chunk` key (for chunk results).
### Basic Hybrid Search
<Tabs>
<Tab title="TypeScript">
```typescript
const results = await client.search.memories({
q: "machine learning best practices",
searchMode: "hybrid", // Search memories + chunks
limit: 10
});
// Handle mixed results
results.results.forEach(result => {
if ('memory' in result) {
console.log('Memory:', result.memory);
} else if ('chunk' in result) {
console.log('Chunk:', result.chunk);
console.log('From document:', result.documents?.[0]?.title);
}
});
```
</Tab>
<Tab title="Python">
```python
results = client.search.memories(
q="machine learning best practices",
search_mode="hybrid", # Search memories + chunks
limit=10
)
# Handle mixed results
for result in results.results:
if 'memory' in result:
print('Memory:', result['memory'])
elif 'chunk' in result:
print('Chunk:', result['chunk'])
print('From document:', result.get('documents', [{}])[0].get('title'))
```
</Tab>
<Tab title="cURL">
```bash
curl -X POST "https://api.supermemory.ai/v4/search" \
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"q": "machine learning best practices",
"searchMode": "hybrid",
"limit": 10
}'
```
</Tab>
</Tabs>
### When to Use Hybrid Mode
Use hybrid mode when:
- You want comprehensive search across both memories and documents
- Memories might not exist for certain queries but document content is available
- You need flexibility to get either memory or document chunk results
- You want a single search endpoint that covers all content types
Use memories-only mode (`searchMode="memories"`) when:
- You only need user memories and preferences
- You want faster, more focused results
- You're building a personalized chatbot that relies on user context
### Handling Mixed Results
When using hybrid mode, you'll receive mixed results. Here's how to process them:
<Tabs>
<Tab title="TypeScript">
```typescript
const results = await client.search.memories({
q: "quantum computing applications",
searchMode: "hybrid",
limit: 10
});
// Separate memory and chunk results
const memoryResults = results.results.filter(r => 'memory' in r);
const chunkResults = results.results.filter(r => 'chunk' in r);
console.log(`Found ${memoryResults.length} memories and ${chunkResults.length} chunks`);
// Process memories
memoryResults.forEach(mem => {
console.log('Memory:', mem.memory);
console.log('Similarity:', mem.similarity);
});
// Process chunks
chunkResults.forEach(chunk => {
console.log('Chunk:', chunk.chunk);
console.log('Document:', chunk.documents?.[0]?.title);
console.log('Similarity:', chunk.similarity);
});
```
</Tab>
<Tab title="Python">
```python
results = client.search.memories(
q="quantum computing applications",
search_mode="hybrid",
limit=10
)
# Separate memory and chunk results
memory_results = [r for r in results.results if 'memory' in r]
chunk_results = [r for r in results.results if 'chunk' in r]
print(f"Found {len(memory_results)} memories and {len(chunk_results)} chunks")
# Process memories
for mem in memory_results:
print('Memory:', mem['memory'])
print('Similarity:', mem['similarity'])
# Process chunks
for chunk in chunk_results:
print('Chunk:', chunk['chunk'])
print('Document:', chunk.get('documents', [{}])[0].get('title'))
print('Similarity:', chunk['similarity'])
```
</Tab>
</Tabs>
### Hybrid Search with All Features
Combining hybrid mode with other features:
<Tabs>
<Tab title="TypeScript">
```typescript
const results = await client.search.memories({
q: "research findings on AI",
searchMode: "hybrid",
containerTag: "research_team",
threshold: 0.7,
rerank: true,
include: {
documents: true,
relatedMemories: true,
summaries: true
},
limit: 10
});
// Results are automatically sorted by similarity
// Memory results have 'memory' field, chunk results have 'chunk' field
results.results.forEach(result => {
if ('memory' in result) {
// Memory result
console.log('Memory:', result.memory);
console.log('Context:', result.context);
} else {
// Chunk result
console.log('Chunk:', result.chunk);
console.log('Document:', result.documents?.[0]);
}
});
```
</Tab>
<Tab title="Python">
```python
results = client.search.memories(
q="research findings on AI",
search_mode="hybrid",
container_tag="research_team",
threshold=0.7,
rerank=True,
include={
"documents": True,
"relatedMemories": True,
"summaries": True
},
limit=10
)
# Results are automatically sorted by similarity
# Memory results have 'memory' field, chunk results have 'chunk' field
for result in results.results:
if 'memory' in result:
# Memory result
print('Memory:', result['memory'])
print('Context:', result.get('context'))
else:
# Chunk result
print('Chunk:', result['chunk'])
print('Document:', result.get('documents', [{}])[0])
```
</Tab>
<Tab title="cURL">
```bash
curl -X POST "https://api.supermemory.ai/v4/search" \
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"q": "research findings on AI",
"searchMode": "hybrid",
"containerTag": "research_team",
"threshold": 0.7,
"rerank": true,
"include": {
"documents": true,
"relatedMemories": true,
"summaries": true
},
"limit": 10
}'
```
</Tab>
</Tabs>
<Note>
**Important**: In hybrid mode, results are automatically merged and sorted by similarity score. Memory results and chunk results are deduplicated - if a chunk is already associated with a memory result, it won't appear as a separate chunk result.
</Note>
## Common Use Cases
- **Chatbots**: Basic search with container tag and low threshold
- **Q&A Systems**: Add reranking for better relevance
- **Knowledge Retrieval**: Include documents and summaries
- **Real-time Search**: Skip rewriting and reranking for maximum speed
- **Hybrid Search**: Use `searchMode="hybrid"` when you need comprehensive search across both memories and documents

View file

@ -194,33 +194,65 @@ Companies like Composio [Rube.app](https://rube.app) use memories search for let
This endpoint works best for conversational AI use cases like chatbots.
</Info>
**Hybrid Search Mode:**
The `/v4/search` endpoint supports a `searchMode` parameter with two options:
- **`"memories"`** (default): Searches only memory entries. Returns results with a `memory` key containing the memory content.
- **`"hybrid"`**: Searches memories first, then falls back to document chunks if needed. Returns mixed results where each result object has either a `memory` key (for memory results) or a `chunk` key (for chunk results from documents).
<Note>
In hybrid mode, results are automatically merged by similarity score and deduplicated. Check for the presence of `memory` or `chunk` keys to distinguish result types.
</Note>
<Tabs>
<Tab title="TypeScript">
```typescript
// Memories search
// Memories search (default mode)
const results = await client.search.memories({
q: "machine learning accuracy",
limit: 5,
containerTag: "research",
threshold: 0.7,
rerank: true
rerank: true,
searchMode: "memories" // Default: only search memories
});
// Hybrid search (memories + chunks)
const hybridResults = await client.search.memories({
q: "machine learning accuracy",
limit: 5,
containerTag: "research",
threshold: 0.7,
searchMode: "hybrid" // Search memories + fallback to chunks
});
```
</Tab>
<Tab title="Python">
```python
# Memories search
# Memories search (default mode)
results = client.search.memories(
q="machine learning accuracy",
limit=5,
container_tag="research",
threshold=0.7,
rerank=True
rerank=True,
search_mode="memories" # Default: only search memories
)
# Hybrid search (memories + chunks)
hybrid_results = client.search.memories(
q="machine learning accuracy",
limit=5,
container_tag="research",
threshold=0.7,
search_mode="hybrid" # Search memories + fallback to chunks
)
```
</Tab>
<Tab title="cURL">
```bash
# Memories search (default mode)
curl -X POST "https://api.supermemory.ai/v4/search" \
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
-H "Content-Type: application/json" \
@ -229,7 +261,20 @@ Companies like Composio [Rube.app](https://rube.app) use memories search for let
"limit": 5,
"containerTag": "research",
"threshold": 0.7,
"rerank": true
"rerank": true,
}'
# Hybrid search (memories + chunks)
curl -X POST "https://api.supermemory.ai/v4/search" \
-H "Authorization: Bearer $SUPERMEMORY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"q": "machine learning accuracy",
"limit": 5,
"containerTag": "research",
"threshold": 0.7,
"rerank": true,
"searchMode": "hybrid"
}'
```
</Tab>
@ -283,7 +328,7 @@ Companies like Composio [Rube.app](https://rube.app) use memories search for let
```
The `/v4/search` endpoint searches through and returns memories.
The `/v4/search` endpoint searches through and returns memories. With `searchMode="hybrid"`, it can also return document chunks when memories aren't found, providing comprehensive search coverage.
## Direct Document Retrieval

View file

@ -205,6 +205,28 @@ These parameters are specific to `client.search.memories()`:
```
</ParamField>
<ParamField query="searchMode" type="string" default="memories">
**Search mode - memories only or hybrid search**
Controls whether to search only memories or also include document chunks:
- **`"memories"`** (default): Searches only memory entries. Returns results with `memory` field.
- **`"hybrid"`**: Searches memories first, then falls back to document chunks if needed. Returns mixed results with either `memory` field (for memory results) or `chunk` field (for chunk results).
<Note>
In hybrid mode, results are automatically merged and deduplicated. Results contain objects with either a `memory` key (for memory results) or a `chunk` key (for chunk results from document search).
</Note>
```typescript
searchMode: "memories" // Only search memories (default)
searchMode: "hybrid" // Search memories + fallback to chunks
```
**When to use hybrid mode:**
- When you want comprehensive search across both memories and documents
- When memories might not exist for certain queries but document content is available
- When you need the flexibility to get either memory or document chunk results
</ParamField>
<ParamField query="containerTag" type="string">
**Filter by single container tag**

View file

@ -114,6 +114,8 @@ Response from `client.search.documents()` and `client.search.execute()`:
Response from `client.search.memories()`:
When `searchMode="memories"` (default), all results are memory entries:
```json
{
"results": [
@ -160,14 +162,101 @@ Response from `client.search.memories()`:
}
```
When `searchMode="hybrid"`, results can contain both memory entries and document chunks. **Memory results have a `memory` key, chunk results have a `chunk` key:**
```json
{
"results": [
{
"id": "mem_xyz789",
"memory": "Complete memory content about quantum computing applications...",
"similarity": 0.87,
"metadata": {
"category": "research",
"topic": "quantum-computing"
},
"updatedAt": "2024-01-18T09:15:00Z",
"version": 3,
"context": {
"parents": [],
"children": []
},
"documents": [
{
"id": "doc_quantum_paper",
"title": "Quantum Computing Applications",
"type": "pdf",
"createdAt": "2024-01-10T08:00:00Z",
"updatedAt": "2024-01-10T08:00:00Z"
}
]
},
{
"id": "chunk_abc123",
"chunk": "This is a chunk of content from a document about quantum computing...",
"similarity": 0.82,
"metadata": {
"category": "research",
"source": "document"
},
"updatedAt": "2024-01-15T10:30:00Z",
"version": 1,
"context": {
"parents": [],
"children": []
},
"documents": [
{
"id": "doc_quantum_research",
"title": "Quantum Computing Research Paper",
"type": "pdf",
"metadata": {
"author": "Dr. Smith"
},
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
]
}
],
"timing": 198,
"total": 2
}
```
<Note>
**Distinguishing Memory vs Chunk Results:**
In hybrid mode, check which key exists on the result object:
- **Memory results**: Have a `memory` key (no `chunk` key)
- **Chunk results**: Have a `chunk` key (no `memory` key)
```typescript
// TypeScript example
results.results.forEach(result => {
if ('memory' in result) {
// This is a memory result
console.log('Memory:', result.memory);
} else if ('chunk' in result) {
// This is a chunk result
console.log('Chunk:', result.chunk);
}
});
```
</Note>
### Memory Result Fields
<ResponseField name="id" type="string">
Unique identifier for the memory entry.
Unique identifier for the memory entry or chunk ID. In hybrid mode, can be either a memory ID (e.g., `mem_xyz789`) or a chunk ID (e.g., `chunk_abc123`).
</ResponseField>
<ResponseField name="memory" type="string">
**Complete memory content**. Unlike document search which returns chunks, memory search returns the full memory text.
<ResponseField name="memory" type="string" optional>
**Complete memory content**. Only present for memory results (when `searchMode="memories"` or when a memory result is returned in hybrid mode). This field is not present for chunk results.
</ResponseField>
<ResponseField name="chunk" type="string" optional>
**Chunk content from a document**. Only present for chunk results when `searchMode="hybrid"`. This field is not present for memory results. Contains the actual text content from the document chunk.
</ResponseField>
<ResponseField name="similarity" type="number" range="0-1">
@ -189,7 +278,11 @@ Response from `client.search.memories()`:
</ResponseField>
<ResponseField name="version" type="number | null" optional>
Version number of this memory entry. Used for tracking memory evolution and relationships.
Version number of this memory entry. Used for tracking memory evolution and relationships. For chunk results, this is typically `1`.
</ResponseField>
<ResponseField name="rootMemoryId" type="string | null" optional>
Root memory ID for memory entries. Only present for memory results. Always `null` for chunk results.
</ResponseField>
<ResponseField name="context" type="object" optional>