Text2Cypher 与 LLM 图查询 Agent:从自然语言到可执行 Cypher

系统讲解 Text2Cypher 与 LLM 图查询 Agent 的完整工程链路:问题定义(自然语言到图的语义鸿沟)、schema 提示(模式摘要、属性裁剪、token 预算)、few-shot 示例与检索式提示、查询校验(语法解析、语义检查、标签与关系白名单)、只读沙箱与安全执行(超时、强制 LIMIT、资源隔离)、错误自愈(错误分类、重试与修复提示)、图检索增强(GraphRAG 与 Text2Cypher 协同)、Agent 编排(工具调用与多步推理)、评测体系(执行准确率、查询相似度、端到端)、以及成本延迟与常见坑,帮助把自然语言查图做成可上线的生产能力。

引言

让业务同学用一句中文问「上个月给 A 公司转过账的账户里,哪些又和风险名单有三度以内的关系」,然后系统直接返回结果——这是 Text2Cypher 想解决的问题。它把自然语言翻译成 Cypher,交给图数据库执行,再把结果组织成答案。听起来只是「调个模型」,但真正上线会遇到一连串工程问题:模型不认识你的 schema,编造出根本不存在的标签;生成的查询语法对但语义错,跑出来一堆空结果;一次误生成的 MATCH (n) DETACH DELETE n 能把生产库清空;查询太慢拖垮整个实例;错了以后模型不知道错在哪,反复重试同一个错误。本文把 Text2Cypher 拆成一条完整链路:先讲问题定义(自然语言与图之间的语义鸿沟在哪),再讲 schema 提示、few-shot 与检索式提示、查询校验的三道闸门、只读沙箱与安全执行、错误自愈的重试循环、图检索增强(Text2Cypher 与 GraphRAG 怎么协同)、Agent 编排、评测体系与生产实践,最后是成本、延迟与常见坑。目标:你能把「自然语言查图」从 demo 做到可上线。

前置:/graphdb-neo4j-cypher-guide/(Cypher 基础)、/graphdb-cypher-advanced/(高级查询)、/graphdb-graphrag-vector/(图检索增强)。


目录


1. 问题定义:自然语言到图的语义鸿沟

Text2Cypher 的最小闭环:

用户问题(自然语言)
   ↓ 提示 + schema + few-shot
LLM 生成 Cypher
   ↓ 校验(语法 / 语义 / 白名单)
执行(只读沙箱) → 组织答案

语义鸿沟的四个来源:

1. 词汇鸿沟:用户说「供应商」,图里叫 :Vendor
2. 结构鸿沟:用户说「关联方」,图里是 3 跳路径
3. 度量鸿沟:「大额」在图里是 amount > 100000
4. 时间鸿沟:「上个月」要翻译成日期区间谓词
→ 前两个靠 schema 提示,后两个靠业务词典

为什么不能只靠模型裸生成:

- 模型没见过你的 schema → 编造标签/属性名
- 模型不知道数据分布 → 生成的查询可能全表扫描
- 模型不理解安全边界 → 可能生成写操作
- 模型不保证语法 → Cypher 方言版本差异会翻车
→ Text2Cypher = 模型生成 + 工程约束

三种技术路线对比:

路线做法优点缺点
纯提示生成直接让模型写 Cypher简单、无训练成本准确率不稳、schema 漂移易错
微调模型用历史查询对微调小模型领域准确率高、延迟低需标注数据、schema 变更要重训
检索式提示检索相似历史查询作示例无需训练、可增量更新依赖示例库质量

成熟度预期管理:

- 简单单跳查询(找某实体的属性):准确率可到 90% 以上
- 中等多跳 / 聚合:70%~85%,需要校验兜底
- 复杂时序 + 多约束:50%~70%,建议人工确认
→ 不要承诺「100% 准确」,要设计「错了也能兜住」的链路

心智:Text2Cypher 的鸿沟来自四处——词汇(供应商 vs Vendor)、结构(关联方 vs 三跳路径)、度量(大额 vs 阈值)、时间(上个月 vs 区间);前两者靠 schema 提示,后两者靠业务词典;技术路线有纯提示、微调、检索式三种,按成熟度分场景承诺准确率,工程约束比模型选型更决定成败。


2. Schema 提示:把图模式喂给模型

schema 提示要解决的矛盾:

- 给太少:模型不知道有哪些标签和关系 → 编造
- 给太多:token 爆掉、关键信息被淹没 → 精度下降
→ 目标:用最小 token 表达「可查询的结构」

三种 schema 表达形式:

形式 1(紧凑 DSL):
(:Person {id, name, age})-[:FRIEND]->(:Person)
(:Company {id, name})-[:SUPPLIES {amount, at}]->(:Company)

形式 2(JSON Schema):
{"nodes":{"Person":{"props":["id","name"]}}, ...}

形式 3(样例查询):
MATCH (p:Person)-[:FRIEND]->(f) RETURN f.name
→ 紧凑 DSL 最省 token,JSON 最结构化,样例最直观

schema 抽取的实现:

// 标签 + 属性 + 关系两端标签组合
CALL db.schema.nodeTypeProperties()
YIELD nodeType, propertyName, propertyTypes, mandatory
RETURN nodeType, propertyName, propertyTypes, mandatory

CALL db.schema.relTypeProperties()
YIELD relType, propertyName, propertyTypes
RETURN relType, propertyName, propertyTypes

关系模式抽取(起点标签到终点标签):

MATCH (a)-[r]->(b)
RETURN DISTINCT labels(a) AS fromLabels, type(r) AS relType,
       labels(b) AS toLabels, keys(r) AS relProps
LIMIT 200

属性裁剪与 token 预算:

- 只保留高频属性(覆盖率 > 5%),低频属性省略
- 枚举型属性给 3~5 个样例值(如 status: active/suspended)
- 敏感属性(手机号、身份证)不出现在提示里
- 标签数 > 100 时按业务域分组,按问题路由子 schema
- schema 提示 300~800 token、few-shot 3~6 条、总输入控制在 2K~4K
→ 提示里的 schema 是「导航地图」,不是「完整字典」

schema 提示模板:

你是图数据库查询专家。下面是图模式:

节点:
(:Person {id, name, age, city})
(:Company {id, name, industry})
(:Account {id, balance})

关系:
(:Person)-[:WORKS_AT {since}]->(:Company)
(:Person)-[:FRIEND]->(:Person)
(:Account)-[:TRANSFER {amount, at}]->(:Account)
(:Person)-[:OWNS]->(:Account)

规则:
1. 只生成只读查询(MATCH / RETURN / WITH)
2. 禁止 CREATE / MERGE / SET / DELETE / DROP
3. 结果集必须带 LIMIT(默认 100)
4. 时间用 datetime('2026-09-01T00:00:00Z') 形式

心智:schema 提示的核心是「最小 token 表达可查询结构」——用紧凑 DSL 而非完整 JSON,只保留高频属性、枚举给样例值、敏感属性不入提示;用 db.schema 系列过程自动抽取;大 schema 走两级路由(先选业务域再给该域 schema),总输入控制在 2K~4K token。


3. Few-shot 示例与检索式提示

few-shot 的作用:

- 教模型「你的图里这类问题怎么写」
- 覆盖:多跳路径、聚合、时间过滤、排序取 TopN
- 比自然语言规则更有效(模型模仿示例 > 理解规则)
→ 示例质量 > 示例数量,3~6 条精选胜过 20 条泛泛

示例库的结构:

{
  "question": "查张三的朋友里在北京的",
  "cypher": "MATCH (p:Person {name:'张三'})-[:FRIEND]->(f:Person) WHERE f.city='北京' RETURN f.name LIMIT 100",
  "tags": ["单跳", "属性过滤"],
  "verified": true
}

静态 few-shot vs 检索式 few-shot:

静态:固定 5 条塞进提示
  - 优点:简单、稳定;缺点:与当前问题无关时是噪声
检索式:按用户问题检索最相似的 K 条示例
  - 向量检索(问题 embedding 相似)或按标签/意图路由
  - 优点:示例相关性高,准确率显著提升
→ 生产推荐检索式,示例库可持续积累

示例检索的实现(伪代码):

def build_prompt(question, schema, store, k=4):
    hits = store.search(question, k=k)          # 语义检索
    shots = [e for e in hits if e["verified"]]
    shots = ensure_coverage(shots, ["多跳", "聚合"])  # 保证结构多样
    return TEMPLATE.format(schema=schema, examples=render(shots), question=question)

示例的选取原则:

- 与目标问题「结构相似」优于「字面相似」
- 覆盖难点模式:变长路径、聚合分组、时间窗口
- 示例里的标签属性必须与当前 schema 一致(防过时)
- 可保留 1 条「反面示例」说明禁止的写法
→ 示例库要版本化,schema 变更时同步失效

心智:few-shot 的本质是「用示例教结构」而非「用规则教语法」;生产用检索式——按问题语义检索最相似的 K 条已验证示例,并强制覆盖多跳、聚合等难点模式;示例库要版本化,schema 变更时同步失效,示例质量远比数量重要。


4. 查询校验:语法、语义与白名单

为什么必须有校验层:

- 模型输出不可信:可能语法错、可能语义错、可能危险
- 直接丢给数据库 = 把数据库暴露给概率模型
- 校验层是「模型世界」与「数据库世界」之间的防火墙
→ 校验不是可选项,是上线的前提

三道闸门:

闸门 1 语法:能否被 Cypher 解析器解析(EXPLAIN 编译,不执行)
闸门 2 语义:标签 / 关系 / 属性是否在 schema 白名单内
闸门 3 安全:是否只读、是否有 LIMIT、是否触碰敏感属性
→ 三道全过才允许执行

闸门 1:语法校验(EXPLAIN 编译不执行):

def syntax_check(driver, cypher):
    try:
        with driver.session() as s:
            s.run("EXPLAIN " + cypher).consume()
        return True, None
    except Exception as e:
        return False, str(e)

闸门 2:语义白名单:

import re
ALLOWED_LABELS = {"Person", "Company", "Account"}
ALLOWED_RELS = {"WORKS_AT", "FRIEND", "TRANSFER", "OWNS"}
ALLOWED_PROPS = {"id", "name", "age", "city", "industry", "balance", "amount", "at", "since"}

def semantic_check(cypher):
    errs = []
    for lab in re.findall(r':\s*([A-Za-z_]\w*)', cypher):
        if lab not in ALLOWED_LABELS and lab not in ALLOWED_RELS:
            errs.append(f"未知标签或关系: {lab}")
    for prop in re.findall(r'\.([A-Za-z_]\w*)', cypher):
        if prop not in ALLOWED_PROPS:
            errs.append(f"未知属性: {prop}")
    return errs

闸门 3:安全校验 + 自动补 LIMIT:

FORBIDDEN = re.compile(
    r'\b(CREATE|MERGE|SET|DELETE|DETACH|REMOVE|DROP|FOREACH|LOAD\s+CSV|'
    r'CALL\s+\{?db\.|apoc\.(create|merge|refactor|periodic|do\.))\b', re.IGNORECASE)

def security_check(cypher):
    errs = []
    if FORBIDDEN.search(cypher):
        errs.append("包含禁止的写操作或高危过程")
    if not re.search(r'\bLIMIT\b', cypher, re.IGNORECASE):
        cypher = cypher.rstrip().rstrip(';') + "\nLIMIT 100"   # 自动补齐
    return errs

校验失败的处理策略:

失败类型处理
语法错把错误信息回灌给模型修复重试
未知标签检索最相近的合法标签,提示模型改用
含写操作直接拒绝,不重试(安全红线)
缺 LIMIT自动补齐后执行
超时风险加超时 + 降级到更保守的查询

心智:校验层是模型与数据库之间的防火墙,三道闸门缺一不可——语法(EXPLAIN 编译不执行)、语义(标签/关系/属性白名单)、安全(只读正则 + 强制 LIMIT);失败处理要分型:语法/语义错回灌重试,写操作直接拒绝不重试,缺 LIMIT 自动补齐。


5. 只读沙箱与安全执行

为什么需要沙箱:

- 校验层是「静态」的,正则可能被绕过
- 模型可能生成资源消耗型查询(笛卡尔积、无上界变长路径)
- 生产库上直接跑 LLM 生成的查询 = 高风险
→ 沙箱是「最后一道物理防线」

沙箱的四个层次:

1. 账号层:只读账号,无写权限(数据库层兜底)
2. 查询层:强制超时 + 强制 LIMIT + 只读事务
3. 资源层:独立实例 / 只读副本,与写入实例隔离
4. 网络层:从副本读,主库不受影响
→ 层层递进,任何一层被绕过都还有下一层

只读账号创建(Neo4j):

CREATE ROLE reader;
GRANT MATCH {*} ON GRAPH neo4j NODES * TO reader;
GRANT MATCH {*} ON GRAPH neo4j RELATIONSHIPS * TO reader;
GRANT ACCESS ON DATABASE neo4j TO reader;
// 注意:不给 CREATE / SET / DELETE 任何权限

强制超时 + 只读事务 + 行数上限:

def run_safe(driver, cypher, timeout_s=10, max_rows=1000):
    with driver.session(default_access_mode="READ") as s:   # 写操作直接报错
        result = s.run("CALL apoc.cypher.runTimeboxed($q, {}, $ms)",
                       q=cypher, ms=timeout_s * 1000)
        return result.data()[:max_rows]

资源隔离的部署形态:

形态 A:只读副本(写入集群 → 复制 → 只读副本 ← LLM 查询)
  优点:完全隔离、成本低;缺点:有复制延迟
形态 B:独立分析实例(定期快照导入,LLM 只查分析实例)
  优点:物理隔离最彻底;缺点:数据非实时
形态 C:同实例只读角色(限制权限 + 超时)
  优点:实时;缺点:仍有资源竞争风险
→ 生产优先 A 或 B,C 只用于低风险内部工具

结果集保护:

- 强制 LIMIT(校验层已加,沙箱再兜底)
- 大字段截断(长文本属性只返回前 500 字符)
- 敏感属性返回前脱敏(手机号打码)
- 返回行数超过阈值即告警
→ 保护数据库,也保护下游(避免海量结果灌给模型)

心智:沙箱是物理防线,四层递进——只读账号(无写权限)、查询层(超时 + LIMIT + 只读事务)、资源层(只读副本或独立分析实例)、网络层(从副本读);部署优先「只读副本」或「独立分析实例」,同实例只读角色只用于低风险场景;结果集也要保护(截断、脱敏、行数上限)。


6. 错误自愈与重试循环

为什么模型会「一错再错」:

- 模型看不到数据库的真实报错(除非你回灌)
- 报错信息太原始("Invalid input ')'")模型看不懂
- 没有「修正方向」时,模型倾向于原样重试
→ 自愈的关键:把错误翻译成模型能懂的话 + 给出修正方向

错误分类与处理:

错误类别典型信息处理策略
语法错误Invalid input / Unexpected回灌原始错误 + 提示检查括号与关键字
未知标签Unknown label给出最相近的合法标签候选
未知属性Unknown property给出该标签的合法属性列表
类型错误Type mismatch提示转换函数 toInteger / toFloat
超时Transaction timeout建议加索引锚点、减小深度、加 LIMIT
空结果无报错但 rows 为 0放宽条件重试一次(去掉某个过滤)

自愈循环的实现:

def text2cypher_with_retry(question, schema, llm, driver, max_attempts=3):
    cypher = llm.generate(question, schema)
    for _ in range(max_attempts):
        ok, err = syntax_check(driver, cypher)
        errs = [] if ok else [err]
        if ok:
            errs = semantic_check(cypher) + security_check(cypher)
        if not errs:
            rows = run_safe(driver, cypher)
            if rows:
                return cypher, rows
            errs = ["查询返回 0 行,请放宽条件"]
        cypher = llm.repair(question, schema, cypher, errs)   # 回灌修复
    return None, None   # 放弃,走兜底模板

修复提示(repair prompt)的写法:

你上一次生成的 Cypher 无法执行:

Cypher: {cypher}
错误: {errors}
可用标签: {labels} / 可用关系: {rels} / 可用属性: {props}

请只输出修正后的 Cypher,不要解释。

防止「无限重试」与空结果幻觉:

- 硬上限:最多 2~3 次重试
- 相同错误重复出现 → 立即放弃(模型卡住了)
- 重试预算:总耗时超阈值就降级(返回「无法回答」)
- 降级路径:模板查询兜底(预置常见问题的固定查询)
- 空结果:先判断「条件是否过严」(去掉一个 WHERE 再试)
  放宽后仍空 → 返回「未找到匹配数据」,绝不硬造答案
→ 自愈不是万能,要有「放弃」和「兜底」

心智:自愈的关键是把数据库报错「翻译」成模型能懂的修正提示,并给出合法的标签/关系/属性候选;错误要分类处理(语法回灌、未知标签给候选、类型错给转换函数、超时建议锚点与 LIMIT、空结果放宽重试);必须有硬上限、重复错误即放弃、模板兜底,绝不允许无限重试或对空结果硬造答案。


7. 图检索增强:Text2Cypher 与 GraphRAG 协同

两条路线的分工:

Text2Cypher:精确的结构化查询(谁是谁的朋友、转账总额)
GraphRAG:语义检索 + 图扩展(相关背景、多跳证据)
→ 不是二选一,而是「精确问句走 Text2Cypher,开放问句走 GraphRAG」

路由判断与混合链路:

走 Text2Cypher:问题里有明确实体/关系/聚合意图
  例:「A 公司有哪些供应商」「张三的账户余额」
走 GraphRAG:问题开放、需要背景知识
  例:「A 公司有哪些潜在风险」
混合:先 GraphRAG 召回相关子图 → 再 Text2Cypher 精确计算
→ 用一个轻量分类器或让 LLM 自己选工具
def answer(question):
    intent = classify(question)          # cypher / rag / hybrid
    if intent == "cypher":
        return text2cypher_with_retry(question, schema, llm, driver)
    if intent == "rag":
        return graphrag_answer(question)
    anchors = vector_search(question, top_k=5)     # hybrid
    subgraph = expand_subgraph(anchors, hops=2)    # 2 跳内子图
    return llm.answer(question, context=serialize(subgraph))

GraphRAG 补充 Text2Cypher 的两个场景:

场景 1:Text2Cypher 生成失败 → 用 GraphRAG 兜底给「近似答案」
场景 2:结果需要解释 → 用 GraphRAG 召回路径作为「证据链」
→ 两者互为兜底与增强

检索质量的影响因素:

- 实体链接:问题里的「A 公司」能否准确映射到图里的节点
- 子图规模:2 跳内可能已很大,要按相关性剪枝
- 序列化格式:紧凑 DSL 比自然语言描述更省 token
→ 实体链接是 GraphRAG 准确率的第一瓶颈

心智:Text2Cypher 与 GraphRAG 不是替代关系——精确的结构化问句走 Text2Cypher,开放的语义问句走 GraphRAG,混合链路是「向量召回锚点 → 图扩展子图 → 精确查询」;两者互为兜底(生成失败用 RAG 近似、结果解释用 RAG 给证据链);实体链接质量是 GraphRAG 的第一瓶颈。


8. Agent 编排:工具调用与多步推理

从单次生成到多步 Agent:

单次:问题 → Cypher → 答案(一步到位)
Agent:问题 → 思考 → 调工具 → 观察 → 再思考 → 答案
→ 复杂问题需要多步:先查实体 ID,再查关系,再聚合

可用工具集设计:

tool: get_schema()          → 返回当前 schema(含域路由)
tool: search_entity(name)   → 实体链接,返回候选节点与 ID
tool: run_cypher(query)     → 执行校验后的只读查询
tool: vector_search(text)   → 向量检索节点 / 文档
tool: expand(node_id, hops) → 扩展子图
→ 工具要「窄而清晰」,每个工具职责单一

ReAct 式循环:

Thought: 需要先找到「A 公司」的节点 ID
Action: search_entity("A 公司")
Observation: [{id:"c_1024", name:"A 公司", score:0.97}]
Thought: 有了 ID,查它的供应商及供应商的风险等级
Action: run_cypher("MATCH (c:Company {id:'c_1024'})<-[:SUPPLIES]-(s:Company) RETURN s.name, s.risk LIMIT 100")
Observation: [{s.name:"B", s.risk:"高"}, ...]
Answer: ...

工具调用的关键约束与上下文管理:

- run_cypher 的输入必须过校验层(复用第 4 节的三道闸门)
- 每步工具调用有超时,总步数有上限(如 6 步)
- 观察结果要截断(避免把大结果集塞回上下文)
- 工具报错作为 Observation 回灌,让 Agent 自我修正
- 每步 Observation 只保留必要摘要;历史超 N 步做摘要压缩
→ Agent 自由度越高,约束必须越硬;上下文膨胀是延迟与成本主因

多步推理的适用与不适用:

适用:需要先消歧实体、再按结果决定下一步的探索式问题
不适用:单跳事实查询(多步只会增加延迟与出错面)
→ 简单问题走单次生成,复杂问题才上 Agent

心智:Agent 编排把「一次生成」升级为「思考-工具-观察」多步循环,工具集要窄而清晰(get_schema / search_entity / run_cypher / vector_search / expand);run_cypher 必须复用校验层,每步超时、总步数上限、观察结果截断;简单问题别上 Agent(徒增延迟与出错面),上下文膨胀是成本主因。


9. 评测体系与生产实践

三层评测指标:

1. 查询级:生成的 Cypher 是否可执行(执行率)
2. 结果级:执行结果是否与标准答案一致(结果准确率)
3. 端到端:最终答案是否被用户接受(人工 / LLM 评审)
→ 只测第 1 层会「语法全对但结果全错」

评测数据集构建与宽松匹配:

- 从真实问题日志采样(覆盖高频意图)
- 每条包含:问题 + 标准 Cypher + 期望结果
- 分层:单跳 / 多跳 / 聚合 / 时间 / 组合
- 规模:200~500 条即可覆盖主要失效模式
- 匹配方式:不比字符串,比「执行结果集」(顺序无关)
def exec_match(pred, gold, driver):
    p = set(map(frozenset, run_safe(driver, pred)))
    g = set(map(frozenset, run_safe(driver, gold)))
    return p == g

常见评测结论:

优化手段执行准确率变化(相对基线)
加 schema 提示显著提升(从不可用到底线可用)
加 few-shot(静态)中等提升
换检索式 few-shot明显提升
加校验 + 重试执行率大幅提升
加实体链接复杂问题准确率提升明显

生产落地的运维项与产品设计:

运维:全量日志(问题 / Cypher / 校验结果 / 耗时)
      失败样本回流待标注池,人工修正后进示例库
      灰度:新提示 / 新模型先小流量对比,指标不降才全量
      监控:执行率、空结果率、超时率、用户追问率
产品:展示生成的 Cypher(可解释、可信任)
      结果可一键转可视化图;支持「改一句再问」的交互
      明确标注「AI 生成,仅供参考」
→ 上线不是终点,是持续迭代的起点;透明 + 可纠正优于假装全对

心智:评测要分三层(可执行率、结果准确率、端到端接受度),只测执行率会漏掉「语法全对结果全错」;评测集 200~500 条覆盖五类意图并持续更新;生产要全量日志、失败样本回流示例库、灰度对比、监控执行率与追问率;产品侧要透明(展示 Cypher)与可纠正(支持改问)。


10. 成本、延迟与常见坑

延迟拆解与成本构成:

总延迟 = LLM 生成(1~5s)+ 校验(<50ms)+ 执行(10ms~10s)+ 答案组织(1~3s)
- LLM 生成是大头:用小模型做简单意图、流式输出降低体感延迟
- 执行可能失控:靠索引 + LIMIT + 超时控制
- 多步 Agent 延迟翻倍:限制步数
成本 = 输入 token(schema + few-shot + 问题)+ 输出 token + 每步 Agent 输入
降本三招:schema 精简、few-shot 缓存(prompt caching)、简单问题走小模型
→ 优化优先级:执行正确性 > 生成延迟 > 答案润色

常见坑清单:

坑 1:schema 硬编码在提示里 → 图演进后模型仍用旧标签
坑 2:不做校验直接执行 → 一次误生成的写操作毁库
坑 3:不强制 LIMIT → 模型生成全表返回,打爆内存
坑 4:把原始报错直接回灌 → 模型看不懂,反复犯同一错
坑 5:空结果当「没有数据」返回 → 实际是查询条件写错
坑 6:few-shot 示例过时 → 示例里的标签已不存在,误导模型
坑 7:多步 Agent 无步数上限 → 无限循环烧钱
坑 8:结果集直接塞回模型 → 上下文爆炸
坑 9:评测只看生成不看结果 → 上线后发现结果大面积错
坑 10:无兜底路径 → 生成失败时用户体验断崖

上线检查清单:

[ ] schema 提示自动生成(不硬编码)
[ ] 三道校验闸门齐全(语法 / 语义 / 安全)
[ ] 只读账号 + 超时 + 强制 LIMIT
[ ] 错误自愈有硬上限与兜底模板
[ ] 全量日志与失败样本回流
[ ] 评测集覆盖五类意图
[ ] 灰度发布与指标对比
[ ] 用户侧展示 Cypher 并可纠正

心智:Text2Cypher 的十大坑集中在四处——schema 与示例过时(模型误导)、安全与资源约束缺失(毁库/打爆)、错误自愈设计不当(反复犯错/无限循环)、评测与兜底缺失(上线才发现结果全错);上线前逐条过检查清单,把「模型的不确定性」用工程约束兜住。


速查表

链路与要点:

环节关键动作核心风险
Schema 提示紧凑 DSL、属性裁剪、两级路由过时 schema 误导模型
Few-shot检索式、覆盖难点模式、版本化示例过时
语法校验EXPLAIN 编译不执行无校验直接执行
语义校验标签 / 关系 / 属性白名单编造标签
安全校验只读正则 + 强制 LIMIT写操作毁库
沙箱执行只读账号 + 超时 + 副本资源竞争
错误自愈报错翻译 + 候选提示 + 硬上限无限重试
GraphRAG 协同意图路由、混合链路实体链接错误
Agent 编排窄工具集 + 步数上限上下文膨胀
评测三层指标 + 200~500 条只测生成不测结果

一句话记忆:Text2Cypher 的成败不在模型而在工程约束——语义鸿沟四处(词汇/结构/度量/时间),前两者靠 schema 提示(紧凑 DSL + 高频属性 + 两级路由,控制在 2K~4K token)、后两者靠业务词典;few-shot 用检索式并按问题取最相似示例;生成后必须过三道闸门(EXPLAIN 语法、标签关系属性白名单、只读正则 + 强制 LIMIT),再进只读沙箱(只读账号 + 超时 + 只读副本)执行;报错要翻译成模型能懂的修正提示并给合法候选,自愈有硬上限与模板兜底;复杂探索式问题才上 Agent(窄工具集 + 步数上限 + 观察截断),简单问题单次生成即可;评测分三层(可执行率、结果准确率、端到端),只测执行率会漏掉「语法全对结果全错」;上线后全量日志、失败样本回流示例库、灰度对比,产品侧展示生成的 Cypher 并允许用户改问——用工程约束把概率模型的不确定性兜住,才是可上线的 Text2Cypher。


延伸阅读

  • /graphdb-neo4j-cypher-guide/ — Cypher 语法与查询基础
  • /graphdb-cypher-advanced/ — 高级查询、子查询与过程调用
  • /graphdb-graphrag-vector/ — 向量检索与图检索增强
  • /graphdb-graph-query-optimization/ — 执行计划与慢查询诊断
  • /graphdb-schema-constraints-governance/ — Schema 治理与数据质量
  • /graphdb-knowledge-graph-reasoning/ — 知识图谱推理与语义查询

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「graphdb」更多文章

  1. 流式图处理与实时图计算:CDC 入图、增量更新与窗口化子图
  2. 图数据库访问控制与数据安全:角色、标签级权限与多租户隔离
  3. 图数据库容量规划与成本优化:内存估算、分片与云实例选型