En aquest blog anirem construint un per a les recomanacions de productes utilitzant taxonomia i taxonomia complementària. Facilita la creació i el manteniment de gràfics de coneixement amb actualitzacions de font contínues. knowledge graph CocoIndex s una manera d'organitzar els catàlegs de productes en una estructura lògica i jeràrquica; es pot trobar una gran explicació detallada En la pràctica, és un problema complicat: un producte pot formar part de múltiples categories, i una categoria pot tenir múltiples pares. Product taxonomy i Aquí També utilitzarem LLM per generar una llista de taxonomies complementàries per a cada producte - per exemple, quan algú compra un quadern, també poden comprar una ploma com a producte complementari. El codi font està disponible a . CocoIndex Exemples - product_taxonomy Estem constantment millorant, i més característiques i exemples estan arribant aviat. starring our . GitHub repo GitHub Repo Prerequisits CocoIndex utilitza PostgreSQL internament per al processament incremental. Instal·lar Neo4j, una base de dades de gràfics. Alternativament, podeu canviar a Ollama, que executa els models LLM localment - guia. Documentació Podeu llegir la documentació oficial de CocoIndex per als objectius del gràfic de la propietat . Aquí Flux de dades per construir el gràfic del coneixement Visió general El flux principal és de . 100 línies de codi Python Declararem un flux de dades Productes d’ingestió (en JSON) for each product, parse JSON map & clean up data extract taxonomy from the mapped data Recollida de dades Exportació de dades a neo4j Afegir documents com a font @cocoindex.flow_def(name="StoreProduct") def store_product_flow(flow_builder: cocoindex.FlowBuilder, data_scope: cocoindex.DataScope): data_scope["products"] = flow_builder.add_source( cocoindex.sources.LocalFile(path="products", included_patterns=["*.json"]), refresh_interval=datetime.timedelta(seconds=5)) Aquí Creació a . el És la clau de l’esquerra. flow_builder.add_source Càritas filename Afegir col·lectors de dades Afegir col·lectors a l'abast d'arrel per recollir el producte, la taxonomia i la taxonomia complementària. product_node = data_scope.add_collector() product_taxonomy = data_scope.add_collector() product_complementary_taxonomy = data_scope.add_collector() Processament de cada producte We will parse the JSON file for each product, and transform the data to the format that we need for downstream processing. Mapa de dades @cocoindex.op.function(behavior_version=2) def extract_product_info(product: cocoindex.typing.Json, filename: str) -> ProductInfo: return ProductInfo( id=f"{filename.removesuffix('.json')}", url=product["source"], title=product["title"], price=float(product["price"].lstrip("$").replace(",", "")), detail=Template(PRODUCT_TEMPLATE).render(**product), ) Aquí definim una funció per a la cartografia de dades, per exemple, Neteja el camp d'ID Títol del mapa -> Títol clean up the field price generar una cadena de marcatge per al detall del producte basat en tots els camps (per al LLM per extreure la taxonomia i la taxonomia complementària, trobem que el marcatge funciona millor com a context per al LLM). El flux Dins del flux, connectem la transformació de cartografia de dades per processar cada producte JSON. with data_scope["products"].row() as product: data = (product["content"] .transform(cocoindex.functions.ParseJson(), language="json") .transform(extract_product_info, filename=product["filename"])) product_node.collect(id=data["id"], url=data["url"], title=data["title"], price=data["price"]) La primera transformació() pars el fitxer JSON. El segon transform() realitza el mapping de dades definit. Recopilem els camps que necessitem per al node del producte en Neo4j. Extracció de taxonomia i taxonomia complementària utilitzant LLM Definició de taxonomia del producte Atès que estem utilitzant LLM per extreure la taxonomia del producte, hem de proporcionar una instrucció detallada a la doctrina de nivell de classe. @dataclasses.dataclass class ProductTaxonomy: """ Taxonomy for the product. A taxonomy is a concise noun (or short noun phrase), based on its core functionality, without specific details such as branding, style, etc. Always use the most common words in US English. Use lowercase without punctuation, unless it's a proper noun or acronym. A product may have multiple taxonomies. Avoid large categories like "office supplies" or "electronics". Use specific ones, like "pen" or "printer". """ name: str Informació taxonòmica del producte Bàsicament volem extreure totes les taxonomies possibles per a un producte, i pensar en quins altres productes són susceptibles de ser comprats juntament amb el producte actual. @dataclasses.dataclass class ProductTaxonomyInfo: """ Taxonomy information for the product. Fields: - taxonomies: Taxonomies for the current product. - complementary_taxonomies: Think about when customers buy this product, what else they might need as complementary products. Put labels for these complentary products. """ taxonomies: list[ProductTaxonomy] complementary_taxonomies: list[ProductTaxonomy] Per a cada producte, volem tenir una mica de coneixement sobre la seva taxonomia i taxonomia complementària i podríem utilitzar això com a pont per trobar el producte relacionat utilitzant el gràfic del coneixement. LLM Extracció Finalment, utilitzarem per extreure la taxonomia i la taxonomia complementària del detall del producte. cocoindex.functions.ExtractByLlm taxonomy = data["detail"].transform(cocoindex.functions.ExtractByLlm( llm_spec=cocoindex.LlmSpec( api_type=cocoindex.LlmApiType.OPENAI, model="gpt-4.1"), output_type=ProductTaxonomyInfo)) Per exemple, LLM pren la descripció de la , i extreu la taxonomia a ser Això vol dir que quan la gent compra També poden estar interessats en Com a taxonomia complimentària. Penja de gel gel pen Penja de gel Notícies I després recollirem la taxonomia i la taxonomia complementària al col·lector. with taxonomy['taxonomies'].row() as t: product_taxonomy.collect(id=cocoindex.GeneratedField.UUID, product_id=data["id"], taxonomy=t["name"]) with taxonomy['complementary_taxonomies'].row() as t: product_complementary_taxonomy.collect(id=cocoindex.GeneratedField.UUID, product_id=data["id"], taxonomy=t["name"]) Construcció de grafs de coneixement Conceptes bàsics Tots els nodes per a Neo4j necessiten dues coses: Etiqueta: El tipus de node. per exemple, producte, taxonomia. Camp de clau primària: El camp que identifica de manera única el node. per exemple, id per a nodes de producte. CocoIndex utilitza el camp de clau primària per coincidir amb els nodes i deduplicar-los. Si teniu múltiples nodes amb la mateixa clau primària, CocoIndex només en conserva un. Hi ha dues maneres de mapejar els nodes: Quan disposeu d'un col·lector només per al node, podeu exportar-lo directament a Neo4j. Per exemple Producte. Quan disposeu d'un col·lector de relacions que es connecti amb el node, podeu mapejar els nodes dels camps seleccionats en el col·lector de relacions. Per exemple, product_taxonomy.collect(id=cocoindex.GeneratedField.UUID, product_id=data["id"], taxonomy=t["name"]) Recull una relació i es crea un node de taxonomia a partir de la relació. Configuració de la connexió Neo4j: conn_spec = cocoindex.add_auth_entry( "Neo4jConnection", cocoindex.storages.Neo4jConnection( uri="bolt://localhost:7687", user="neo4j", password="cocoindex", )) Exportació Enllaç a Neo4j El producte El producte product_node.export( "product_node", cocoindex.storages.Neo4j( connection=conn_spec, mapping=cocoindex.storages.Nodes(label="Product") ), primary_key_fields=["id"], ) Això exporta nodes Neo4j amb etiqueta Des de la El col·leccionista Product product_node Es declara Neo4j node etiqueta de producte. Especifica id com el camp clau primària. Transporta tots els camps des del col·lector de product_node fins als nodes Neo4j amb l'etiqueta Product. Exportació Enllaç a Neo4j Taxonomia Taxonomia No hi ha col·leccionista explícit per Els nadius són part de la i Col·lectors i camps es recullen durant l'extracció taxonòmica. Taxonomy product_taxonomy product_complementary_taxonomy Per exportar-los com a nodes Neo4j, primer hem de declarar els nodes. Taxonomy flow_builder.declare( cocoindex.storages.Neo4jDeclaration( connection=conn_spec, nodes_label="Taxonomy", primary_key_fields=["value"], ) ) A continuació, l’exportació És el cas de Neo4j. product_taxonomy product_taxonomy.export( "product_taxonomy", cocoindex.storages.Neo4j( connection=conn_spec, mapping=cocoindex.storages.Relationships( rel_type="PRODUCT_TAXONOMY", source=cocoindex.storages.NodeFromFields( label="Product", fields=[ cocoindex.storages.TargetFieldMapping( source="product_id", target="id"), ] ), target=cocoindex.storages.NodeFromFields( label="Taxonomy", fields=[ cocoindex.storages.TargetFieldMapping( source="taxonomy", target="value"), ] ), ), ), primary_key_fields=["id"], ) Així mateix, es pot exportar el És el cas de Neo4j. product_complementary_taxonomy product_complementary_taxonomy.export( "product_complementary_taxonomy", cocoindex.storages.Neo4j( connection=conn_spec, mapping=cocoindex.storages.Relationships( rel_type="PRODUCT_COMPLEMENTARY_TAXONOMY", source=cocoindex.storages.NodeFromFields( label="Product", fields=[ cocoindex.storages.TargetFieldMapping( source="product_id", target="id"), ] ), target=cocoindex.storages.NodeFromFields( label="Taxonomy", fields=[ cocoindex.storages.TargetFieldMapping( source="taxonomy", target="value"), ] ), ), ), primary_key_fields=["id"], ) El Declara com mapejar relacions en Neo4j. cocoindex.storages.Relationships En una relació, hi ha: Un node font i un node objectiu. Una relació que connecta la font i la meta. Tingueu en compte que diferents relacions poden compartir els mateixos nodes de font i meta. Pren els camps de la Col·leccionista i creador els nodes. NodeFromFields entity_relationship Taxonomy Funció principal Finalment, la funció principal per al flux inicia el flux CocoIndex i l'executa. @cocoindex.main_fn() def _run(): pass if __name__ == "__main__": load_dotenv(override=True) _run() Cerca i prova el teu índex Ara tots estem preparats! Install the dependencies: pip install -e . Run following commands to setup and update the index. python main.py cocoindex setup python main.py cocoindex update You'll see the index updates state in the terminal. For example, you'll see the following output: documents: 9 added, 0 removed, 0 updated (Optional) I used CocoInsight to troubleshoot the index generation and understand the data lineage of the pipeline. It is in free beta now, you can give it a try. Run following command to start CocoInsight: python3 main.py cocoindex server -c https://cocoindex.io And then open the url . It just connects to your local CocoIndex server, with Zero pipeline data retention. https://cocoindex.io/cocoinsight Descobreix el gràfic del coneixement Un cop construït el gràfic del coneixement, podeu explorar el gràfic del coneixement que heu construït en el navegador Neo4j. Per a l'entorn de desenvolupador, podeu connectar-vos al navegador Neo4j utilitzant les credencials: Nom d'usuari: Neo4j contrasenya: cocoindex que està preconfigurat en el nostre docker compost config.yaml. Es pot obrir a , i executeu la següent consulta Cypher per obtenir totes les relacions: http://localhost:7474 MATCH p=()-->() RETURN p Support us Estem constantment millorant, i més característiques i exemples estan arribant aviat. Si t'agrada aquest article, si us plau, dóna'ns una estrella ⭐ a Per ajudar-nos a créixer GitHub repo Gràcies per llegir!