mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 15:12:00 +00:00
735dc32052
- 交结果的提示(VERIFY_FINAL_PROMPT,双盲复算、反方审稿、审批质询共用)以前写「提到某次查询时写 [[see:Q1]]」,模型就 把它写进括号、句中;反方审稿的系统提示自己也把它写在括号里(「([[v:Qn.rX.列名]] 或 [[see:Qn]])」)。改成和写作者 一致:依据挂在句末(「……结果一致。[[see:Q3]]」),说明它渲染后不显示,不要放进括号、句中或「依据」「见」「取自」 后面。已经写进括号的由上一个提交的渲染收拾干净 - 模型自己停了查询、收尾那次调用超过时长上限时,limit 以前是 None:质询的报错写着「回答超过时长上限(180 秒)」, answer.limit 却是 null,界面少了「已达时长上限」;双盲复算、反方审稿把它当成别的原因,审批卡上照出内部原话。 现在记 timeout_s;循环里先撞上的上限照旧优先(同金额被拒的收尾),结构化输出、退回普通调用两条路都一样 - 交回的理由是空的、只有标点,或者只是一个占位词(验收里盲算交了字面的「placeholder」,审批卡照着显示):当没给 理由,不组装理由文档。反方审稿的记录里理由为空,审批卡照旧写「反方没有给出理由」;质询照「模型没有给出回答内容」 报错;双盲复算的对照工件里说明为空 测试:交给模型的提示(含三处调用方的系统提示、任务)里不再示范括号里的依据;写进括号的依据在理由文档里渲染干净、 仍挂在句子上;审批质询的回答、反方审稿的理由、双盲复算的说明端到端都没有空括号;收尾超时 limit 为 timeout_s(核查 agent 和质询接口、事件里都是);占位词的理由三处都不当理由。
65 lines
3.4 KiB
Python
65 lines
3.4 KiB
Python
"""反方审稿的理由:依据写进括号不再断句,占位词不当理由(期 5 真实模型验收 M1)。
|
||
|
||
真实模型验收里,反方的理由「先按订单状态做全量概览核对口径([[see:Q1]]):」「复算写作者的原查询(同 SQL 同过滤条件,
|
||
[[see:Q2]])」渲染成「():」「(同 SQL 同过滤条件,)」:审稿记录(rationale 和 rationale_doc)随正式运行封存,审批卡上
|
||
照片段原文显示。
|
||
|
||
模型一律是 MockChatModel 剧本,区域、金额都是虚构的。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from app.core import artifact_store
|
||
from tests.test_challenge_node import ( # noqa: F401 - 夹具按名字引入
|
||
NET,
|
||
REFUNDS,
|
||
Models,
|
||
Play,
|
||
engine_up,
|
||
finish,
|
||
graph,
|
||
output_of,
|
||
shop,
|
||
)
|
||
|
||
BROKEN = ("()", "(,", ",)", "()", "(,", ",)")
|
||
|
||
|
||
async def _record(monkeypatch, shop, plays) -> tuple[dict, dict]:
|
||
Models(monkeypatch, shop, plays=plays)
|
||
row = await finish(graph(shop))
|
||
assert row.status == "succeeded", row.error
|
||
out = await output_of(row.id, "chal")
|
||
return artifact_store.load(out["challenge_artifact"]), row.output["_issuance"]
|
||
|
||
|
||
async def test_see_in_brackets_does_not_break_the_rationale(monkeypatch, shop):
|
||
plays = {
|
||
"华南销售额超过华东": Play([NET], "refuted", "扣除退款后华南为 [[v:Q1.r1.净销售额]]([[see:Q1]]),"
|
||
"仍低于华东的 [[v:Q1.r0.净销售额]](同口径,[[see:Q1]])。"),
|
||
"居各区域之首": Play([REFUNDS], "weakened", "先核对退款口径([[see:Q1]]):华东含 [[v:Q1.r0.退款笔数]] 笔退款"
|
||
"([[see:Q1]],扣除后仍居首)。"),
|
||
}
|
||
record, issuance = await _record(monkeypatch, shop, plays)
|
||
first, second = record["claims"]
|
||
assert first["rationale"] == "先核对退款口径:华东含 1 笔退款(扣除后仍居首)。"
|
||
assert second["rationale"] == "扣除退款后华南为 900,仍低于华东的 1,200(同口径)。"
|
||
for claim in (first, second):
|
||
doc = claim["rationale_doc"]
|
||
assert doc["markdown"] == claim["rationale"] and doc["violations"] == []
|
||
assert not any(mark in claim["rationale"] for mark in BROKEN)
|
||
# 括号里的依据仍挂在句子上:判「被推翻」的引用到了自己的查询,照常采信、出具降档
|
||
assert second["verdict"] == "refuted" and issuance["tier"] == "degraded"
|
||
|
||
|
||
async def test_a_placeholder_rationale_is_recorded_as_no_rationale(monkeypatch, shop):
|
||
"""反方交回的理由只是占位词:记录里理由为空(审批卡据此写「反方没有给出理由」),判「被推翻」的照常不予采信。"""
|
||
plays = {"华南销售额超过华东": Play([NET], "refuted", "placeholder"),
|
||
"居各区域之首": Play([REFUNDS], "stands", "placeholder")}
|
||
record, issuance = await _record(monkeypatch, shop, plays)
|
||
first, second = record["claims"]
|
||
assert (first["verdict"], first["rationale"], first["rationale_doc"]) == ("stands", "", None)
|
||
assert second["verdict"] == "inconclusive"
|
||
assert second["rationale"] == "理由没有引用到任何查询结果,反方给出的「被推翻」不予采信,记为无法判断。反方没有给出理由"
|
||
assert "placeholder" not in str(record)
|
||
assert issuance["tier"] == "formal"
|