文章目录
基于 LLM 实现 Rerank
下边通过设计 Prompt 让 LLM 实现重排序的功能。
函数定义
python
class LLMReranker:
def __init__(self, llm_client):
self.llm = llm_client
def rerank(self, query: str, documents: list[dict]) -> list[dict]:
# 构建 prompt
prompt = self._build_rerank_prompt(query, documents)
# 调用 LLM
response = self.llm.chat.completions.create(
model="gpt-3.5-turbo",
temperature=0, # 降低随机性
messages=[
{"role": "system", "content": """你是一个专业的搜索结果重排序专家。
你的任务是:
1. 评估每个文档与用户查询的相关性
2. 给出0-1之间的相关性分数
3. 解释评分理由
4. 按相关性从高到低排序
评分标准:
- 0.8-1.0: 完全相关,直接回答问题
- 0.6-0.8: 高度相关,包含大部分所需信息
- 0.4-0.6: 部分相关,包含一些相关信息
- 0.0-0.4: 基本不相关
请以JSON格式返回结果。"""},
{"role": "user", "content": prompt}
]
)
# 解析响应
try:
results = eval(response.choices[0].message.content)
return results
except:
return []
def _build_rerank_prompt(self, query: str, documents: list[dict]) -> str:
prompt = f"""请对以下文档进行重排序:
用户查询: {query}
待排序文档:
"""
for i, doc in enumerate(documents, 1):
prompt += f"""
文档{i}:
ID: {doc['id']}
内容: {doc['text']}
"""
prompt += """
请以如下JSON格式返回重排序结果:
[
{
"id": "文档ID",
"score": 相关性分数,
"reason": "评分理由"
},
...
]
"""
return prompt
# 使用示例
def main():
# 初始化查询和文档
query = "Python如何处理JSON数据?"
documents = [
{
"id": "doc1",
"text": "Python提供了json模块来处理JSON数据。使用json.loads()可以将JSON字符串转换为Python对象,使用json.dumps()可以将Python对象转换为JSON字符串。",
},
{
"id": "doc2",
"text": "在Python中,字典(dict)是一种常用的数据结构,它的格式与JSON非常相似。你可以使用字典来存储键值对数据。",
},
{
"id": "doc3",
"text": "Python是一种面向对象的编程语言,支持类和对象的概念。你可以创建自定义类来组织数据和行为。",
}
]
# 初始化 LLM client (这里以 OpenAI 为例)
from openai import OpenAI
client = OpenAI()
# 执行重排序
reranker = LLMReranker(client)
results = reranker.rerank(query, documents)
# 打印结果
print("\n查询:", query)
print("\n重排序结果:")
for i, result in enumerate(results, 1):
print(f"\n{i}. 文档ID: {result['id']}")
print(f" 相关性分数: {result['score']}")
print(f" 评分理由: {result['reason']}")
预期输出
json
[
{
"id": "doc1",
"score": 0.95,
"reason": "文档直接回答了如何处理JSON数据的问题,提供了具体的json模块使用方法(loads和dumps函数),信息完整且准确。"
},
{
"id": "doc2",
"score": 0.65,
"reason": "文档提到了Python字典与JSON的关系,对理解JSON处理有帮助,但没有直接说明处理方法。"
},
{
"id": "doc3",
"score": 0.2,
"reason": "文档只介绍了Python的面向对象特性,与JSON数据处理无直接关系。"
}
]
实现说明
-
简单易用:
- 不需要额外的模型
- 只依赖LLM API
- 实现逻辑清晰
-
灵活性强:
- 可以通过修改prompt调整评分标准
- 可以获取评分理由
- 支持多维度评估
-
可解释性好:
- 每个分数都有明确的理由
- 评分标准透明
- 便于调试和优化
-
适应性强:
- 可处理各种领域的问题
- 不需要领域特定训练
- 支持多语言
使用建议
- Prompt优化:
python
# 可以添加更多评分维度
"""
评分维度:
1. 相关性: 内容与查询的关联程度
2. 完整性: 信息的完整程度
3. 准确性: 信息的准确程度
4. 时效性: 信息的新旧程度
"""
- 批量处理:
python
# 对于大量文档,可以分批处理
def batch_rerank(self, query: str, documents: list, batch_size: int = 5):
results = []
for i in range(0, len(documents), batch_size):
batch = documents[i:i + batch_size]
batch_results = self.rerank(query, batch)
results.extend(batch_results)
return sorted(results, key=lambda x: x['score'], reverse=True)
- 错误处理:
python
try:
response = self.llm.chat.completions.create(...)
results = eval(response.choices[0].message.content)
except Exception as e:
print(f"重排序错误: {str(e)}")
# 返回原始顺序
return [{"id": doc["id"], "score": 0.5} for doc in documents]
- 缓存结果:
python
from functools import lru_cache
@lru_cache(maxsize=1000)
def cached_rerank(self, query: str, doc_key: str):
# 实现缓存逻辑
pass
这种基于LLM的重排序方案特别适合:
- 快速原型验证
- 小规模应用
- 需要高可解释性的场景
- 多语言或跨领域应用
完整 Prompt
你是一个专业的搜索结果重排序专家。你的任务是评估每个文档与用户查询的相关性,并给出排序。
评分标准:
1. 相关性分数范围: 0.0-1.0
- 0.8-1.0: 完全相关,直接回答问题
- 0.6-0.8: 高度相关,包含大部分所需信息
- 0.4-0.6: 部分相关,包含一些相关信息
- 0.0-0.4: 基本不相关
2. 评分维度:
- 相关性: 文档内容是否直接回答查询问题
- 完整性: 回答的信息是否完整
- 准确性: 信息是否准确专业
- 直接性: 是否需要用户进一步推理或处理
用户查询: Python如何处理JSON数据?
待评估文档:
文档1:
ID: doc1
内容: Python提供了json模块来处理JSON数据。使用json.loads()可以将JSON字符串转换为Python对象,使用json.dumps()可以将Python对象转换为JSON字符串。
文档2:
ID: doc2
内容: 在Python中,字典(dict)是一种常用的数据结构,它的格式与JSON非常相似。你可以使用字典来存储键值对数据。
文档3:
ID: doc3
内容: Python是一种面向对象的编程语言,支持类和对象的概念。你可以创建自定义类来组织数据和行为。
请按以下JSON格式返回重排序结果,必须包含id字段:
[
"文档ID",
...
]
注意:
1. 结果必须按score从高到低排序
2. 结果中只需要给出id字段
3. 返回格式必须是合法的JSON格式,不要做任何解释