本项目用于从商品 Markdown chunk 中抽取可比数值属性,并基于规则构造 Qwen Rerank pointwise 训练数据。
整体流程如下:
原始 JSONL 商品数据
-> Markdown chunk 预处理
-> LLM 抽取结构化可比属性
-> 属性分布统计
-> 基于规则生成 rerank pointwise 数据
data/
merged_markdown_content_for_ingest.jsonl 原始商品 Markdown 数据
processed_markdown_content.jsonl 预处理后的 chunk 数据
test.jsonl 少量测试数据
attribute/
test_structured_facts.jsonl LLM 抽取后的结构化属性
test_structured_facts.errors.jsonl 抽取失败记录
test_structured_facts.usage.jsonl token 与费用统计
fact_stats.json 属性统计结果
fact_stats.md 属性统计 Markdown 报告
rerank_pointwise/
train.jsonl 训练集
test.jsonl 测试集
stats.json 数据生成统计
prompt/
prompt1.py / prompt2.py LLM 属性抽取提示词
query_gen.md 规则构造方案说明
脚本:
preprocess_markdown_jsonl.py
功能:
- 保留
id >= 4554的原始数据。 - 按 Markdown 二级标题
##切分文档。 - 每个切分文档保留一级标题和一级标题下的公共前缀内容。
- 输出 ID 从
0开始连续编号。
示例:
python preprocess_markdown_jsonl.py data\merged_markdown_content_for_ingest.jsonl data\processed_markdown_content.jsonl脚本:
extract_comparable_facts_qwen.py
功能:
- 调用百炼平台 Qwen 模型,使用 OpenAI 兼容接口。
- 读取
prompt\prompt2.py中的提示词。 - 对每个商品 chunk 抽取结构化可比数值属性。
- 对模型输出做 Pydantic 结构校验。
- 校验
doc_id和evidence是否能对应原文。 - 支持并发、重试、断点续跑。
- 记录输入 token、输出 token 和费用。
运行前先配置 .env:
测试运行:
python extract_comparable_facts_qwen.py --limit 10 --overwrite全量运行时可指定输入输出:
python extract_comparable_facts_qwen.py `
--input data\processed_markdown_content.jsonl `
--output data\attribute\test_structured_facts.jsonl `
--errors data\attribute\test_structured_facts.errors.jsonl `
--usage-output data\attribute\test_structured_facts.usage.jsonl `
--concurrency 16如果中途停止,重新运行会跳过已成功写入 output 的 doc_id。
脚本:
analyze_structured_facts.py
功能:
- 统计
normalized_attribute - 统计
raw_attribute - 统计
object - 统计
unit - 统计
normalized_attribute + object - 统计
其他可比数值属性下的原始属性分布 - 统计
object == 商品的属性分布
运行:
python analyze_structured_facts.py输出:
data\attribute\fact_stats.json
data\attribute\fact_stats.md
脚本:
generate_doc_centric_rerank_data.py
功能:
- 读取 LLM 抽取结果。
- 按
doc_id从processed_markdown_content.jsonl补齐doc_text。 - 基于规则生成 pointwise 样本:
- positive
- boundary negative
- unit boundary negative
- object mismatch negative
- condition mismatch negative
- partial match negative
- 生成前按文档做
95:5train/test 切分,避免同一文档泄漏。 - 属性列表为空的文档会跳过。
object == 商品的事实会跳过,不参与 query 构造。
运行:
python generate_doc_centric_rerank_data.py默认输出:
data\rerank_pointwise\train.jsonl
data\rerank_pointwise\test.jsonl
data\rerank_pointwise\stats.json
可调整每个文档生成样本数:
python generate_doc_centric_rerank_data.py `
--min-samples-per-doc 3 `
--max-samples-per-doc 10生成的 pointwise 样本格式:
{
"query_id": "q_00000001",
"query": "有没有单耳机重量低于6g的耳机?",
"doc_id": 123,
"doc_text": "# 商品说明...",
"label": 1,
"label_text": "yes",
"sample_type": "positive",
"negative_type": null,
"constraints": [
{
"raw_attribute": "重量(参考值)",
"normalized_attribute": "重量",
"object": "单耳机",
"operator": "<=",
"value": 6,
"unit": "g",
"condition": {},
"value_type": "number"
}
],
"source_doc_id": 123,
"source": "doc_centric_rule",
"reason": "当前文档明确满足:单耳机重量不超过6g"
}pip install -r requirements.txt当前依赖主要用于 Qwen API 调用和结构校验:
openai
pydantic
python-dotenv
.env中包含 API Key,不应提交到版本库。- 抽取属性质量会直接影响后续规则生成质量。
其他可比数值属性在 query 中会使用raw_attribute,避免问题文本出现泛化字段名。object == 商品的属性当前被过滤,因为生成的问题过泛、区分度较弱。fact_stats.md建议用于后续人工校准规则,例如补充 higher/lower 比较方向和 object mismatch 候选。