从目录混乱到实时推荐:使用 LLMs 和 Neo4j 构建产品图
Source: Dev.to
大多数我见过的商品推荐系统基本上是高级的关键词匹配器。它们在拥有数百万次点击数据时还能勉强工作,但在以下情况下就会彻底失效:
- 你推出了一个全新商品,零交互数据 📉
- 你的目录标签和描述混乱不堪 🤦
- 你想解释为什么推荐某个商品(而不是只给出一个黑箱分数)
我刚刚构建了一个实时推荐引擎,它使用 LLM 和图数据库真正理解商品。核心逻辑只有约 100 行 Python。
秘密武器:商品分类法 + 知识图谱
我们不只依赖用户行为,而是教会 LLM 理解:
- 商品到底是什么(细粒度分类,如 “凝胶笔” 而不是 “办公用品”)
- 人们会一起购买什么(互补商品,如 “凝胶笔” → “笔记本”、 “笔筒”)
所有这些都存储在 Neo4j 图数据库中,关系成为一等公民。现在你可以查询诸如 “显示所有与这支凝胶笔拥有互补分类的商品” 的信息。
实际案例:凝胶笔问题
当有人浏览凝胶笔时,传统推荐系统可能会展示:
- 其他凝胶笔(同一类别)
- 热门商品(基于销量)
- 随机的 “其他顾客也购买了” (如果数据足够多)
使用我们的方案,LLM 会分析商品描述并提取:
- 主要分类:
gel pen、writing instrument - 互补分类:
notebook、pencil case、desk 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 中构建知识图谱
我们导出三类实体:
- 商品节点:
id、title、price、url - 分类节点:唯一标签,如 “gel pen”、 “notebook”
- 关系:
PRODUCT_TAXONOMY与PRODUCT_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,且不保留数据。