Skip to content

fix(tool): skip redundant use_tool filter for normal users (IKABRE) - #2356

Open
yaojin3616 wants to merge 1 commit into
mainfrom
fix/IKABRE-tool-list-perf
Open

fix(tool): skip redundant use_tool filter for normal users (IKABRE)#2356
yaojin3616 wants to merge 1 commit into
mainfrom
fix/IKABRE-tool-list-perf

Conversation

@yaojin3616

Copy link
Copy Markdown
Collaborator

修复说明 (IKABRE)

普通用户访问 /api/v1/tool?is_preset=0|2(API 工具 / MCP 工具)接口响应缓慢。该接口在拿到粗粒度的 FGA 资源列表(AccessType.GPTS_TOOL_READ)后,又对所有可见工具重新跑了一遍 filter_tool_ids_by_permission_async。这次重过滤在粗筛已经返回相同集合(can_read 关系)时是多余的;其代价是 N 次 FGA batch_check + N 次 DB 查 creator,对持有较多自定义/MCP 工具的普通用户而言,p99 直接落到多秒级。

改动

  • bisheng/permission/domain/tool_permission_template.py — 新增 relation_for_tool_permission_id(permission_id),从模板中反查某个权限 id 对应的 OpenFGA relation,未知 id 返回 None,让调用方安全降级到严格过滤。
  • bisheng/tool/domain/services/tool.pyget_tool_list 在请求的权限 id 映射到 can_read(与 AccessType.GPTS_TOOL_READ 同一关系)时跳过第二次过滤;只有真正需要不同关系的 id(如自定义的 manage_tool_owner)才走严格路径,避免意外放权。[perf] 日志新增 mode=coarse_skip / mode=strict 字段,便于线上确认分支。
  • test/tool/test_tool_service_permissions.py — 替换原 use_tool 过滤断言为:
    • test_get_tool_list_skips_redundant_filter_for_can_read_permissionuse_tool 路径必须 调用 filter_tool_ids_by_permission_async,回归 IKABRE 的核心。
    • test_get_tool_list_still_filters_for_strict_permission — 非 can_read 权限 id 仍走严格过滤,防止过度放权。
    • test_relation_for_tool_permission_id_maps_known_ids — 模板 helper 的真值表。

验证

  • Python AST 检查所有改动文件 → 全部 OK
  • 模板 helper 单测全部用例通过(直接 import + 断言)
  • get_tool_list 快速路径与严格路径的测试通过手工推演(uv sync 受限于磁盘空间无法在本机跑 pytest,但 stub 模式与生产代码走的是同一分支)
  • 未引入新依赖;改动局限在 tool 列表接口,不影响其它模块

关联

  • 关联 issue: dataelement/bisheng#IKABRE(普通用户查看 api工具 mcp工具 接口很慢)

The /api/v1/tool?is_preset=0|2 endpoint re-ran a per-tool permission
filter (filter_tool_ids_by_permission_async) AFTER the coarse
AccessType.GPTS_TOOL_READ FGA list had already returned exactly the
same can_read set. For normal users the redundant call issued N FGA
batch_check + N DB lookups per request, producing the multi-second
latency on the API tools / MCP tools list (IKABRE).

Add relation_for_tool_permission_id(permission_id) so callers can
detect when the requested id maps to the same relation the coarse
list already used. In get_tool_list, skip the per-tool filter on the
can_read fast path; the strict path stays in place for ids that need
a different relation, so we never accidentally over-grant visibility.

mode=coarse_skip / mode=strict in the [perf] log make the branch taken
visible in production logs.

Tests: replace the per-tool filter check with a fast-path assertion
(use_tool must NOT call filter_tool_ids_by_permission_async) and add a
strict-path test for non-can_read ids, plus a unit test for the
template helper.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant