README_semantic_similarity.md 7.3 KB

语义相似度分析模块

功能概述

提供基于 AI Agent 的语义相似度分析功能,支持缓存机制以提高性能和降低 API 调用成本。

主要功能

1. 核心函数

  • difference_between_phrases() - 返回原始 AI 响应
  • difference_between_phrases_parsed() - 返回解析后的 JSON 字典
  • compare_phrases() - difference_between_phrases_parsed() 的别名

2. 缓存系统设计

缓存文件名设计

方案:可读文件名 + 哈希后缀

cache/semantic_similarity/
├── 宿命感_vs_余华的小说_gpt-4.1-mini_t0.0_a7f3e2d9.json
├── 人工智能_vs_机器学习_claude-sonnet-4.5_t0.0_b8e4f3e0.json
├── 深度学习_vs_神经网络_gemini-2.5-pro_t0.2_c9f5g4h1.json
└── 创意写作_vs_AI生成_gpt-4.1-mini_t0.7_d0a6h5i2.json

文件名格式:

{phrase_a}_vs_{phrase_b}_{model}_t{temp}_{hash[:8]}.json
  • phrase_a: 第一个短语(最长20字符,特殊字符转为下划线)
  • phrase_b: 第二个短语(最长20字符,特殊字符转为下划线)
  • model: 模型简称(提取 / 后部分,最长20字符)
  • t{temp}: 温度参数(格式化为1位小数,如 t0.0, t0.2, t0.7)
  • hash[:8]: 完整哈希的前8位

哈希生成逻辑:

  • 基于所有影响结果的参数生成唯一 MD5 哈希:
    • phrase_a - 第一个短语
    • phrase_b - 第二个短语
    • model_name - 模型名称
    • temperature - 温度参数
    • max_tokens - 最大 token 数
    • prompt_template - 提示词模板

缓存文件格式(结构化 JSON):

{
  "input": {
    "phrase_a": "宿命感",
    "phrase_b": "余华的小说",
    "model_name": "openai/gpt-4.1-mini",
    "temperature": 0.0,
    "max_tokens": 65536,
    "prompt_template": "从语意角度,判断【{phrase_a}】和【{phrase_b}】..."
  },
  "output": {
    "result": "{\n  \"说明\": \"...\",\n  \"相似度\": 0.75\n}"
  },
  "metadata": {
    "timestamp": "2025-11-19 14:30:45",
    "cache_key": "a7f3e2d9c1b4a5f8e6d7c9b2a1f3e5d7",
    "cache_file": "宿命感_vs_余华的小说_gpt-4.1-mini_t0.0_a7f3e2d9.json"
  }
}

缓存特性

  1. 自动缓存:默认启用,首次调用保存结果
  2. 智能匹配:相同参数自动从缓存读取
  3. 可控性:支持 use_cache=False 强制重新请求
  4. 可追溯:缓存文件包含完整元数据和时间戳
  5. 自定义目录:支持通过 cache_dir 参数自定义缓存位置

使用示例

基本使用(自动缓存)

from lib.semantic_similarity import compare_phrases

# 第一次调用 - 请求 API 并缓存
result = await compare_phrases("宿命感", "余华的小说")
# 输出: ✓ 已缓存: 宿命感_vs_余华的小说_gpt-4.1-mini_t0.0_a7f3e2d9.json

# 第二次调用相同参数 - 从缓存读取
result = await compare_phrases("宿命感", "余华的小说")
# 输出: ✓ 使用缓存: 宿命感_vs_余华的小说_t0.0_a7f3e2d9.json

print(result['相似度'])  # 0.3
print(result['说明'])    # "两个概念..."

禁用缓存

# 强制重新请求 API
result = await compare_phrases(
    "人工智能",
    "机器学习",
    use_cache=False
)

自定义缓存目录

# 使用自定义缓存目录
result = await compare_phrases(
    "深度学习",
    "神经网络",
    cache_dir="my_cache/similarity"
)

自定义提示词模板

custom_template = """
请详细分析【{phrase_a}】和【{phrase_b}】的语义关系
输出格式:
```json
{{
  "说明": "详细分析",
  "相似度": 0.5,
  "关系类型": "相关/包含/对立/无关"
}}

"""

result = await compare_phrases(

"机器学习",
"深度学习",
prompt_template=custom_template

)


### 配置不同模型

```python
# 使用 Claude 模型
result = await compare_phrases(
    "人工智能",
    "深度学习",
    model_name='anthropic/claude-sonnet-4.5',
    temperature=0.2
)

缓存管理

查看缓存

# 查看缓存目录
ls cache/semantic_similarity/

# 查看特定缓存文件
cat cache/semantic_similarity/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6.json

清理缓存

# 清理所有缓存
rm -rf cache/semantic_similarity/

# 清理特定缓存文件
rm cache/semantic_similarity/a1b2c3d4*.json

缓存统计

from pathlib import Path
import json

cache_dir = Path("cache/semantic_similarity")
cache_files = list(cache_dir.glob("*.json"))

print(f"缓存文件总数: {len(cache_files)}")

# 统计各模型使用情况
model_stats = {}
for file in cache_files:
    with open(file, 'r') as f:
        data = json.load(f)
        model = data.get('model_name', 'unknown')
        model_stats[model] = model_stats.get(model, 0) + 1

print("各模型缓存数量:")
for model, count in model_stats.items():
    print(f"  {model}: {count}")

参数说明

所有函数共享参数

参数 类型 默认值 说明
phrase_a str 必填 第一个短语
phrase_b str 必填 第二个短语
model_name str 'openai/gpt-4.1-mini' 使用的 AI 模型
temperature float 0.0 温度参数(0.0-1.0)
max_tokens int 65536 最大生成 token 数
prompt_template str None 自定义提示词模板
use_cache bool True 是否启用缓存
cache_dir str 'cache/semantic_similarity' 缓存目录路径

支持的模型

  • 'google/gemini-2.5-pro'
  • 'anthropic/claude-sonnet-4.5'
  • 'google/gemini-2.0-flash-001'
  • 'openai/gpt-5-mini'
  • 'anthropic/claude-haiku-4.5'
  • 'openai/gpt-4.1-mini' (默认)

性能优化

缓存命中率优化

  1. 参数标准化:确保相同语义使用相同参数
  2. 批量处理:对相同短语对只调用一次
  3. 预热缓存:提前为常用短语对生成缓存

示例:批量处理

phrase_pairs = [
    ("宿命感", "余华的小说"),
    ("人工智能", "机器学习"),
    ("深度学习", "神经网络"),
]

for phrase_a, phrase_b in phrase_pairs:
    result = await compare_phrases(phrase_a, phrase_b)
    print(f"{phrase_a} vs {phrase_b}: {result['相似度']}")

注意事项

  1. 参数敏感性:任何参数变化都会导致新的缓存键
  2. 存储空间:长期使用可能积累大量缓存文件
  3. 缓存一致性:模型更新后建议清理旧缓存
  4. 并发安全:当前实现不支持并发写入同一缓存文件

故障排查

缓存未命中

问题:相同参数调用但未使用缓存

可能原因

  • 参数细微差异(如空格、换行)
  • prompt_template 不一致
  • 缓存文件损坏或被删除

解决方案

# 检查缓存键
from lib.semantic_similarity import _generate_cache_key, DEFAULT_PROMPT_TEMPLATE

key = _generate_cache_key(
    "宿命感", "余华的小说",
    "openai/gpt-4.1-mini", 0.0, 65536,
    DEFAULT_PROMPT_TEMPLATE
)
print(f"缓存键: {key}")

缓存损坏

问题:缓存文件存在但无法加载

解决方案

# 删除损坏的缓存文件
rm cache/semantic_similarity/{cache_key}.json

版本历史

  • v1.0 - 初始版本,支持基本语义相似度分析
  • v1.1 - 添加缓存系统
  • v1.2 - 支持自定义提示词模板
  • v1.3 - 优化缓存文件格式,添加元数据