<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ca">
	<id>http://wiki.joanillo.org/index.php?action=history&amp;feed=atom&amp;title=RAG%3A_Ingesta</id>
	<title>RAG: Ingesta - Historial de revisió</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.joanillo.org/index.php?action=history&amp;feed=atom&amp;title=RAG%3A_Ingesta"/>
	<link rel="alternate" type="text/html" href="http://wiki.joanillo.org/index.php?title=RAG:_Ingesta&amp;action=history"/>
	<updated>2026-10-16T23:16:54Z</updated>
	<subtitle>Historial de revisió per a aquesta pàgina del wiki</subtitle>
	<generator>MediaWiki 1.34.2</generator>
	<entry>
		<id>http://wiki.joanillo.org/index.php?title=RAG:_Ingesta&amp;diff=299286&amp;oldid=prev</id>
		<title>Joan: Es crea la pàgina amb «__TOC__  =Ingesta de documents=  Anem a fer la ingesta de documents al QDrant (ja sabem fer els chunks). Primer de tot, creem la col·lecció '''josep_pla''' (una sola...».</title>
		<link rel="alternate" type="text/html" href="http://wiki.joanillo.org/index.php?title=RAG:_Ingesta&amp;diff=299286&amp;oldid=prev"/>
		<updated>2026-10-16T14:39:13Z</updated>

		<summary type="html">&lt;p&gt;Es crea la pàgina amb «__TOC__  =Ingesta de documents=  Anem a fer la ingesta de documents al QDrant (ja sabem fer els chunks). Primer de tot, creem la col·lecció &amp;#039;&amp;#039;&amp;#039;josep_pla&amp;#039;&amp;#039;&amp;#039; (una sola...».&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Pàgina nova&lt;/b&gt;&lt;/p&gt;&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
=Ingesta de documents=&lt;br /&gt;
&lt;br /&gt;
Anem a fer la ingesta de documents al QDrant (ja sabem fer els chunks). Primer de tot, creem la col·lecció '''josep_pla''' (una sola vegada, la primera vegada):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -X PUT &amp;quot;http://localhost:6333/collections/josep_pla&amp;quot; \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d '{&lt;br /&gt;
    &amp;quot;vectors&amp;quot;: {&lt;br /&gt;
      &amp;quot;size&amp;quot;: 1024,&lt;br /&gt;
      &amp;quot;distance&amp;quot;: &amp;quot;Cosine&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }'&lt;br /&gt;
&lt;br /&gt;
curl &amp;quot;http://localhost:6333/collections/josep_pla&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sobre la configuració (Default, 1024, Cosine):&lt;br /&gt;
&lt;br /&gt;
* És correcta per a un RAG amb text en català, amb dues condicions.&lt;br /&gt;
* 1024 ha de coincidir exactament amb la dimensió del model d’embeddings. Models multilingües habituals que funcionen bé en català, com BAAI/bge-m3 o intfloat/multilingual-e5-large, generen vectors de 1024 dimensions, així que si fas servir un d’aquests, és correcte. Si algun dia canvies a un model de 768 o 384 dimensions, hauràs d’esborrar la col·lecció i tornar-la a crear amb la mida nova. No es pot modificar. Per comprovar la mida, pots fer len(model.encode(&amp;quot;prova&amp;quot;)) en Python.&lt;br /&gt;
* Cosine és la mètrica adequada per a aquests models, que estan pensats per comparar per similitud de cosinus. El Qdrant normalitza els vectors internament quan fas servir Cosine, així que no cal que els normalitzis tu.&lt;br /&gt;
* ''Default'' vol dir vector sense nom, i és el que crea la comanda de dalt. És el més senzill quan només tens un tipus de vector per document. Això té una conseqüència al codi Python. A l’hora d’inserir i consultar, has de passar el vector directament com a llista (vector=embedding), no com a diccionari amb nom (vector={&amp;quot;nom&amp;quot;: embedding}). Si el teu script ja ho feia així, no cal canviar res.&lt;br /&gt;
&lt;br /&gt;
prompt:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
en un altre chat m'has ajudat a fer un script per fer els splits i chunks de documents. Com a resultat tinc un fitxer JSONL amb els chunks. Per exemple, el primer document que tinc és:&lt;br /&gt;
&lt;br /&gt;
fitxer club_tandem.txt.chunks.jsonl:&lt;br /&gt;
&lt;br /&gt;
{&amp;quot;id&amp;quot;: &amp;quot;27463c80-037a-5bf7-a5a3-9a5ff9e2efe2&amp;quot;, &amp;quot;text&amp;quot;: &amp;quot;CLUB TÀNDEM (T1xC4) — «EL QUADERN GRIS» DE JOSEP PLA, ELS DIETARIS I LA CONSTRUCCIÓ DEL JO\n\nConversa entre Juliana Canet (JC), presentadora, i Marina Porras (MP).&amp;quot;, &amp;quot;metadata&amp;quot;: {&amp;quot;doc_id&amp;quot;: &amp;quot;club_tandem.txt&amp;quot;, &amp;quot;filename&amp;quot;: &amp;quot;club_tandem.txt&amp;quot;, &amp;quot;format&amp;quot;: &amp;quot;txt&amp;quot;, &amp;quot;author&amp;quot;: &amp;quot;Juliana Canet, Marina Porras&amp;quot;, &amp;quot;title&amp;quot;: &amp;quot;EL JO: El quadern gris, de Josep Pla&amp;quot;, &amp;quot;year&amp;quot;: 2025, &amp;quot;description&amp;quot;: &amp;quot;Club Tàndem (T1xC4): La Juliana Canet i la Marina Porras conversen sobre El quadern gris de Josep Pla, els dietaris i la construcció del jo.&amp;quot;, &amp;quot;url&amp;quot;: &amp;quot;https://www.youtube.com/watch?v=VeteJXJlVtE&amp;quot;, &amp;quot;chunk_index&amp;quot;: 0, &amp;quot;n_chunks&amp;quot;: 64, &amp;quot;char_start&amp;quot;: 0, &amp;quot;char_end&amp;quot;: 162, &amp;quot;n_chars&amp;quot;: 162, &amp;quot;n_words&amp;quot;: 27}}&lt;br /&gt;
{&amp;quot;id&amp;quot;: &amp;quot;566b3589-f274-5702-bd1d-65e3635326bb&amp;quot;, &amp;quot;text&amp;quot;: &amp;quot;—Juliana Canet: Avui és una cita importantíssima.\n\n—Marina Porras: De fet, podríem dir que és la que més... Sempre ho diem, a cada capítol.\n\n—JC: No, però mira, és veritat que Mercè Rodoreda segurament és la més especial per a les dues, diguéssim, com a cosa conjunta i compartida. Amb Montserrat Roig, jo ja vaig explicar que hi tenia una vinculació especial per pur sentimentalisme. I tu tens molt clar que aquest llibre del qual parlarem avui és el que et va generar, si més no, una impressió més grossa de tots, no?\n\n—MP: Potser Ferrater va una mica empatat com a impressió sentimental, perquè a mi Ferrater m'importa molt i ocupa molt. Però és veritat que no tant El quadern gris, sinó Josep Pla en general, que és el tema d'avui, ocupa un lloc gegant en el meu imaginari. Però és que Josep Pla ocupa un lloc gegant a la literatura catalana del segle XX, al periodisme del segle XX. I és un senyor de qui no et pots escapar.&amp;quot;, &amp;quot;metadata&amp;quot;: {&amp;quot;doc_id&amp;quot;: &amp;quot;club_tandem.txt&amp;quot;, &amp;quot;filename&amp;quot;: &amp;quot;club_tandem.txt&amp;quot;, &amp;quot;format&amp;quot;: &amp;quot;txt&amp;quot;, &amp;quot;author&amp;quot;: &amp;quot;Juliana Canet, Marina Porras&amp;quot;, &amp;quot;title&amp;quot;: &amp;quot;EL JO: El quadern gris, de Josep Pla&amp;quot;, &amp;quot;year&amp;quot;: 2025, &amp;quot;description&amp;quot;: &amp;quot;Club Tàndem (T1xC4): La Juliana Canet i la Marina Porras conversen sobre El quadern gris de Josep Pla, els dietaris i la construcció del jo.&amp;quot;, &amp;quot;url&amp;quot;: &amp;quot;https://www.youtube.com/watch?v=VeteJXJlVtE&amp;quot;, &amp;quot;chunk_index&amp;quot;: 1, &amp;quot;n_chunks&amp;quot;: 64, &amp;quot;char_start&amp;quot;: 164, &amp;quot;char_end&amp;quot;: 1093, &amp;quot;section&amp;quot;: &amp;quot;UNA CITA IMPORTANTÍSSIMA&amp;quot;, &amp;quot;n_chars&amp;quot;: 929, &amp;quot;n_words&amp;quot;: 171}}&lt;br /&gt;
{&amp;quot;id&amp;quot;: &amp;quot;9e689daf-0c54-5066-89b1-25593acc0e5c&amp;quot;, &amp;quot;text&amp;quot;: &amp;quot;Però és que Josep Pla ocupa un lloc gegant a la literatura catalana del segle XX, al periodisme del segle XX. I és un senyor de qui no et pots escapar.\n\n—JC: Absolutament. Si t'agrada una mica llegir o tens interès a escriure, és impossible no topar-se amb Josep Pla, no llegir-lo i que no et quedi, com dius tu, una impressió. Jo, quan vaig llegir Josep Pla per primera vegada, vaig dir: «És impossible que ningú no m'hagi parlat mai d'aquest senyor abans». Saps? Que no m'hi hagués trobat abans.\n\n—MP: Te'n recordes de per on vas començar?\n\n—JC: Jo crec que per El quadern gris.\n\n—MP: Clar, jo també, eh? Crec que és la gran porta d'entrada, El quadern gris. Avui en parlarem.\n\n—JC: Però abans sí que ens toca explicar que Pla és un senyor que, quan el llegeixes, es nota. I bàsicament jo crec que tothom que fa periodisme, per descomptat, però també tothom que escriu en català, Josep Pla l'ha marcat d'alguna manera. Ni que sigui per ignorar-lo o per voler fer una cosa radicalment contrària. Però és com si ningú s'escapés de la influència i del lloc que ocupa Pla a la literatura catalana.&amp;quot;, &amp;quot;metadata&amp;quot;: {&amp;quot;doc_id&amp;quot;: &amp;quot;club_tandem.txt&amp;quot;, &amp;quot;filename&amp;quot;: &amp;quot;club_tandem.txt&amp;quot;, &amp;quot;format&amp;quot;: &amp;quot;txt&amp;quot;, &amp;quot;author&amp;quot;: &amp;quot;Juliana Canet, Marina Porras&amp;quot;, &amp;quot;title&amp;quot;: &amp;quot;EL JO: El quadern gris, de Josep Pla&amp;quot;, &amp;quot;year&amp;quot;: 2025, &amp;quot;description&amp;quot;: &amp;quot;Club Tàndem (T1xC4): La Juliana Canet i la Marina Porras conversen sobre El quadern gris de Josep Pla, els dietaris i la construcció del jo.&amp;quot;, &amp;quot;url&amp;quot;: &amp;quot;https://www.youtube.com/watch?v=VeteJXJlVtE&amp;quot;, &amp;quot;chunk_index&amp;quot;: 2, &amp;quot;n_chunks&amp;quot;: 64, &amp;quot;char_start&amp;quot;: 942, &amp;quot;char_end&amp;quot;: 2037, &amp;quot;section&amp;quot;: &amp;quot;UNA CITA IMPORTANTÍSSIMA&amp;quot;, &amp;quot;n_chars&amp;quot;: 1095, &amp;quot;n_words&amp;quot;: 200}}&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
Ara necessitaria doncs un script que em faci la ingesta de tots els chunks a la meva col·lecció.&lt;br /&gt;
Com a paràmetre s'haurà de passar la ruta del fitxer de chunks. El nom de la col·lecció ('josep-pla') la pots posar a la capçalera del document (hardcoded), perquè serà fixa.&lt;br /&gt;
&lt;br /&gt;
El script es dirà ingesta_josep_pla.py&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Abans que res, en el servidor, igual que he fet en el petit projecte embeddings:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p ~/ingesta &amp;amp;&amp;amp; cd ~/ingesta&lt;br /&gt;
python3 -m venv .venv&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
pip install --upgrade pip&lt;br /&gt;
&lt;br /&gt;
pip install torch --index-url https://download.pytorch.org/whl/cu128&lt;br /&gt;
&lt;br /&gt;
python -c &amp;quot;import torch; print(torch.__version__, torch.cuda.is_available(), torch.cuda.get_device_name(0), torch.cuda.get_arch_list())&amp;quot;&lt;br /&gt;
&lt;br /&gt;
pip install sentence-transformers qdrant-client&lt;br /&gt;
pip freeze &amp;gt; requirements.txt   # útil per a la reproduïbilitat del TFM&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
script ''ingesta_josep_pla.py'':&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python3&lt;br /&gt;
# -*- coding: utf-8 -*-&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
ingesta_josep_pla.py&lt;br /&gt;
&lt;br /&gt;
Fa la ingesta d'un fitxer de chunks (.jsonl) a la col·lecció de Qdrant.&lt;br /&gt;
&lt;br /&gt;
Ús:&lt;br /&gt;
    python ingesta_josep_pla.py ruta/al/fitxer.chunks.jsonl&lt;br /&gt;
&lt;br /&gt;
Cada línia del JSONL ha de tenir:&lt;br /&gt;
    {&amp;quot;id&amp;quot;: &amp;quot;&amp;lt;uuid&amp;gt;&amp;quot;, &amp;quot;text&amp;quot;: &amp;quot;...&amp;quot;, &amp;quot;metadata&amp;quot;: {...}}&lt;br /&gt;
&lt;br /&gt;
La col·lecció ha d'existir prèviament (creada amb curl, 1024 dimensions, Cosine).&lt;br /&gt;
Com que els id dels chunks són UUID deterministes, tornar a executar l'script&lt;br /&gt;
amb el mateix fitxer no duplica punts: els sobreescriu (upsert).&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# ---------------------------------------------------------------------------&lt;br /&gt;
# CONFIGURACIÓ&lt;br /&gt;
# ---------------------------------------------------------------------------&lt;br /&gt;
COLLECTION_NAME = &amp;quot;josep_pla&amp;quot;&lt;br /&gt;
&lt;br /&gt;
QDRANT_URL = &amp;quot;http://localhost:6333&amp;quot;&lt;br /&gt;
QDRANT_API_KEY = None            # posa-hi la clau si el Qdrant en té&lt;br /&gt;
&lt;br /&gt;
EMBEDDING_MODEL = &amp;quot;BAAI/bge-m3&amp;quot;  # ha de ser el MATEIX model que faràs servir per consultar&lt;br /&gt;
VECTOR_SIZE = 1024&lt;br /&gt;
# Prefix per als documents. bge-m3 no en necessita (&amp;quot;&amp;quot;).&lt;br /&gt;
# Si fas servir intfloat/multilingual-e5-large, posa &amp;quot;passage: &amp;quot;&lt;br /&gt;
# (i a la consulta, &amp;quot;query: &amp;quot;).&lt;br /&gt;
PASSAGE_PREFIX = &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
BATCH_SIZE = 32                  # chunks per lot (embeddings + upsert)&lt;br /&gt;
# ---------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
import argparse&lt;br /&gt;
import json&lt;br /&gt;
import sys&lt;br /&gt;
from pathlib import Path&lt;br /&gt;
&lt;br /&gt;
from qdrant_client import QdrantClient&lt;br /&gt;
from qdrant_client.models import PointStruct&lt;br /&gt;
from sentence_transformers import SentenceTransformer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def llegeix_chunks(ruta: Path):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Llegeix el JSONL i retorna la llista de chunks vàlids.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    chunks = []&lt;br /&gt;
    with ruta.open(&amp;quot;r&amp;quot;, encoding=&amp;quot;utf-8&amp;quot;) as f:&lt;br /&gt;
        for n_linia, linia in enumerate(f, start=1):&lt;br /&gt;
            linia = linia.strip()&lt;br /&gt;
            if not linia:&lt;br /&gt;
                continue&lt;br /&gt;
            try:&lt;br /&gt;
                chunk = json.loads(linia)&lt;br /&gt;
            except json.JSONDecodeError as e:&lt;br /&gt;
                print(f&amp;quot;  ⚠ Línia {n_linia}: JSON invàlid ({e}). S'omet.&amp;quot;)&lt;br /&gt;
                continue&lt;br /&gt;
            if not chunk.get(&amp;quot;id&amp;quot;) or not chunk.get(&amp;quot;text&amp;quot;, &amp;quot;&amp;quot;).strip():&lt;br /&gt;
                print(f&amp;quot;  ⚠ Línia {n_linia}: sense 'id' o 'text'. S'omet.&amp;quot;)&lt;br /&gt;
                continue&lt;br /&gt;
            chunks.append(chunk)&lt;br /&gt;
    return chunks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def comprova_colleccio(client: QdrantClient):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Comprova que la col·lecció existeix i que la mida del vector quadra.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    if not client.collection_exists(COLLECTION_NAME):&lt;br /&gt;
        sys.exit(&lt;br /&gt;
            f&amp;quot;✖ La col·lecció '{COLLECTION_NAME}' no existeix. &amp;quot;&lt;br /&gt;
            f&amp;quot;Crea-la primer amb la comanda curl.&amp;quot;&lt;br /&gt;
        )&lt;br /&gt;
    info = client.get_collection(COLLECTION_NAME)&lt;br /&gt;
    vectors = info.config.params.vectors&lt;br /&gt;
    mida = getattr(vectors, &amp;quot;size&amp;quot;, None)&lt;br /&gt;
    if mida is None:&lt;br /&gt;
        sys.exit(&lt;br /&gt;
            &amp;quot;✖ La col·lecció té vectors amb nom; aquest script espera &amp;quot;&lt;br /&gt;
            &amp;quot;un vector sense nom (Default).&amp;quot;&lt;br /&gt;
        )&lt;br /&gt;
    if mida != VECTOR_SIZE:&lt;br /&gt;
        sys.exit(&lt;br /&gt;
            f&amp;quot;✖ La col·lecció espera vectors de {mida} dimensions, &amp;quot;&lt;br /&gt;
            f&amp;quot;però l'script està configurat per a {VECTOR_SIZE}.&amp;quot;&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    parser = argparse.ArgumentParser(&lt;br /&gt;
        description=f&amp;quot;Ingesta de chunks a la col·lecció Qdrant '{COLLECTION_NAME}'.&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    parser.add_argument(&amp;quot;fitxer&amp;quot;, type=Path, help=&amp;quot;Ruta al fitxer .jsonl de chunks&amp;quot;)&lt;br /&gt;
    args = parser.parse_args()&lt;br /&gt;
&lt;br /&gt;
    if not args.fitxer.is_file():&lt;br /&gt;
        sys.exit(f&amp;quot;✖ No trobo el fitxer: {args.fitxer}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # 1. Connexió i comprovació de la col·lecció&lt;br /&gt;
    client = QdrantClient(url=QDRANT_URL, api_key=QDRANT_API_KEY)&lt;br /&gt;
    comprova_colleccio(client)&lt;br /&gt;
&lt;br /&gt;
    # 2. Lectura dels chunks&lt;br /&gt;
    print(f&amp;quot;→ Llegint {args.fitxer} ...&amp;quot;)&lt;br /&gt;
    chunks = llegeix_chunks(args.fitxer)&lt;br /&gt;
    if not chunks:&lt;br /&gt;
        sys.exit(&amp;quot;✖ No hi ha cap chunk vàlid al fitxer.&amp;quot;)&lt;br /&gt;
    print(f&amp;quot;  {len(chunks)} chunks llegits.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # 3. Model d'embeddings&lt;br /&gt;
    print(f&amp;quot;→ Carregant el model {EMBEDDING_MODEL} ...&amp;quot;)&lt;br /&gt;
    model = SentenceTransformer(EMBEDDING_MODEL)&lt;br /&gt;
    dim_model = model.get_sentence_embedding_dimension()&lt;br /&gt;
    if dim_model != VECTOR_SIZE:&lt;br /&gt;
        sys.exit(&lt;br /&gt;
            f&amp;quot;✖ El model genera vectors de {dim_model} dimensions, &amp;quot;&lt;br /&gt;
            f&amp;quot;però la col·lecció n'espera {VECTOR_SIZE}.&amp;quot;&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
    # 4. Embeddings + upsert per lots&lt;br /&gt;
    total = len(chunks)&lt;br /&gt;
    pujats = 0&lt;br /&gt;
    for inici in range(0, total, BATCH_SIZE):&lt;br /&gt;
        lot = chunks[inici:inici + BATCH_SIZE]&lt;br /&gt;
        textos = [PASSAGE_PREFIX + c[&amp;quot;text&amp;quot;] for c in lot]&lt;br /&gt;
&lt;br /&gt;
        vectors = model.encode(&lt;br /&gt;
            textos,&lt;br /&gt;
            batch_size=BATCH_SIZE,&lt;br /&gt;
            normalize_embeddings=True,&lt;br /&gt;
            show_progress_bar=False,&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
        punts = []&lt;br /&gt;
        for chunk, vector in zip(lot, vectors):&lt;br /&gt;
            # Payload: el text + totes les metadades al primer nivell,&lt;br /&gt;
            # així es poden fer filtres directes (p. ex. per doc_id o year).&lt;br /&gt;
            payload = {&amp;quot;text&amp;quot;: chunk[&amp;quot;text&amp;quot;], **chunk.get(&amp;quot;metadata&amp;quot;, {})}&lt;br /&gt;
            punts.append(&lt;br /&gt;
                PointStruct(id=chunk[&amp;quot;id&amp;quot;], vector=vector.tolist(), payload=payload)&lt;br /&gt;
            )&lt;br /&gt;
&lt;br /&gt;
        client.upsert(collection_name=COLLECTION_NAME, points=punts, wait=True)&lt;br /&gt;
        pujats += len(punts)&lt;br /&gt;
        print(f&amp;quot;  {pujats}/{total} chunks pujats&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # 5. Resum&lt;br /&gt;
    n_punts = client.count(COLLECTION_NAME, exact=True).count&lt;br /&gt;
    print(f&amp;quot;✔ Ingesta acabada: {pujats} chunks de {args.fitxer.name}.&amp;quot;)&lt;br /&gt;
    print(f&amp;quot;  La col·lecció '{COLLECTION_NAME}' té ara {n_punts} punts en total.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python3 ingesta_josep_pla.py chunks/club_tandem.txt.chunks.jsonlls &lt;br /&gt;
&lt;br /&gt;
  32/64 chunks pujats&lt;br /&gt;
  64/64 chunks pujats&lt;br /&gt;
✔ Ingesta acabada: 64 chunks de club_tandem.txt.chunks.jsonl.&lt;br /&gt;
  La col·lecció 'josep_pla' té ara 64 punts en total.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ python3 ingesta_josep_pla.py chunks/Pla_CapCreus.pdf.chunks.jsonl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
prompt:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Fes-me una comanda curl per recuperar els punts que continguin la paraula 'Dylan'&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Per buscar una paraula exacta dins del text no cal fer servir embeddings. N’hi ha prou amb un filtre sobre el camp text del payload, amb l’endpoint scroll:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
curl -X POST &amp;quot;http://localhost:6333/collections/josep_pla/points/scroll&amp;quot; \&lt;br /&gt;
  -H &amp;quot;Content-Type: application/json&amp;quot; \&lt;br /&gt;
  -d '{&lt;br /&gt;
    &amp;quot;filter&amp;quot;: {&lt;br /&gt;
      &amp;quot;must&amp;quot;: [&lt;br /&gt;
        { &amp;quot;key&amp;quot;: &amp;quot;text&amp;quot;, &amp;quot;match&amp;quot;: { &amp;quot;text&amp;quot;: &amp;quot;Dylan&amp;quot; } }&lt;br /&gt;
      ]&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;limit&amp;quot;: 100,&lt;br /&gt;
    &amp;quot;with_payload&amp;quot;: true,&lt;br /&gt;
    &amp;quot;with_vector&amp;quot;: false&lt;br /&gt;
  }'&lt;br /&gt;
&lt;br /&gt;
{&amp;quot;result&amp;quot;:{&amp;quot;points&amp;quot;:[{&amp;quot;id&amp;quot;:&amp;quot;0e9f2797-80c6-5016-8d8b-40fcc4006fa8&amp;quot;,&amp;quot;payload&amp;quot;:{&amp;quot;text&amp;quot;:&amp;quot;I és un tio que no renuncia mai a fer les coses que vol fer.\n\n—JC: Que això dius: bé, clar... Doncs no. Ni tan sols hi estic tan a favor, eh? Jo estic molt a favor de fer renúncies també, saps?\n\n—MP: Ostres, jo és que hi trobo una cosa tan magnètica, en aquesta gent que no cedeix ni un mil·límetre...\n\n—JC: A tu et funciona molt, aquesta gent.\n\n—MP: Ostres, si em funciona! Fins i tot encara que potser s'estiguin equivocant i estiguin fent alguna cosa que els fa molta il·lusió, que els sembla el pas més important de la seva vida, però que tu des de fora veus clarament que és un error. Però és seu, és la seva cosa. I llavors, si rectifiquen, encara té molt més mèrit.\n\n—JC: Sí, i l'autocontrol és molt avorrit.\n\n—MP: És horrible. Bob Dylan és un senyor que no té gens d'autocontrol. Arriba allà, i el documental t'explica tot de testimonis de com van viure l'arribada de Dylan. Hi ha poetes, hi ha la Joan Baez, que diu, en plan: «Clar, jo no havia vist mai ningú així». Ho diu amb aquests ulls de senyora completament enamorada, que és el que va estar...\n\n—JC: Però perquè desprèn... sexe, no?&amp;quot;,&amp;quot;doc_id&amp;quot;:&amp;quot;club_tandem.txt&amp;quot;,&amp;quot;filename&amp;quot;:&amp;quot;club_tandem.txt&amp;quot;,&amp;quot;format&amp;quot;:&amp;quot;txt&amp;quot;,&amp;quot;author&amp;quot;:&amp;quot;Juliana Canet, Marina Porras&amp;quot;,&amp;quot;title&amp;quot;:&amp;quot;EL JO: El quadern gris, de Josep Pla&amp;quot;,&amp;quot;year&amp;quot;:2025,&amp;quot;description&amp;quot;:&amp;quot;Club Tàndem (T1xC4): La Juliana Canet i la Marina Porras conversen sobre El quadern gris de Josep Pla, els dietaris i la construcció del jo.&amp;quot;,&amp;quot;url&amp;quot;:&amp;quot;https://www.youtube.com/watch?v=VeteJXJlVtE&amp;quot;,&amp;quot;chunk_index&amp;quot;:31,&amp;quot;n_chunks&amp;quot;:64,&amp;quot;char_start&amp;quot;:26825,&amp;quot;char_end&amp;quot;:27924,&amp;quot;section&amp;quot;:&amp;quot;BOB DYLAN: CREAR-SE A UN MATEIX&amp;quot;,&amp;quot;n_chars&amp;quot;:1099,&amp;quot;n_words&amp;quot;:209}},...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Autor}}, octubre 2026&lt;/div&gt;</summary>
		<author><name>Joan</name></author>
		
	</entry>
</feed>