mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 03:01:58 +00:00
K3b:说明写清工具边界不按值换数值格的取舍;LATERAL 的 ON 条件里看得见它自己连的来源
整行引用找列时,在连接的来源本身里(LATERAL)只看得见前面的来源,在 ON 条件里连这个来源自己也看得见(_visible_sources),和 Postgres 的作用域一致。质询的已知局限补上:没设遮罩的列里存成数的号码工具边界不按值换、agent 看得到,要遮就在那个数据源上把那一列也设成遮罩;mask_query_result、模块说明按这一轮的改动重写,长行重新折好。
This commit is contained in:
@@ -49,8 +49,9 @@
|
||||
正文里写出某人的年龄遮不住,只靠 SQL 里的等值比较和按列遮;同一个短的数在 SQL 里被换掉了,别的列上撞上它的阈值、
|
||||
LIMIT 的行数照原样(age = 30 AND visits >= 30)。够长的数在回答正文和回答引用的格子里按值遮,碰巧和某个遮罩值相同的
|
||||
数(访问次数正好等于某一笔金额)也遮掉,这是产品取舍,不按上下文去猜;工具边界不按值换数值格(存下的是证据),交给
|
||||
agent 的、存下的查询快照里这样的数照原样,只在回答和质询工件里遮。占位的写法(未知、暂无……,masking.PLACEHOLDERS)
|
||||
不当遮罩值
|
||||
agent 的、存下的查询快照里这样的数照原样,只在回答和质询工件里遮。反过来,没设遮罩的列里存成数的号码(别的库里的
|
||||
联系方式表把手机号存成整数)工具边界也不按值换,agent 看得到:要遮就在那个数据源上把那一列也设成遮罩。存成文字的照换。
|
||||
占位的写法(未知、暂无……,masking.PLACEHOLDERS)不当遮罩值
|
||||
- 遮罩数值列的 SUM / AVG / MIN / MAX 算派生自遮罩列,整列遮(COUNT 不算,见 _value_columns),CASE 里有一支取的是
|
||||
遮罩列的也算:MIN / MAX 就是某一行的原值,只有一行的分组 SUM / AVG 也是,按列认不出哪些汇总值安全,宁可多遮。
|
||||
核查 agent 的查询在工具边界照这个办法遮,所以这样的指标双盲复算不了(原 SQL 里认得出的,派盲算之前就记为无法
|
||||
|
||||
@@ -28,8 +28,9 @@
|
||||
认它带不带同名的列(_schema_tables),不知道表结构的按带得出算(多遮)。分档写在派生来源里、外层按它分组的(一档
|
||||
一行,_grouped_labels)同当分组键的 CASE 一样照常显示(_shown_labels)
|
||||
- 哪些值(_Secrets):遮罩列里出现过的值,按值认有门槛(SECRET_MIN、SECRET_DIGITS),占位的写法(PLACEHOLDERS:未知、
|
||||
暂无……)不收;换的时候先按词、按开头几个字筛出正文里真有的那几个值,不现编上万个分支的正则;正文、文字格、SQL 的字符串和注释里换了写法的长号码(199-1474-2785、
|
||||
+86 …、全角数字)按纯数字写法在集合里查(loose_spans);已经摆在读者眼前的值免遮,之后并进来的照样免(protected)
|
||||
暂无……)不收;换的时候先按词、按开头几个字筛出正文里真有的那几个值,不现编上万个分支的正则;正文、文字格、SQL 的
|
||||
字符串和注释里换了写法的长号码(199-1474-2785、+86 …、全角数字)按纯数字写法在集合里查(loose_spans);已经摆在
|
||||
读者眼前的值免遮,之后并进来的照样免(protected)
|
||||
- 快照遮好的样子(_masked_view),回答时才认得出、事后要照位置重放的地方(view_edits、replay_edits)
|
||||
- 一次核查里认出的遮罩值(SeenValues):调用方交进来的和 agent 查询时遮掉的分开记,合起来时 agent 查到的在前
|
||||
|
||||
@@ -1263,9 +1264,9 @@ def _visible_sources(select: Any, node: Any) -> list[tuple[str, Any]]:
|
||||
from sqlglot import exp
|
||||
|
||||
sources = _from_sources(select)
|
||||
child = node
|
||||
child, below = node, None
|
||||
while child.parent is not None and child.parent is not select:
|
||||
child = child.parent
|
||||
child, below = child.parent, child
|
||||
if child.parent is not select:
|
||||
return sources
|
||||
if isinstance(child, exp.From):
|
||||
@@ -1273,7 +1274,10 @@ def _visible_sources(select: Any, node: Any) -> list[tuple[str, Any]]:
|
||||
if isinstance(child, exp.Join):
|
||||
joins = list(select.args.get("joins") or [])
|
||||
at = next((i for i, join in enumerate(joins) if join is child), None)
|
||||
return sources[:1 + at] if at is not None else sources
|
||||
if at is None:
|
||||
return sources
|
||||
# 在连接的来源本身里(LATERAL)只看得见前面的;在 ON 条件里连它自己也看得见
|
||||
return sources[:1 + at] if below is child.this else sources[:2 + at]
|
||||
return sources
|
||||
|
||||
|
||||
@@ -2403,8 +2407,9 @@ def mask_query_result(payload: dict[str, Any], masked: Iterable[str], kind: str
|
||||
|
||||
- 整列遮:列名直接对上遮罩列的,加上按 SQL 认出值取自遮罩列的(_derived_hidden:别名、函数、子查询、WITH、
|
||||
SELECT *(展开的列换了名字的也算)、表值函数、整行引用和函数参数里的 *、列名表、TABLE x;COUNT、只在条件里用到、
|
||||
分档当分组键的不算);SQL 解析不了、又写着遮罩列(或者 *、TABLE x)的,整份结果的列都遮。这几列的格子换成
|
||||
「已遮罩」,类型记成文本
|
||||
分档当分组键的不算,分档写在派生来源里、外层按它分组的也不算);认不全的(SQL 解析不了又写着遮罩列、*、TABLE x,
|
||||
(表达式).* 读到遮罩列,表名、SQL 写在字符串里交给函数,分析出意外、超出工作量上限)整份结果的列都遮。这几列的
|
||||
格子换成「已遮罩」,类型记成文本
|
||||
- 别的列按值换,只换文字格:整格就是遮罩值的换掉,文字格里夹着的那一截换掉(换了写法的号码也认,
|
||||
_Secrets.loose_spans),换过的格子记下来(QueryMask.cells)。遮罩值是这份结果里的加上 known:先查号码、再查写着
|
||||
号码的备注、没设遮罩的联系方式表(别的库里的也一样)时,后一份同样遮好。门槛同按值遮(SECRET_DIGITS、SECRET_MIN);
|
||||
|
||||
Reference in New Issue
Block a user