在企业法务审查大型商业合同时,最让人头疼的是主合同文本与其背后几十份庞杂技术附件、SLA(服务等级协议)之间的逻辑冲突。
例如,主合同的责任限制条款规定“最高赔偿限额为合同总金额”,但附件 SLA 中却规定“若可用性低于 99.5%,需向甲方赔偿双倍损失”。在法律执行上,这种条款的前后矛盾极易引发争议。
为此,三函代码开发了一套基于**多文档依赖图谱(Document Graph)**的合同冲突检测系统。
一、 多文档图谱架构
我们将全套合作协议的每一个条款抽象为图中的一个节点,并建立以下三种有向关系边:
references:代表条款之间的互相引用。overrides:代表优先顺序或覆盖关系(如主约声明其效力高于附件)。contradicts:代表语义上存在潜在逻辑冲突。
二、 基于 Python 的合同条款冲突检测实现
以下为基于文本特征提取和 NetworkX 图谱,自动检测交叉条款冲突的 Python 实现:
import networkx as nx
from sentence_transformers import SentenceTransformer, util
# 加载轻量级语义比对模型
similarity_model = SentenceTransformer('shibing624/text2vec-base-chinese')
def build_contract_document_graph(clauses):
"""
clauses: 字典列表 [{'id', 'doc_name', 'text', 'category'}]
"""
G = nx.DiGraph()
for c in clauses:
G.add_node(c['id'], doc=c['doc_name'], text=c['text'], category=c['category'])
return G
def detect_clause_conflicts(G):
"""
在图谱中比对同一类别下的条款,检测语义是否冲突
"""
nodes = list(G.nodes(data=True))
conflicts = []
# 逐对计算语义特征
for i in range(len(nodes)):
for j in range(i + 1, len(nodes)):
n1_id, n1_data = nodes[i]
n2_id, n2_data = nodes[j]
# 仅比对相同类别(如“赔偿限额”、“知识产权归属”)但位于不同文档下的条款
if n1_data['category'] == n2_data['category'] and n1_data['doc'] != n2_data['doc']:
emb1 = similarity_model.encode(n1_data['text'], convert_to_tensor=True)
emb2 = similarity_model.encode(n2_data['text'], convert_to_tensor=True)
cosine_sim = util.cos_sim(emb1, emb2).item()
# 如果语义非常相关,但表达了不同甚至相反的意思,则发出警告
# 例如,一个限制在 100%,另一个限制在 200% 或无限
if 0.5 < cosine_sim < 0.85: # 语义接近但数值/条件可能有偏离
if any(kw in n1_data['text'] for kw in ["赔偿", "无限", "双倍"]) != any(kw in n2_data['text'] for kw in ["赔偿", "无限", "双倍"]):
conflicts.append({
"clause_1": n1_id,
"clause_2": n2_id,
"category": n1_data['category'],
"similarity": cosine_sim,
"reason": "检测到跨文档同类条款存在表达不一致性,可能存在赔偿限额冲突!"
})
return conflicts三、 谈判替代条款推荐
当检测到高风险条款时,系统不仅进行报警,还会自动从内部的“合规条款模板库”中检索出最佳实践,自动将高风险的“单方知识产权归属”重写为符合双方商业对等性的替代条款。 这让董事会在决策签约时,能够手握极具技术说服力的“修改批注版草案”,在商务谈判中占据主动权。