Skip to content

Commit a8b8c0f

Browse files
authored
Merge pull request #72 from TamiTakamiya/TamiTakamiya/llamastack-pgvector
Llama Stack PGVector Support
2 parents 1c38b94 + af96b79 commit a8b8c0f

File tree

4 files changed

+104
-10
lines changed

4 files changed

+104
-10
lines changed

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ You can generate the vector database either using
7474
2. [Llama-Index Postgres (PGVector) Vector Store](#postgres-pgvector-vector-store)
7575
3. [Llama-Stack Faiss Vector-IO](#llama-stack-faiss)
7676
4. [Llama-Stack SQLite-vec Vector-IO](#llama-stack-sqlite-vec)
77+
5. [Llama-Stack Postgres (PGVector) Vector Store](#llama-stack-postgres-pgvector-vector-store)
7778

7879
Llama-Index approaches require you to download the embedding model, and we also
7980
recommend it for Llama-Stack targets even though it should work even without
@@ -320,7 +321,54 @@ python scripts/query_rag.py \
320321
-k 5 \
321322
-q "how can I configure a cinder backend"
322323
```
324+
### Llama-Stack Postgres (PGVector) Vector Store
323325
326+
To generate a vector database stored in Postgres (PGVector) for Llama-Stack, run the following
327+
commands:
328+
329+
1. Start Postgres with the pgvector extension by running:
330+
331+
```bash
332+
make start-postgres-debug
333+
```
334+
335+
The `data` folder of Postgres is created at `./postgresql/data`. Note that this command
336+
also creates `./output`, which is not used for the Llama-Stack version while it is used for Llama-Index version.
337+
338+
2. Run:
339+
340+
```bash
341+
POSTGRES_USER=postgres \
342+
POSTGRES_PASSWORD=somesecret \
343+
POSTGRES_HOST=localhost \
344+
POSTGRES_PORT=15432 \
345+
POSTGRES_DATABASE=postgres \
346+
uv run python ./custom_processor.py \
347+
-o ./output \
348+
-f custom_docs/0.1/ \
349+
-md embeddings_model/ \
350+
-mn sentence-transformers/all-mpnet-base-v2 \
351+
-i custom_docs-0_1 \
352+
--vector-store-type llamastack-pgvector
353+
```
354+
355+
Which generates embeddings on PostgreSQL, which can be used for RAG.
356+
357+
3. When you run `query_rag.py` to check some results, specify these environment variables for database access:
358+
359+
```bash
360+
POSTGRES_USER=postgres \
361+
POSTGRES_PASSWORD=somesecret \
362+
POSTGRES_HOST=localhost \
363+
POSTGRES_PORT=15432 \
364+
POSTGRES_DATABASE=postgres \
365+
uv run python scripts/query_rag.py \
366+
-p vector_db/custom_docs/0.1 \
367+
-x custom-docs-0_1 \
368+
-m embeddings_model \
369+
-k 5 \
370+
-q "how can I configure a cinder backend"
371+
```
324372
## Update lockfiles
325373
326374
The lock file is used in this repository:

scripts/query_rag.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,15 @@ def _llama_stack_query(args: argparse.Namespace) -> None: # noqa: C901
194194
"mode": "vector", # "vector", "keyword", or "hybrid". Default "vector"
195195
"score_threshold": 0,
196196
}
197+
vector_stores = cfg.get("registered_resources", {}).get("vector_stores", [])
198+
if not vector_stores:
199+
logging.error("No vector stores found in configuration")
200+
exit(1)
201+
vector_store_id = vector_stores[0]["vector_store_id"]
197202
res = client.vector_io.query(
198-
vector_store_id=args.product_index, query=args.query, params=query_cfg
203+
vector_store_id=vector_store_id,
204+
query=args.query,
205+
params=query_cfg,
199206
)
200207

201208
if len(res.chunks) == 0:
@@ -308,7 +315,9 @@ def _llama_stack_query(args: argparse.Namespace) -> None: # noqa: C901
308315

309316
vector_store_type = args.vector_store_type
310317
if args.vector_store_type == "auto":
311-
if os.path.exists(os.path.join(args.db_path, "metadata.json")):
318+
if os.environ.get("POSTGRES_DATABASE"):
319+
args.vector_store_type = "llamastack-pgvector"
320+
elif os.path.exists(os.path.join(args.db_path, "metadata.json")):
312321
args.vector_store_type = "faiss"
313322
elif os.path.exists(os.path.join(args.db_path, "sqlite-vec_store.db")):
314323
args.vector_store_type = "llamastack-sqlite-vec"

src/lightspeed_rag_content/document_processor.py

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,9 @@ class _LlamaStackDB(_BaseDB):
234234
provider_type: inline::rag-runtime
235235
vector_io:
236236
- config:
237-
persistence:
238-
namespace: vector_io::{provider_type}
239-
backend: kv_rag
237+
{vector_io_cfg}
240238
provider_id: {index_id}
241-
provider_type: inline::{provider_type}
239+
provider_type: {provider_type_prefix}::{provider_type}
242240
storage:
243241
backends:
244242
kv_rag:
@@ -284,6 +282,19 @@ class _LlamaStackDB(_BaseDB):
284282
provider_id: {vector_io_provider_id}
285283
vector_store_id: {vector_store_id}"""
286284

285+
# Template for vector_io/config section
286+
VECTOR_IO_CONFIG_TEMPLATE_FOR_SQLITE = """persistence:
287+
namespace: vector_io::{provider_type}
288+
backend: kv_rag"""
289+
VECTOR_IO_CONFIG_TEMPLATE_FOR_PGVECTOR = """persistence:
290+
namespace: vector_io::{provider_type}
291+
backend: kv_default
292+
host: ${{env.POSTGRES_HOST}}
293+
port: ${{env.POSTGRES_PORT}}
294+
db: ${{env.POSTGRES_DATABASE}}
295+
user: ${{env.POSTGRES_USER}}
296+
password: ${{env.POSTGRES_PASSWORD}}"""
297+
287298
CFG_FILENAME = "llama-stack.yaml"
288299

289300
def __init__(self, config: _Config):
@@ -317,6 +328,7 @@ def __init__(self, config: _Config):
317328
assert config.vector_store_type in ( # noqa: S101
318329
"llamastack-faiss",
319330
"llamastack-sqlite-vec",
331+
"llamastack-pgvector",
320332
)
321333

322334
super().__init__(config)
@@ -363,14 +375,33 @@ def write_yaml_config(
363375
self, index_id: str, filename: str, db_file: str, files_metadata_db_file: str
364376
) -> None:
365377
"""Write a llama-stack configuration file using class templates."""
366-
if self.config.vector_store_type == "llamastack-faiss":
367-
vector_io_cfg = ""
378+
if self.config.vector_store_type == "llamastack-pgvector":
379+
provider_type_prefix = "remote"
380+
required_vars = [
381+
"POSTGRES_USER",
382+
"POSTGRES_PASSWORD",
383+
"POSTGRES_HOST",
384+
"POSTGRES_PORT",
385+
"POSTGRES_DATABASE",
386+
]
387+
missing = [v for v in required_vars if not os.getenv(v)]
388+
if missing:
389+
raise ValueError(
390+
f"Missing required environment variables: {', '.join(missing)}"
391+
)
392+
vector_io_cfg = self.VECTOR_IO_CONFIG_TEMPLATE_FOR_PGVECTOR.format(
393+
provider_type=self.provider_type,
394+
)
368395
else:
369-
vector_io_cfg = "db_path: " + db_file
396+
provider_type_prefix = "inline"
397+
vector_io_cfg = self.VECTOR_IO_CONFIG_TEMPLATE_FOR_SQLITE.format(
398+
provider_type=self.provider_type,
399+
)
370400

371401
with open(filename, "w", encoding="utf-8") as fd:
372402
data = self.TEMPLATE.format(
373403
index_id=index_id,
404+
provider_type_prefix=provider_type_prefix,
374405
provider_type=self.provider_type,
375406
vector_io_cfg=vector_io_cfg,
376407
kv_db_path=db_file,

src/lightspeed_rag_content/utils.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,13 @@ def get_common_arg_parser() -> argparse.ArgumentParser:
121121
parser.add_argument(
122122
"--vector-store-type",
123123
default="faiss",
124-
choices=["faiss", "postgres", "llamastack-faiss", "llamastack-sqlite-vec"],
124+
choices=[
125+
"faiss",
126+
"postgres",
127+
"llamastack-faiss",
128+
"llamastack-sqlite-vec",
129+
"llamastack-pgvector",
130+
],
125131
help="vector store type to be used.",
126132
)
127133
parser.add_argument(

0 commit comments

Comments
 (0)