从目录混乱到实时推荐:使用 LLMs 和 Neo4j 构建产品图

发布: (2025年12月12日 GMT+8 11:52)
6 min read
原文: Dev.to

Source: Dev.to

大多数我见过的商品推荐系统基本上是高级的关键词匹配器。它们在拥有数百万次点击数据时还能勉强工作,但在以下情况下就会彻底失效:

  • 你推出了一个全新商品,零交互数据 📉
  • 你的目录标签和描述混乱不堪 🤦
  • 你想解释为什么推荐某个商品(而不是只给出一个黑箱分数)

我刚刚构建了一个实时推荐引擎,它使用 LLM 和图数据库真正理解商品。核心逻辑只有约 100 行 Python。

秘密武器:商品分类法 + 知识图谱

我们不只依赖用户行为,而是教会 LLM 理解:

  • 商品到底是什么(细粒度分类,如 “凝胶笔” 而不是 “办公用品”)
  • 人们会一起购买什么(互补商品,如 “凝胶笔” → “笔记本”、 “笔筒”)

所有这些都存储在 Neo4j 图数据库中,关系成为一等公民。现在你可以查询诸如 “显示所有与这支凝胶笔拥有互补分类的商品” 的信息。

实际案例:凝胶笔问题

当有人浏览凝胶笔时,传统推荐系统可能会展示:

  • 其他凝胶笔(同一类别)
  • 热门商品(基于销量)
  • 随机的 “其他顾客也购买了” (如果数据足够多)

使用我们的方案,LLM 会分析商品描述并提取:

  • 主要分类gel penwriting instrument
  • 互补分类notebookpencil casedesk organizer

图谱现在知道这些关系,所以在查看凝胶笔时可以呈现笔记本、计划本和收纳盒——并且可解释这些关联。

架构(简化版)

Product JSONs → CocoIndex Pipeline → LLM Extraction → Neo4j Graph

1. 将商品作为流式输入

我们监视一个商品 JSON 文件夹并自动刷新:

data_scope["products"] = flow_builder.add_source(
    cocoindex.sources.LocalFile(
        path="products",
        included_patterns=["*.json"]
    ),
    refresh_interval=datetime.timedelta(seconds=5)
)

每当商品文件发生变化时,管道会自动更新——无需手动重建。

2. 清洗并标准化数据

我们把原始 JSON 映射为干净的结构:

@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),
    )

detail 字段会生成一段 Markdown “商品说明”,随后喂给 LLM。

3. 让 LLM 完成繁重工作

我们把分类合约定义为数据类:

@dataclasses.dataclass
class ProductTaxonomy:
    """
    A concise noun or short phrase based on core functionality.
    Use lowercase, avoid brands/styles.
    Be specific: "pen" not "office supplies".
    """
    name: str

@dataclasses.dataclass
class ProductTaxonomyInfo:
    taxonomies: list[ProductTaxonomy]
    complementary_taxonomies: list[ProductTaxonomy]

随后调用 LLM:

taxonomy = data["detail"].transform(
    cocoindex.functions.ExtractByLlm(
        llm_spec=cocoindex.LlmSpec(
            api_type=cocoindex.LlmApiType.OPENAI,
            model="gpt-4.1"
        ),
        output_type=ProductTaxonomyInfo
    )
)

LLM 读取 Markdown 描述并返回符合我们模式的结构化 JSON——不再需要手动解析。

4. 在 Neo4j 中构建知识图谱

我们导出三类实体:

  • 商品节点idtitlepriceurl
  • 分类节点:唯一标签,如 “gel pen”、 “notebook”
  • 关系PRODUCT_TAXONOMYPRODUCT_COMPLEMENTARY_TAXONOMY
product_node.export(
    "product_node",
    cocoindex.storages.Neo4j(
        connection=conn_spec,
        mapping=cocoindex.storages.Nodes(label="Product")
    ),
    primary_key_fields=["id"],
)

Neo4j 会根据主键自动去重。如果有五个商品都把 “notebook” 作为互补分类,它们都会指向同一个 Taxonomy 节点。

实时运行

在准备好 Postgres(用于 CocoIndex 的增量处理)和 Neo4j 后,执行:

pip install -e .
cocoindex update --setup main

你会看到类似输出:

documents: 9 added, 0 removed, 0 updated

随后打开 Neo4j Browser(http://localhost:7474)并运行:

MATCH p=()-->() RETURN p

Boom——整个商品图谱可视化呈现。

为什么它真的有效

  • LLM 擅长文本理解——把凌乱的自然语言解释交给模型,只需提供模式和文档字符串即可。
  • 图数据库天生适合关系——你得到可解释的关联,并且可以运行图算法(PageRank、社区检测、最短路径等)。
  • 增量更新免费——CocoIndex 负责所有管道细节;添加商品文件,即可得到更新后的图谱。

你可以继续构建的方向

  • 添加 品牌材质、或 使用场景 等分类,作为独立节点类型。
  • 接入 点击流数据,为边加权或创建 FREQUENTLY_BOUGHT_WITH 关系。
  • 当需要完全控制时,用 Ollama(本地 LLM)替换 OpenAI。
  • 在上层加入 图算法,发现商品簇或检测热门分类。

亲自尝试

完整代码已开源:

👉 CocoIndex Product Recommendation Example

仓库包含:

  • 完整的流定义
  • LLM 提取操作
  • Neo4j 映射
  • 示例商品 JSON

如果你在玩 LLM 原生数据管道或基于图的推荐,欢迎分享你的作品。留言或 @ 我吧!

P.S. 如果觉得有帮助,请给 CocoIndex 仓库点个星 ⭐

P.P.S. 你也可以使用 CocoInsight(免费 beta)可视化管道——它就像数据管道的 DevTools,且不保留数据。

Back to Blog

相关文章

阅读更多 »