muse-agent-example/tests/单元/test_推断偏好聚合.py

85 lines
3.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""推断偏好聚合的纯函数护栏:事件阈值、比例、原话依据、条数上限与排序。"""
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)