85 lines
3.4 KiB
Python
85 lines
3.4 KiB
Python
"""推断偏好聚合的纯函数护栏:事件阈值、比例、原话依据、条数上限与排序。"""
|
||
|
||
import pytest
|
||
|
||
from muse.作者经验.推断偏好 import 生成建议, 聚合挑选明细
|
||
|
||
|
||
def _明细(动作, 原话="", 时刻=0):
|
||
return {
|
||
"feedback_id": f"fb-{动作}-{时刻}",
|
||
"created_at": 时刻,
|
||
"domain": "combat",
|
||
"query": "机甲",
|
||
"quote": 原话,
|
||
"method_version_id": "v1",
|
||
"action": 动作,
|
||
}
|
||
|
||
|
||
@pytest.mark.case_id(
|
||
"NC-w32-a10020",
|
||
environment="离线",
|
||
given="构造的挑选明细(时间倒序)",
|
||
when="聚合明细并生成推断建议",
|
||
then=["分列计数、依据取最近非空原话、护栏与排序生效"],
|
||
contract="docs/系统架构/新版设计/模块设计/B07-作者经验.md#偏好双轨关系",
|
||
)
|
||
def test_聚合与建议护栏__a10020():
|
||
# 明细按时间倒序(与存储读法一致):最近的原话在前
|
||
明细 = [
|
||
_明细("selected", "最近的打戏原话", 9),
|
||
_明细("selected", "", 8),
|
||
_明细("selected", "较早的原话", 7),
|
||
_明细("selected", "", 6),
|
||
_明细("rejected", "", 5),
|
||
]
|
||
聚合 = 聚合挑选明细(明细)
|
||
桶 = 聚合[("combat", "v1")]
|
||
assert 桶["选用次数"] == 4 and 桶["拒绝次数"] == 1
|
||
assert 桶["选用依据"]["quote"] == "最近的打戏原话"
|
||
|
||
标题表 = {"v1": {"title": "机甲近身刀法"}}
|
||
建议 = 生成建议(聚合, 标题表)
|
||
assert len(建议) == 1
|
||
条 = 建议[0]
|
||
assert 条["topic"] == "参考偏好:combat"
|
||
assert "机甲近身刀法" in 条["text"] and "选用 4 次" in 条["text"]
|
||
assert 条["quote"] == "最近的打戏原话"
|
||
assert 条["feedback_id"] == "fb-selected-9"
|
||
assert 条["证据"]["causality"] == "not_established"
|
||
|
||
# 护栏1:支撑事件不足 5 不生成
|
||
assert 生成建议(聚合挑选明细(明细[:3]), 标题表) == []
|
||
# 护栏2:选用未达 3 倍拒绝不生成(3选2拒=5事件但 3 < 3*2)
|
||
胶着 = [
|
||
_明细("selected", "原话", 5),
|
||
_明细("selected", "", 4),
|
||
_明细("selected", "", 3),
|
||
_明细("rejected", "", 2),
|
||
_明细("rejected", "", 1),
|
||
]
|
||
assert 生成建议(聚合挑选明细(胶着), 标题表) == []
|
||
# 护栏3:无原话依据不生成
|
||
无原话 = [_明细("selected", "", i) for i in range(5)]
|
||
assert 生成建议(聚合挑选明细(无原话), 标题表) == []
|
||
# 回避倾向:拒绝 ≥5 且 ≥3 倍选用,带拒绝原话
|
||
回避 = [_明细("rejected", "不要这种花哨写法", 9)] + [_明细("rejected", "", i) for i in range(4)]
|
||
回避建议 = 生成建议(聚合挑选明细(回避), 标题表)
|
||
assert len(回避建议) == 1 and "避免" in 回避建议[0]["text"]
|
||
assert 回避建议[0]["quote"] == "不要这种花哨写法"
|
||
|
||
# 护栏4:至多 5 条,按支撑事件降序
|
||
多版本 = {}
|
||
for 序 in range(7):
|
||
vid = f"v{序}"
|
||
行 = [
|
||
{**_明细("selected", f"原话{序}", 时刻), "method_version_id": vid}
|
||
for 时刻 in range(5 + 序)
|
||
]
|
||
多版本.update(聚合挑选明细(行))
|
||
全部 = 生成建议(多版本, {f"v{序}": {"title": f"方法{序}"} for 序 in range(7)})
|
||
assert len(全部) == 5
|
||
事件数 = [条["支撑事件"] for 条 in 全部]
|
||
assert 事件数 == sorted(事件数, reverse=True)
|