Skip to content

Commit f59b3c9

Browse files
diberryCopilot
andauthored
docs: add Copilot instruction files for NoSQL vector search samples (#86)
Adds 3 per-path instruction files to `.github/instructions/` that provide context-aware guidance when working on nosql-vector-search-* samples: - vector-search-samples.instructions.md — execution patterns, auth flow, container architecture - cli-examples.instructions.md — CLI invocation per language, env vars, troubleshooting - terminology-and-review.instructions.md — terminology standards, PR review checklist These complement the existing .github/copilot-instructions.md with more detailed, structured guidance scoped to the nosql-* sample directories. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 4812eb0 commit f59b3c9

3 files changed

Lines changed: 455 additions & 0 deletions

File tree

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
---
2+
applyTo: "nosql-*/**"
3+
---
4+
# Running Samples — CLI Invocation (Cosmos DB NoSQL Vector Search)
5+
6+
Environment variables are loaded from a `.env` file in each sample directory. Run `azd up` first to provision infrastructure — the CLI commands below only run data-plane application code.
7+
8+
## Prerequisites
9+
10+
```bash
11+
# 1. Deploy infrastructure (creates account, database, 2 containers with vector policies, RBAC)
12+
azd up
13+
14+
# 2. Copy and populate the .env file in the sample directory
15+
cp sample.env .env
16+
# Edit .env with values from your azd deployment
17+
```
18+
19+
Infrastructure is provisioned once. Both containers (`hotels_diskann`, `hotels_quantizedflat`) persist across runs.
20+
21+
## Environment Variables
22+
23+
Create a `.env` file in the sample directory with these variables:
24+
25+
| Variable | Purpose | Example |
26+
|----------|---------|---------|
27+
| `AZURE_COSMOSDB_ENDPOINT` | Cosmos DB account endpoint | `https://myaccount.documents.azure.com:443/` |
28+
| `AZURE_COSMOSDB_DATABASENAME` | Database name | `Hotels` |
29+
| `AZURE_OPENAI_EMBEDDING_ENDPOINT` | Azure OpenAI endpoint | `https://myoai.openai.azure.com/` |
30+
| `AZURE_OPENAI_EMBEDDING_MODEL` | Embedding model name | `text-embedding-3-small` |
31+
| `AZURE_OPENAI_EMBEDDING_DEPLOYMENT` | Embedding deployment name | `text-embedding-3-small` |
32+
| `AZURE_OPENAI_EMBEDDING_API_VERSION` | API version | `2024-08-01-preview` |
33+
| `DATA_FILE_WITH_VECTORS` | Path to pre-embedded data JSON | `../data/HotelsData_toCosmosDB_Vector.json` |
34+
| `DATA_FILE_WITHOUT_VECTORS` | Path to raw data JSON | `../data/HotelsData_toCosmosDB.JSON` |
35+
| `EMBEDDED_FIELD` | Vector field name | `DescriptionVector` |
36+
| `EMBEDDING_DIMENSIONS` | Vector dimensions | `1536` |
37+
| `VECTOR_ALGORITHM` | Algorithm to use | `diskann` or `quantizedflat` |
38+
| `VECTOR_DISTANCE_FUNCTION` | Distance function | `cosine`, `euclidean`, or `dotproduct` |
39+
| `AZURE_SUBSCRIPTION_ID` | Azure subscription ID | Set by `azd env get-values` |
40+
| `AZURE_TENANT_ID` | Azure AD tenant ID | Set by `azd env get-values` |
41+
| `AZURE_RESOURCE_GROUP` | Resource group name | Set by `azd env get-values` |
42+
| `AZURE_ENV_NAME` | azd environment name | Set by `azd env get-values` |
43+
| `AZURE_LOCATION` | Azure region | Set by `azd env get-values` |
44+
| `AZURE_OPENAI_SERVICE` | Azure OpenAI service name | Set by `azd env get-values` |
45+
46+
## SDK Packages per Language
47+
48+
| Language | Cosmos DB SDK | Azure OpenAI SDK |
49+
|----------|--------------|-----------------|
50+
| TypeScript | `@azure/cosmos` (v4.5+) | `openai` (v5+) |
51+
| .NET | `Microsoft.Azure.Cosmos` | `Azure.AI.OpenAI` |
52+
| Python | `azure-cosmos` | `openai` (v1.57+, NOT v5) |
53+
| Java | `com.azure:azure-cosmos` | `com.azure:azure-ai-openai` |
54+
| Go | `github.com/Azure/azure-sdk-for-go/sdk/data/azcosmos` | `github.com/Azure/azure-sdk-for-go/sdk/ai/azopenai` (v0.7.1) |
55+
56+
## TypeScript / Node.js
57+
58+
```bash
59+
# Install dependencies
60+
npm install
61+
62+
# Build
63+
npm run build
64+
65+
# Run with diskANN container
66+
npm run start:diskann
67+
68+
# Run with quantizedFlat container
69+
npm run start:quantizedflat
70+
71+
# Clean up inserted documents
72+
npm run delete:all
73+
```
74+
75+
The `.env` file is loaded natively via `node --env-file .env` (Node.js 20+). No `dotenv` package needed.
76+
77+
### ESM Module Pattern
78+
79+
TypeScript samples use ESM (`"type": "module"` in `package.json`):
80+
- Requires `.js` extensions in import paths (even for `.ts` source files)
81+
- Uses `import.meta.url` for `__dirname` equivalent
82+
- Requires Node.js 20+
83+
84+
## Python
85+
86+
```bash
87+
# Install dependencies
88+
pip install -r requirements.txt
89+
90+
# Run sample (set env vars before running, or use shell export)
91+
python src/vector_search.py
92+
93+
# Clean up inserted documents
94+
python src/delete_all.py
95+
```
96+
97+
Set `VECTOR_ALGORITHM=diskann` or `VECTOR_ALGORITHM=quantizedflat` as an environment variable (or in `.env` and load via `export $(cat .env | xargs)`) to select the container. Do NOT use `python-dotenv` — use `os.environ` to read env vars.
98+
99+
## Go
100+
101+
```bash
102+
# Run sample (pass env vars at invocation, or source .env first)
103+
# Example: source .env && go run ./cmd/vector-search/...
104+
go run ./cmd/vector-search/...
105+
```
106+
107+
Set `VECTOR_ALGORITHM` as an environment variable before running. Go uses `os.Getenv()` — no dotenv package needed.
108+
109+
## Java
110+
111+
```bash
112+
# Compile and run (env vars passed via shell or system properties)
113+
mvn compile exec:java
114+
```
115+
116+
Configure `VECTOR_ALGORITHM` as an environment variable or system property to select `hotels_diskann` or `hotels_quantizedflat`.
117+
118+
## .NET
119+
120+
```bash
121+
# Run sample (reads appsettings.json + env var overrides)
122+
dotnet run
123+
```
124+
125+
Set overrides as environment variables. `appsettings.json` holds defaults; env vars take precedence. Do NOT use a dotenv package — .NET uses `appsettings.json` natively.
126+
127+
## Loading Variables from `azd` Environment
128+
129+
If you've already run `azd up`, values are available directly from the azd environment:
130+
131+
**Bash:**
132+
```bash
133+
# Load all variables from azd environment
134+
eval $(azd env get-values)
135+
136+
# Then run (TypeScript example)
137+
npm run start:diskann
138+
```
139+
140+
**PowerShell:**
141+
```powershell
142+
# Load all variables from azd environment
143+
azd env get-values | ForEach-Object {
144+
$parts = $_ -split '=', 2
145+
[Environment]::SetEnvironmentVariable($parts[0], $parts[1].Trim('"'))
146+
}
147+
148+
# Then run (TypeScript example)
149+
npm run start:diskann
150+
```
151+
152+
## Expected Output
153+
154+
Samples print results per container:
155+
156+
```
157+
--- Vector Search: hotels_diskann ---
158+
Query: "luxury hotel with ocean view"
159+
Results:
160+
HotelName: Grand Resort & Spa | Rating: 4.8 | SimilarityScore: 0.8234
161+
HotelName: Oceanview Lodge | Rating: 4.5 | SimilarityScore: 0.7891
162+
...
163+
164+
--- Vector Search: hotels_quantizedflat ---
165+
Query: "luxury hotel with ocean view"
166+
Results:
167+
HotelName: Grand Resort & Spa | Rating: 4.8 | SimilarityScore: 0.8234
168+
HotelName: Oceanview Lodge | Rating: 4.5 | SimilarityScore: 0.7891
169+
...
170+
```
171+
172+
Scores should be consistent between algorithms for the same query (ranking may vary slightly due to approximation).
173+
174+
## Troubleshooting
175+
176+
| Error | Cause | Fix |
177+
|-------|-------|-----|
178+
| `401 Unauthorized` | RBAC not assigned | Run `azd up` or assign custom "Write to Azure Cosmos DB for NoSQL data plane" role |
179+
| `Container not found` | Infrastructure not provisioned | Run `azd up` first |
180+
| `disableKeyBasedAuth` error | Using connection string | Use `DefaultAzureCredential` — key auth is disabled |
181+
| Missing module / package not found | Dependencies not installed | Run `npm install` / `pip install -r requirements.txt` / `mvn install` |
182+
| Wrong dimensions error | Mismatched embedding model | Check `EMBEDDING_DIMENSIONS` matches model output (default: `1536`) |
183+
| `.env` not found | Missing config file | Copy `sample.env` to `.env` and populate values |
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
---
2+
applyTo: "nosql-*/**"
3+
---
4+
# Terminology & PR Review Standards — Cosmos DB NoSQL Vector Search
5+
6+
This file captures correct terminology and common review feedback patterns for `nosql-vector-search-*` samples. Apply these rules when writing, reviewing, or editing sample code and documentation.
7+
8+
## Terminology — Use These Exact Phrasings
9+
10+
### Embedding Field Naming
11+
12+
| ✅ Correct | ❌ Wrong | Rule |
13+
|-----------|---------|------|
14+
| `DescriptionVector` | `text_embedding_ada_002` | Use generic field names — NOT model-specific names |
15+
| `vector` | `ada_embedding` | Field names must not encode the model that produced them |
16+
| `embedding` | `text-embedding-3-small-vector` | Model names change; field names are schema-permanent |
17+
18+
The embedding field name is part of the container schema. Using model-specific names creates schema drift when models are upgraded.
19+
20+
### Client Naming
21+
22+
| ✅ Correct | ❌ Wrong |
23+
|-----------|---------|
24+
| Azure OpenAI client | OpenAI client |
25+
| Azure OpenAI embedding | OpenAI embedding |
26+
27+
Always qualify with "Azure" — these samples use Azure OpenAI endpoints, not the public OpenAI API.
28+
29+
### Algorithm Descriptions
30+
31+
| Algorithm | ✅ Correct Description | ❌ Wrong Description |
32+
|-----------|----------------------|---------------------|
33+
| `quantizedFlat` | "uses vector quantization techniques" | "based on DiskANN research" |
34+
| `diskANN` | "graph-based index optimized for large-scale vector search" ||
35+
| `Flat` | "only for test or very small scenarios with small dimensional vectors" | (do not present as a production option) |
36+
37+
For production recommendations: direct users to `quantizedFlat` or `diskANN`. Never present `Flat` as a general-purpose option.
38+
39+
### Recall Accuracy
40+
41+
| ✅ Correct | ❌ Wrong |
42+
|-----------|---------|
43+
| "High recall" | "~100% recall" |
44+
| "Efficient RU consumption at scale" | "efficient memory usage" |
45+
46+
Cosmos DB NoSQL billing is RU-based, not memory-based. Recall guarantees should not be stated as specific percentages.
47+
48+
## SQL Query — Field Name Injection
49+
50+
Vector field names in SQL queries CANNOT use parameter placeholders. `@embeddedField` is not valid for column/field references in Cosmos DB NoSQL SQL.
51+
52+
### ✅ Correct: String interpolation with validation
53+
54+
```typescript
55+
const SAFE_FIELD_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
56+
57+
function buildVectorQuery(embeddedField: string): string {
58+
if (!SAFE_FIELD_NAME.test(embeddedField)) {
59+
throw new Error(`Invalid field name: ${embeddedField}`);
60+
}
61+
return `
62+
SELECT TOP 5
63+
c.HotelName, c.Description, c.Rating,
64+
VectorDistance(c.${embeddedField}, @embedding) AS SimilarityScore
65+
FROM c
66+
ORDER BY VectorDistance(c.${embeddedField}, @embedding)
67+
`;
68+
}
69+
```
70+
71+
### ❌ Wrong: Parameter placeholder for field name
72+
73+
```sql
74+
-- This is NOT valid Cosmos DB NoSQL SQL
75+
SELECT TOP 5 VectorDistance(c.@embeddedField, @embedding) FROM c
76+
```
77+
78+
Always validate the field name against `/^[A-Za-z_][A-Za-z0-9_]*$/` before interpolation to prevent SQL injection.
79+
80+
## Code Review Checklist
81+
82+
### Authentication
83+
- [ ] Uses `DefaultAzureCredential` — NOT connection strings, account keys, or hardcoded credentials
84+
- [ ] No `AccountKey` or `PrimaryKey` references in sample code
85+
- [ ] `CosmosClient` initialized with credential, not connection string
86+
87+
### Container Access
88+
- [ ] Uses `database.container(containerName)` directly
89+
- [ ] Does NOT call `containers.createIfNotExists()`
90+
- [ ] Does NOT call `containers.create()`
91+
- [ ] Does NOT drop or delete containers
92+
93+
### Vector Search
94+
- [ ] Uses `VectorDistance()` SQL function
95+
- [ ] Does NOT use `$search`, `cosmosSearch`, or MongoDB aggregation pipeline
96+
- [ ] Field name injection validated against `/^[A-Za-z_][A-Za-z0-9_]*$/` if field is configurable
97+
- [ ] Query result includes `HotelName`, `Description`, `Rating`, `SimilarityScore`
98+
99+
### Naming
100+
- [ ] Embedding field is `DescriptionVector` or another generic name — NOT model-specific
101+
- [ ] Client variable is named to reflect "Azure OpenAI" (e.g., `azureOpenAIClient`, not `openaiClient`)
102+
- [ ] Container definition variable: use `containerDefinition` not `containerdef`
103+
- [ ] No unused variable declarations
104+
105+
### Algorithms
106+
- [ ] Only `quantizedFlat` and `diskANN` used in production paths
107+
- [ ] `Flat` algorithm marked as test-only if present
108+
- [ ] No references to IVF, HNSW, or other unsupported algorithms
109+
110+
### Bulk Insert
111+
- [ ] TypeScript / Java / .NET: uses `executeBulkOperations()`
112+
- [ ] Python: uses `container.upsert_item()` in a loop
113+
- [ ] Go: uses item-by-item insert
114+
115+
## Common PR Feedback Patterns
116+
117+
| Feedback | Action Required |
118+
|----------|----------------|
119+
| "Field name is model-specific" | Rename to `DescriptionVector` or `vector` |
120+
| "Should say 'Azure OpenAI client'" | Update variable names and comments |
121+
| "quantizedFlat description is wrong" | Change to "uses vector quantization techniques" |
122+
| "Flat algorithm shouldn't be listed for production" | Add caveat: test/very small scenarios only |
123+
| "Don't use '~100% recall'" | Change to "high recall" |
124+
| "Memory usage is wrong metric" | Change to "efficient RU consumption at scale" |
125+
| "`@embeddedField` is not valid SQL" | Use string interpolation with regex validation |
126+
| "`containerdef` should be `containerDefinition`" | Rename variable |
127+
| "Remove unused variable" | Delete the unused declaration |
128+
| "`createIfNotExists` should not be called" | Replace with `database.container(name)` |

0 commit comments

Comments
 (0)