In hierdie blog sal ons 'n vir produkaanbevelings met behulp van taksonomie en komplementêre taksonomie. maak dit maklik om kenniskaarte te bou en te onderhou met voortdurende bronupdates. knowledge graph Die CocoIndex s 'n manier om produkkatalogi in 'n logiese en hiërargiese struktuur te organiseer; 'n groot gedetailleerde verduideliking kan gevind word In die praktyk is dit 'n ingewikkelde probleem: 'n produk kan deel wees van verskeie kategorieë, en 'n kategorie kan verskeie ouers hê. Product taxonomy i hier Ons sal ook die LLM gebruik om 'n lys van komplementêre taksonomieë vir elke produk te genereer - byvoorbeeld, wanneer iemand 'n notablad koop, kan hulle ook 'n pen as 'n komplementêre produk koop. Die bron kode is beskikbaar by . CocoIndex Voorbeelde - product_taxonomy Ons verbeter voortdurend, en meer funksies en voorbeelde kom binnekort. die starring our . GitHub repo GitHub repo Voorwaardes Installeer PostgreSQL. CocoIndex gebruik PostgreSQL intern vir incrementele verwerking. Installeer Neo4j, 'n grafiese databasis. Konfigureer jou OpenAI API sleutel. Alternatief, kan jy skakel na Ollama, wat LLM modelle plaaslik hardloop - gids. Dokumenteer Jy kan die amptelike CocoIndex Dokumentasie vir Property Graph Targets lees . hier Data vloei om kennis grafiek te bou Oorsig Die kernstroom is oor . ~100 reëls van Python kode Ons sal 'n data vloei verklaar produkte ingestel (in JSON) for each product, parse JSON map & clean up data extract taxonomy from the mapped data versamel data Uitvoer data na neo4j Voeg dokumente by as bron @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)) hier Skep 'n Die Dit is die sleutel van die KTable. flow_builder.add_source Kyk filename Voeg data versamelaars Voeg versamelaars by die wortelomvang by om die produk, taksonomie en komplementêre taksonomie te versamel. product_node = data_scope.add_collector() product_taxonomy = data_scope.add_collector() product_complementary_taxonomy = data_scope.add_collector() Verwerking van elke produk Ons sal die JSON-lêer vir elke produk parseer en die data omskep na die formaat wat ons nodig het vir verdere verwerking. Data kaartjie @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), ) Hier definieer ons 'n funksie vir data-mapping, byvoorbeeld, Maak die ID veld skoon Titel van die kaart -> Titel Maak die pryseveld skoon genereer 'n markdown string vir die produk besonderhede gebaseer op al die velde (vir LLM om taksonomie en komplementêre taksonomie te onttrek, vind ons dat markdown die beste werk as konteks vir LLM). Die vloei Binne die vloei sluit ons die data-mapping-transformasie in om elke produk JSON te verwerk. 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"]) Die eerste transform() parseer die JSON-lêer. Die tweede transform() voer die gedefinieerde data-mapping uit. Ons versamel die velde wat ons nodig het vir die produknodus in Neo4j. Ekstrakteer taksonomie en komplementêre taksonomie met behulp van LLM Product Taxonomy Definisie Aangesien ons die LLM gebruik om produktaksonomie te onttrek, moet ons 'n gedetailleerde instruksies op die klasvlak dokstring verskaf. @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 Definieer produk Taxonomy Info In wese wil ons al die moontlike taksonomies vir 'n produk onttrek, en dink oor watter ander produkte waarskynlik saam met die huidige produk gekoop sal word. @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] Vir elke produk wil ons 'n bietjie insig oor sy taksonomie en komplementêre taksonomie hê en ons kan dit gebruik as 'n brug om verwante produk te vind met behulp van kennisgraaf. LLM Ekstraksie Ten slotte sal ons gebruik om die taksonomie en komplementêre taksonomie uit die produkdetail te onttrek. 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)) Byvoorbeeld, die LLM neem die beskrywing van die , en ekstrakteer taksonomie om te wees Dit beteken dat wanneer mense koop Hulle kan ook geïnteresseerd wees in Dit is 'n komplimentêre taksonomie. Die pen Die pen Die pen Notasie En dan sal ons die taksonomie en komplementêre taksonomie aan die versamelaar versamel. 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"]) Bepaal kennis grafiek basiese konsepte Alle nodes vir Neo4j benodig twee dinge: Label: Die tipe van die knoop. byvoorbeeld, produk, taksonomie. Primêre sleutelveld: Die veld wat die knoop uniek identifiseer. byvoorbeeld, id vir produkknodes. CocoIndex gebruik die primêre sleutelveld om die nodes te ooreenkom en hulle te verdubbel. As jy verskeie nodes met dieselfde primêre sleutel het, hou CocoIndex slegs een van hulle. Daar is twee maniere om nodes te kaarteer: Wanneer jy 'n versamelaar net vir die knoop het, kan jy dit direk na Neo4j uitvoer. byvoorbeeld produk. Wanneer u 'n versamelaar vir verhoudings het wat verbind word met die knoop, kan u nodes van geselekteerde velde in die verhoudingsversamelaar kaarteer. Byvoorbeeld, product_taxonomy.collect(id=cocoindex.GeneratedField.UUID, product_id=data["id"], taxonomy=t["name"]) Versamel 'n verhouding, en taksonomiese knoop word uit die verhouding geskep. Om die Neo4j verbinding te stel: conn_spec = cocoindex.add_auth_entry( "Neo4jConnection", cocoindex.storages.Neo4jConnection( uri="bolt://localhost:7687", user="neo4j", password="cocoindex", )) Uitvoer Geskryf deur Neo4j produkte produkte product_node.export( "product_node", cocoindex.storages.Neo4j( connection=conn_spec, mapping=cocoindex.storages.Nodes(label="Product") ), primary_key_fields=["id"], ) Dit vervoer Neo4j nodes met label van die die versamelaar. Product product_node Dit verklaar die Neo4j-node label Product. Dit spesifiseer id as die primêre sleutelveld. Dit dra al die velde van product_node collector na Neo4j nodes met label Product. Uitvoer Geskryf deur Neo4j Taxonomieë Taxonomieë Ons het nie 'n eksplisiete versamelaar vir node. hulle is deel van die en versamelers en velde word versamel tydens die taksonomiese uitvinding. Taxonomy product_taxonomy product_complementary_taxonomy Om hulle as Neo4j-nodes te eksporteer, moet ons eers verklaar die nodes. Taxonomy flow_builder.declare( cocoindex.storages.Neo4jDeclaration( connection=conn_spec, nodes_label="Taxonomy", primary_key_fields=["value"], ) ) Volgende is die uitvoer van die Soos die verhouding met 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"], ) Ons kan ook die Soos die verhouding met 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"], ) die Verduidelik hoe om verhoudings in Neo4j te kaarteer. cocoindex.storages.Relationships In 'n verhouding is daar: 'n Bronnodus en 'n Doelnodus 'N verhouding wat die bron en doel verbind. Let daarop dat verskillende verhoudings dieselfde bron- en doelnodes kan deel. Neem die velde van die versamel en skep die nodes. NodeFromFields entity_relationship Taxonomy Die hooffunksie Ten slotte, die hooffunksie vir die vloei inisialiseer die CocoIndex vloei en voer dit uit. @cocoindex.main_fn() def _run(): pass if __name__ == "__main__": load_dotenv(override=True) _run() Vra en toets jou indeks Nou is jy almal gereed! 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 Browse die kennis grafiek Nadat die kennisgraaf gebou is, kan jy die kennisgraaf wat jy in Neo4j Browser gebou het, ondersoek. Vir die ontwikkelaar omgewing, kan jy verbinding maak met die Neo4j leser met behulp van credentials: Gebruikersnaam: Neo4j wagwoord: cocoindex wat vooraf ingestel is in ons docker compose config.yaml. Jy kan dit oopmaak by , en die volgende Cypher-vraag uit te voer om al die verhoudings te kry: http://localhost:7474 MATCH p=()-->() RETURN p Ondersteun ons Ons is voortdurend verbeter, en meer funksies en voorbeelde kom binnekort. as jy hierdie artikel hou, gee ons asseblief 'n ster ⭐ by om ons te help groei. GitHub repo Dankie vir die lees!