表助手不再把数据源的起草要求当成使用者的原话:交给模型的背景里起草要求标明「不是这次对话里使用者说的话」,系统提示词和 propose_changes 的说明写清 reason 里引用的原话只能是这次对话里使用者的消息,依据来自起草要求时写「起草要求写着:……」

This commit is contained in:
ThearchyHelios
2026-10-14 14:07:15 +08:00
parent 20bef14520
commit eb8d73b6da
2 changed files with 29 additions and 4 deletions
+12 -4
View File
@@ -3,7 +3,11 @@
**为什么要有它。** 模型起草只看表结构,缩写列名、状态码的意思常常拿不准而留空;审阅时人知道答案,却要一项一项填。表助手
把这张表的结构、目录现状(每项的来源和状态)、关联关系、剖析结果、起草要求、使用次数、上次起草留空的列交给模型,让它主动
问拿不准的地方;使用者说出一条业务事实,它整理成成批的修改提案(形状同助手流里的 catalog_patch),使用者在界面上逐项看过、
一次保存(PATCH /catalog/{table}/patch,记为人工确认)。
一次保存(PATCH /catalog/{table}/patch,记为人工确认,每项的 reason 作为依据进这一项的备注)。
**依据只引用这次对话。** 数据源的起草要求是以前写在数据源上的背景,背景里标明「不是这次对话里使用者说的话」;提示词要求
reason 里的原话只引用这次对话里使用者的消息,依据来自起草要求的写「起草要求写着:……」。验收时模型把起草要求写成了
「使用者说:……」,保存之后看起来像是使用者亲口确认过。
**只改目录、不改业务库。** 模型只有两个工具:
- propose_changes:一批修改提案。按 catalog.plan_patch 核对(取值格式、列名必须在表结构里、公式不收),遮罩列不给码值,已经
@@ -123,7 +127,9 @@ ASSISTANT_SYSTEM = """你是 AgentLab 的「表助手」,和使用者一起完
- 拿不准就问,不要猜。一次只问一两件最要紧的事,问得具体(例如「status 为 9 的行是不是作废的单子?」)。目录里留空的列、\
标着「推断」的项是最值得问的。
- 使用者说出一条业务事实时,用 propose_changes 把它整理成修改提案,reason 里引用使用者的原话(例如「使用者说:9 是作废」)。\
一次可以提多项。提案只是建议:使用者在界面上看过、保存之后才写进数据目录,记为人工确认。
reason 里引用使用者原话只能引用这次对话里使用者的消息;依据来自下面背景里的数据源起草要求时写「起草要求写着:……」,\
不要写成「使用者说」。一次可以提多项。提案只是建议:使用者在界面上看过、保存之后才写进数据目录,记为人工确认,\
reason 会作为这一项的依据一起保存。
- 表名、列名照原样写,只能用下面表结构里有的列。
- 标着「已确认」的项由人工确认过,使用者没有明确要改就不要提修改;标着「已驳回」的项使用者驳回过,不要再提。
- 「界面上还没保存的修改」是使用者已经接受、还没保存的提案:不要重复提;要改其中一项就再提一次,写完整的新值。
@@ -162,7 +168,7 @@ ASSISTANT_PROMPT_LABELS = {
"usage": "这张表被 {runs} 次运行用到(查询 {n} 次)。",
"usage_none": "这张表还没有被运行用到过。",
"description": "数据源说明:{text}",
"guidance": "数据源的起草要求(使用者补充的背景和要求):{text}",
"guidance": "数据源的起草要求(不是这次对话里使用者说的话):{text}",
"structure": "表结构:",
"column": "- {name} {type}{marks}",
"pk": "主键",
@@ -238,7 +244,9 @@ PROPOSE_TOOL_PROMPT: dict[str, Any] = {
"properties": {
"path": {"type": "string", "description": "要改的项,写法见系统提示"},
"value": {"description": "新的值:文字、列名列表、码值对照或关联关系"},
"reason": {"type": "string", "description": "一句话依据,引用使用者的原话"},
"reason": {"type": "string",
"description": "一句话依据:引用这次对话里使用者的原话(「使用者说:……」);"
"来自数据源起草要求的写「起草要求写着:……」"},
},
"required": ["path", "value", "reason"],
},
+17
View File
@@ -353,6 +353,23 @@ async def test_background_has_structure_catalog_and_hides_masked_values(client,
assert "没开剖析" not in system
async def test_the_draft_guidance_is_not_what_the_user_said(client, tmp_path, monkeypatch):
"""数据源的起草要求是以前写在数据源上的背景,不是这次对话里使用者说的话:背景里标明白;系统提示词写清 reason 里引用的
原话只能是这次对话里使用者的消息,依据来自起草要求时写「起草要求写着:……」。验收时模型把起草要求写成了
「使用者说:……」,保存之后看起来像是使用者亲口确认过。"""
sid = await _source(client, tmp_path, guidance="pay_type:1=现金,2=刷卡")
model = Scripted([Turn(text=["好。"])])
use(monkeypatch, model)
await _talk(client, sid, _ask("看看还缺什么"))
system = model.seen[0][0].content
assert "数据源的起草要求(不是这次对话里使用者说的话):pay_type:1=现金,2=刷卡" in system
assert "使用者补充的背景和要求" not in system
assert "只能引用这次对话里使用者的消息" in system and "起草要求写着:" in system
reason = (catalog_assistant.PROPOSE_TOOL_PROMPT["function"]["parameters"]["properties"]["changes"]["items"]
["properties"]["reason"]["description"])
assert "这次对话里使用者" in reason and "起草要求写着" in reason
async def test_background_says_how_many_runs_used_the_table(client, tmp_path, monkeypatch):
"""使用次数的口径同审阅队列:被几次运行用到(同「用过这张表的运行」的 total),查询几次(同目录清单的「使用 N 次」)。"""
from app.db.models import Artifact, Run