端点概览
本页面集中列出 AI 服务的 HTTP、SSE、WebSocket 端点,便于快速检索。
管理员访问控制总览
管理员访问控制现在由独立的 Cookie 会话、RBAC 权限校验、敏感操作 challenge 与审计日志共同组成:
super_admin 自动拥有完整后台权限目录。
sub_admin 仅拥有 admin_permission_grants 中激活的权限码。
POST /admin/admin-users 允许创建 sub_admin;只有同时具备 admin_permissions.write 且完成 challenge 的操作者才可在创建时附带初始 grant。
- 管理员
role_code / status 变更仅允许 super_admin 执行。
- 管理员
role_code / status 变更在通过 super_admin 边界后,还要求 challenge,避免仅凭已登录 Cookie 直接提权。
- 管理员不能通过标准资料更新接口修改自己的
role_code / status。
- 当标准更新、删除或密码重置的目标是
super_admin 时,操作者自身也必须是 super_admin。
- 绝大多数控制面 API 现在都要求管理后台登录态,并在服务端继续执行权限校验。
- 当前保留公开访问的控制面例外有
/healthz、/stream、/models、/public/agents、/public/ws/{session_id}、demo job 公共别名 /public/agents/{agent_id}/etl-jobs*、public Fusion runtime /public/agents/{agent_id}/fusion-runtime 与 /public/agents/{agent_id}/fusion-runs*,以及单证识别 runtime/run surface /document-recognition/runtime-agents* 与 /document-recognition/runs*。
/openapi.json、/docs 与 /redoc 现在同样要求管理员登录态,不再匿名暴露。
/release-metadata 已纳入后台权限边界,至少需要 dashboard.read。
- 敏感操作(如管理员删除、权限变更、角色/状态变更、带初始权限的管理员创建、密码重置、系统设置修改)要求先调用 challenge 接口并携带
x-admin-challenge-token。
- 非法系统设置写入会返回
404 或 400,并作为失败事件写入管理员审计日志。
- 管理员 access token 绑定到服务端会话记录;refresh、logout、密码重置都会使旧 access token 立刻失效。
POST /admin/auth/refresh 对单个原始 refresh token 采用单次消费语义;并发重复刷新时只允许一个请求成功。
- 即使操作者拥有
admin_permissions.write,也不能通过权限授予接口给自己追加新权限。
POST /admin/auth/challenges/{challenge_id}/verify 一旦因密码或 nonce 校验失败,会立即烧毁当前 challenge,前端必须重新申请。
- 管理员创建、更新、删除、权限变更、密码重置与系统设置成功写入,会与对应的成功审计一起提交,避免出现业务状态已变更但成功审计缺失的半成功结果。
管理员认证与治理端点
| 方法 |
路径 |
说明 |
| POST |
/admin/auth/login |
管理员登录,签发 HttpOnly access/refresh cookie |
| POST |
/admin/auth/logout |
清理管理员 cookie,并撤销当前 refresh token |
| POST |
/admin/auth/refresh |
轮换 refresh token 并刷新当前后台会话;同一个原始 refresh token 只能成功消费一次 |
| GET |
/admin/auth/me |
获取当前管理员会话快照与有效权限列表 |
| POST |
/admin/auth/challenges |
为敏感操作创建一次性 challenge |
| POST |
/admin/auth/challenges/{challenge_id}/verify |
校验密码重输并签发短时 challenge token |
| GET |
/admin/permission-catalog |
获取可授予的管理员权限目录 |
| GET |
/admin/admin-users |
获取管理员账号列表 |
| POST |
/admin/admin-users |
创建子管理员;若请求包含初始权限,则还要求 admin_permissions.write + challenge |
| GET |
/admin/admin-users/{admin_user_id} |
获取单个管理员详情 |
| PATCH |
/admin/admin-users/{admin_user_id} |
更新管理员资料;角色与状态变更仅限 super_admin,且角色/状态变更本身还要求 challenge |
| DELETE |
/admin/admin-users/{admin_user_id} |
标准路径删除管理员(需 challenge);super_admin 目标只能由 super_admin 标准删除 |
| POST |
/admin/admin-users/{admin_user_id}/break-glass-delete |
break-glass 删除受保护超级管理员(需 challenge + reason) |
| POST |
/admin/admin-users/{admin_user_id}/permissions |
批量授予子管理员权限(需 challenge);禁止给自己追加新权限 |
| DELETE |
/admin/admin-users/{admin_user_id}/permissions/{grant_id} |
撤销单个权限授予(需 challenge) |
| POST |
/admin/admin-users/{admin_user_id}/password-reset |
重置管理员密码并撤销现有会话(需 challenge);super_admin 目标只能由 super_admin 标准重置 |
| GET |
/admin/audit-logs |
查询管理员操作、拒绝访问与认证审计 |
| GET |
/admin/system-settings |
获取数据库托管的后台运行期设置 |
| PATCH |
/admin/system-settings/{config_key} |
修改 DB-backed 后台系统设置(需 challenge) |
补充说明:
- 所有 /admin/auth/* 接口使用 same-origin Cookie,不要求前端自行管理 Bearer token。
- 生产环境必须显式配置 ADMIN_ACCESS_TOKEN_SECRET_KEY,且 ADMIN_ACCESS_COOKIE_SECURE 必须为 true;否则服务启动会失败。
- challenge verify 成功后返回短时 challenge_token,前端应通过 x-admin-challenge-token 请求头传回;如果密码或 nonce 校验失败,当前 challenge 会立刻失效。
- 管理员删除、权限授予/撤销、密码重置与系统设置变更都会写入 admin_action_audits。
- super_admin 不需要单独维护 grant 记录;其权限列表由服务端按目录动态解析。
- 权限授予接口拒绝自我追加权限,这类失败同样会写入管理员审计日志。
核心会话端点
| 方法 |
路径 |
说明 |
| GET |
/healthz |
健康检查 |
| GET |
/release-metadata |
管理后台 About 对话框使用的发布元数据(测试版返回发布时间 + commit,生产版返回 tag 信息) |
| POST |
/stream |
SSE 流式对话,支持 agent_id 与 message_type |
| GET |
/sessions |
会话历史分页列表(支持 agent_id/q/date_from/date_to/limit/cursor;返回 agent_id/agent_name、human_takeover_enabled 与当前 takeover owner 快照,并对历史会话启用 turn 回退) |
| GET |
/sessions/{session_id}/messages |
会话消息历史(人工回复会包含 sender_id_snapshot/sender_name_snapshot) |
| GET |
/sessions/{session_id}/takeover-events |
会话 takeover 审计流 |
| POST |
/sessions/{session_id}/takeover |
管理员接管会话 |
| POST |
/sessions/{session_id}/release |
管理员释放会话,交还 AI |
| POST |
/sessions/{session_id}/manual-messages |
发送人工可见回复(持久化为 role=agent) |
| GET |
/sessions/{session_id}/turns |
会话 Turn 时间线(支持 limit/cursor) |
| GET |
/sessions/{session_id}/turns/{turn_id}/context |
单个 Turn 的上下文观测详情(含 trace 关联审计) |
| POST |
/sessions/{session_id}/turns/{turn_id}/rag-debug |
针对选中 Turn 重新执行一次 RAG 检索调试,返回 mounted sources、raw vector candidates、final chunks、keyword fallback 诊断与结论 |
| GET |
/sessions/{session_id}/turns/{turn_id}/correction |
读取该 AI Turn 的完整纠错草稿 |
| PATCH |
/sessions/{session_id}/turns/{turn_id}/correction |
创建或更新该 AI Turn 的纠错草稿 |
| POST |
/sessions/{session_id}/turns/{turn_id}/correction/publish |
把纠错草稿发布到 Agent 托管纠错知识源 |
| GET |
/models |
模型清单与默认配置(含每个模型的 description 与 category) |
| WS |
/public/ws/{session_id} |
Demo customer 专用公共 WebSocket,会话读写不要求管理员 Cookie |
| WS |
/ws/{session_id} |
WebSocket 会话房间,支持 agent_id,并可通过查询参数传入 role=customer|operator;当 role=operator 且要执行接管/释放/人工回复时必须提供 operator_id,operator_name 可选 |
补充说明:
- 除 /stream 外,本节列出的控制面会话接口都要求管理员登录态;普通读取与写入分别受 conversations.read / conversations.write 权限保护。
- /public/ws/{session_id} 只用于 demo customer 链路;若要观察、接管、释放或发送人工回复,仍必须使用受保护的 /ws/{session_id} 并携带管理员会话。
- GET /sessions/{session_id}/turns/{turn_id}/context 额外要求 mcp.read 与 skills.read,因为响应中包含 MCP / Skill trace 与上下文载荷。
- POST /sessions/{session_id}/turns/{turn_id}/rag-debug 只要求 conversations.read;它复用选中 Turn 的 agent_id 与输入文本默认值,不额外暴露 MCP / Skill trace。
- GET /sessions/{session_id}/turns/{turn_id}/correction 额外要求 knowledge.read;PATCH/POST /sessions/{session_id}/turns/{turn_id}/correction* 额外要求 knowledge.write。
- GET /sessions/{session_id}/turns 与 GET /sessions/{session_id}/turns/{turn_id}/context 里的 turn-level correction 摘要仍只要求会话/trace 读取权限,但如果当前管理员没有 knowledge.read / knowledge.write,响应会自动隐藏 source_id、source_name、document_id、ingestion_job_* 与 last_error_message。
- GET /knowledge-sources/{source_id}/corrections 同时要求 knowledge.read 与 conversations.read,因为该账本会暴露来源会话/turn 的纠错草稿与发布状态。
- POST /sessions/{session_id}/turns/{turn_id}/correction/publish 返回时通常还是 publishing;只有后台 ingestion_job 成功完成后,该纠错才会真正进入检索链路并转为 published。
- 每次 POST /sessions/{session_id}/turns/{turn_id}/correction/publish 只会把“本次候选纠错文档”送入 ingestion;如果较早的 publish 任务晚于较新的 publish 尝试完成,旧任务结果会被当作 stale 结果清理,而不会覆盖最新状态。
- Admin Conversations 页面会基于 GET /sessions/{session_id}/turns 的游标分页结果构建历史导出 CSV。
- Admin Conversations -> RAG 页签现在会先展示该 Turn 已持久化的 RAG provenance,再允许操作者修改 query / threshold / top_k 重新执行一次 retrieval debug,用于回答“为什么没命中这段知识”;若最终命中来自 keyword_fallback,调试结果会显式标出对应模式与匹配词。
- 已建立的 WS /ws/{session_id} 连接会在后续消息与广播发送前重新校验后台会话;logout 或其他服务端会话撤销后,连接会被拒绝继续读写。
- GET /release-metadata 会根据 APP_ENV 区分返回:
- development / staging:优先展示 RELEASE_PUBLISHED_AT、RELEASE_COMMIT_SHA、RELEASE_COMMIT_SUBJECT
- production:优先展示 RELEASE_TAG_NAME、RELEASE_TAG_MESSAGE
- 若 RELEASE_COMMIT_SHA 或 RELEASE_TAG_NAME 未设置,服务端会回退到 LANGFUSE_RELEASE 作为标识兜底。
- POST /sessions/{session_id}/takeover 仅允许当前会话绑定的 chat Agent 且 human_takeover_enabled=true 时接管;当已被他人占用时,可通过 force=true 强制接管。
- POST /sessions/{session_id}/manual-messages 只允许当前 active owner 发送人工回复;回复会写入 messages,但不会创建 conversation_turns / turn_context_snapshots。
- 纠错草稿响应会返回 status、revision_number、manual_reply_message_id、document_id、ingestion_job_id 与 last_error_message,用于把“当前会话已回复”与“知识库已发布”两个动作拆开显示。
- WS /ws/{session_id} 连接后会先推送 history 与 session,后续可能收到 message、system、takeover_event、error。
- Conversations 导出以 input/expected/metadata 三列为基础,并追加 generation_input_tokens、generation_output_tokens、generation_total_tokens 与 generation_usage_source 四列;每一行仍对应一个可评测 Turn。
- 导出范围已不再局限于当前单个 Turn;Admin 可按 Selected Turns、Current Session、Selected Sessions、Filtered Sessions 扩大候选范围,并批量导出多 turn / 多 session 历史样本。
- GET /sessions/{session_id}/turns/{turn_id}/context 仍用于补充每个导出锚点 Turn 的 langfuse_trace_url 等轻量元数据,不会再额外引入上述导出列之外的新列。
- 新产生的 AI turn 会在写库时持久化 generation_usage,统一遵循 provider_reported -> tokenizer_estimated -> no_model_invocation -> unavailable 的解析顺序;如果同一个 turn 的 provider usage 只覆盖了部分模型调用,则整条 turn 会降级成 tokenizer_estimated,不会把 partial provider total 直接落库。GET /sessions/{session_id}/turns 与 GET /sessions/{session_id}/turns/{turn_id}/context 都会直接返回该结构。
- Admin Conversations 页面导出的 CSV 会附带 generation_input_tokens、generation_output_tokens、generation_total_tokens 与 generation_usage_source 四列,便于排查高消耗 turn。
定时任务控制面端点
| 方法 |
路径 |
说明 |
| GET |
/scheduled-tasks |
获取定时任务列表(支持 agent_id/session_id/status/target_mode/schedule_kind/limit 过滤) |
| GET |
/scheduled-tasks/{task_id} |
获取单个定时任务详情 |
| GET |
/scheduled-tasks/{task_id}/runs |
获取单个定时任务的执行历史 |
| POST |
/scheduled-tasks/{task_id}/cancel |
取消一个定时任务(保留历史执行记录) |
补充说明:
- 本节全部端点要求管理员登录态;读取与变更分别受 scheduled_tasks.read / scheduled_tasks.write 控制。
- Conversation 内的定时任务 create/list/cancel 不通过 API 层正则解析,而是由 orchestrator capability pipeline 中的 scheduler stage 识别并短路处理。
- GET /scheduled-tasks 与 GET /scheduled-tasks/{task_id} 会返回规范化后的 schedule_payload、payload、target_mode、conflict_policy 与 next_run_at 等字段,供 Admin Frontend 直接渲染。
- GET /scheduled-tasks/{task_id}/runs 的每条记录都会额外返回派生字段 execution_state 与 heartbeat_stale,便于控制面区分 queued、recovering、running、heartbeat_expired、succeeded、failed、deferred、cancelled。
- GET /scheduled-tasks/{task_id}/runs 还会返回 derived_generation_usage;该值始终从关联的 conversation_turns 读取,不在 scheduled_task_runs 上重复存储 token 列。
- 后台 timer scheduler 只有在 [scheduled_tasks].enabled=true 时才会主动 claim due task 并执行;即使关闭后台执行,已持久化任务与 run history 仍可通过上述 Admin API 查看。
Agent 管理端点
| 方法 |
路径 |
说明 |
| GET |
/public/agents |
Demo 公共 Agent 目录(仅返回匿名公开且 public-safe 的 Agent) |
| POST |
/agents |
创建 Agent |
| GET |
/agents |
获取 Agent 列表 |
| GET |
/agents/{agent_id} |
获取 Agent 详情 |
| GET |
/agents/{agent_id}/cost-overview |
获取 Agent token 使用概览与访问配额状态 |
| PATCH |
/agents/{agent_id} |
更新 Agent |
| DELETE |
/agents/{agent_id} |
删除 Agent |
| GET |
/agents/{agent_id}/public-api-keys |
获取 Fusion Agent API key 元数据列表(不返回明文) |
| POST |
/agents/{agent_id}/public-api-keys |
创建一个新的 Fusion Agent API key(仅创建响应返回一次明文) |
| POST |
/agents/{agent_id}/public-api-keys/{key_id}/revoke |
撤销一个 Fusion Agent API key |
| GET |
/chat-orchestrators |
获取可选聊天编排器列表 |
| POST |
/agents/{agent_id}/mcp-response-preview |
基于 Agent 已挂载 MCP 执行一次真实预览并返回字段目录 |
| GET |
/public/agents/{agent_id}/fusion-runtime |
获取 published Fusion public runtime metadata |
| POST |
/public/agents/{agent_id}/fusion-runs |
通过 public Fusion runtime 创建 run |
| GET |
/public/agents/{agent_id}/fusion-runs |
列出 public Fusion run |
| GET |
/public/agents/{agent_id}/fusion-runs/{run_id} |
获取单个 public Fusion run |
| GET |
/public/agents/{agent_id}/fusion-runs/{run_id}/inputs/{input_id}/download |
下载 public Fusion run 的输入文件 |
约束说明:
- GET /public/agents 供 demo-backend / demo-frontend 使用,不要求管理员登录态。
- /public/agents/{agent_id}/fusion-* 不要求管理员登录态;public_api_key 模式要求调用方携带有效 x-agent-api-key。
- /agents* 控制面端点,包括 Fusion Agent API key 的 list/create/revoke,仍要求管理员登录态;读取、写入与删除分别受 agents.read、agents.write、agents.delete 控制。
- public_access_mode 当前支持 admin_only、public_anonymous、public_api_key。
- 只有 fusion Agent 允许 public_access_mode=public_api_key;非 Fusion Agent 提交该模式会返回 422。
- GET /public/agents 只返回 status=active 且 public_access_mode=public_anonymous 的 Agent,并使用 public-safe catalog model,不返回 prompt、live Fusion draft、治理配置等控制面字段。
- GET/POST /public/agents/{agent_id}/fusion-* 始终基于当前 published_agent_version_id 指向的 immutable snapshot,不允许 public 调用方执行任意历史 version。
- 当 public_access_mode=public_api_key 时,public Fusion route 必须携带 x-agent-api-key;缺失或无效都会返回 401。
- Fusion Agent API key 采用 hash-only 持久化;创建接口只在成功响应里回传一次明文,后续 list/revoke 只返回 prefix 与元数据。
- 现有 /public/agents/{agent_id}/etl-jobs* 仅对 public_access_mode=public_anonymous 的 ETL Agent 生效;admin_only 与 public_api_key 都不会匿名开放 ETL public alias。
- system_prompt 最大长度由 config.toml 的 [agent].system_prompt_max_length 或环境变量 AGENT_SYSTEM_PROMPT_MAX_LENGTH 控制,默认 30000 字符。
- judge_prompt 最大长度由 config.toml 的 [agent].judge_prompt_max_length 或环境变量 AGENT_JUDGE_PROMPT_MAX_LENGTH 控制,默认 30000 字符;留空表示使用服务端内置的默认 Judge prompt。
- agent_type 是粗粒度能力边界,当前区分 chat、etl、document_extraction;不要用它表达聊天运行时版本。
- orchestrator_key 仅对 chat Agent 生效;未显式提供时,服务端会默认写入当前默认聊天运行时 chameleon_chat_v1。
- 非 chat Agent 若提交 orchestrator_key 会返回 422。
- 仅 chat Agent 支持以下运行时用量限制字段:
- max_concurrent_requests:限制同一 Agent 同时处于执行中的 /stream chat 请求数
- max_total_requests:限制同一 Agent 已持久化到 conversation_turns 的累计 chat turn 数
- max_requests_per_day:限制同一 Agent 在当前 UTC 日内已持久化的 chat turn 数
- max_total_tokens_daily:限制同一 Agent 在当前 UTC 日内已持久化 chat turn 的累计 total_tokens
- max_total_tokens_monthly:限制同一 Agent 在当前 UTC 月内已持久化 chat turn 的累计 total_tokens
- max_cost_usd_daily:限制同一 Agent 在当前 UTC 日内按模型单价估算的累计 chat 成本(USD)
- max_cost_usd_monthly:限制同一 Agent 在当前 UTC 月内按模型单价估算的累计 chat 成本(USD)
- max_tool_calls_total_per_request:限制单次 chat 请求内 Skill + MCP 的总执行次数
- GET /agents/{agent_id}/cost-overview 会返回:
- conversation_usage_rollup
- evaluation_generation_usage_rollup
- evaluation_judge_usage_rollup
- conversation_estimated_cost
- evaluation_generation_estimated_cost
- evaluation_judge_estimated_cost
- combined_estimated_cost
- active_request_count
- total_request_count
- remaining_total_requests
- 上述 *_estimated_cost 都基于 model config 中维护的 input_price_per_million_tokens / output_price_per_million_tokens 估算,单位为 USD;仅用于内部观测,实际账单以模型供应商结算为准。
- 当 chat Agent 达到上述任一请求数 / token / 成本限制时,POST /stream 通常会在执行前直接返回 SSE error 事件,不会继续进入普通固定响应、MCP quick-match 或 LLM 编排流程。
- 例外:若当前请求的 message_type 命中该 Agent 的 message_type_response_config.{rule|form|other} 固定响应,ai-service 会优先返回对应 fixed response,不会先触发 Request Limit 拦截或 limit_reached_message。
- 当 chat Agent 配置 max_tool_calls_total_per_request 时,Skill 与 MCP 的总执行次数会在编排阶段被统一计数;超过上限后,后续工具执行会被标记为 blocked。
- 仅 chat Agent 支持可选 model_routing_config 结构化字段,用于保存角色化模型路由策略:
- 顶层字段:enabled、policy_version、collapse_to_explicit_override、fallback_to_primary_model
- 角色槽位:tool_call_model、general_model、complex_task_model、reasoning_model
- 每个槽位保存 model_name、model_provider、可选 model_temperature
- model_routing_config 的空槽位会继续回退到 Agent 现有的主模型三元组 model_name/model_provider/model_temperature。
- 仅 chat Agent 支持 human_takeover_enabled 布尔开关;非 chat Agent 提交该字段为 true 会返回 422。
- 仅 chat Agent 支持 hide_rag_source_filename 布尔开关;非 chat Agent 提交该字段为 true 会返回 422。该开关只影响注入给模型的 RAG 上下文文本,不影响追踪与审计负载中的原始文件名。
- 当 POST /stream、WS /ws/{session_id} 或 POST /agents/{agent_id}/evaluation-runs 显式携带 model_name / model_provider / model_temperature 时,本次执行会折叠为单模型运行,不会按角色路由不同模型。若本次 /stream 或 WebSocket 请求先命中 Agent 的 message-type fixed response,则不会应用该模型覆盖到会话状态。
- 仅 chat Agent 支持可选 message_type_response_config 结构化字段,用于按 rule/form/other 配置固定响应文案。
- 仅 chat Agent 支持可选 mcp_response_config 结构化字段,用于配置 Agent 级 MCP direct-response、quick-match 与 intent-gate 控制面。
- 仅 chat Agent 支持可选 response_grounding_config 结构化字段,用于约束最终回复阶段的防幻觉策略。
- response_grounding_config 当前字段包括:enabled、policy_version、mode、allow_general_knowledge、low_confidence_behavior、structured_output_failure_behavior。
- response_grounding_config.mode 当前支持 balanced 与 strict;strict 会在存在 RAG / Skill / MCP 嵌入上下文时,更保守地拒绝未显式基于这些上下文的最终回答。
- 查询前门禁关键词匹配的主入口是 Agent settings 中的 mcp_response_config.intent_gate_rules[],不是全局 ai_service/utils/settings.py。
- message_type_response_config 中每个 message_type 条目同时支持默认兜底 enabled + response_text,以及 message_key_responses[] 明细映射。
- mcp_response_config.direct_response_rules[] 绑定 mcp_server_id + tool_name,支持 raw_json、json_subset、text 三种输出模式。
- mcp_response_config.direct_response_rules[].wrap_json_code_block 可选;开启后,JSON 类输出会包成 Markdown ```json fenced block。
- mcp_response_config.quick_match_rules[] 支持前缀短路,例如 #get_tracking123556,可通过 suffix_parameter_name 把后缀文本映射到 MCP 工具参数。
- mcp_response_config.quick_match_rules[].response_rule_key 若配置,则会复用同一 Agent 内的 direct-response rule;若不配置,则 quick-match 默认返回 raw JSON。
- mcp_response_config.intent_gate_rules[] 的 tool_capability 允许任意非空字符串;当前只有 tracking 拥有内建运行时特化,其它 capability 作为管理员自定义挂载门禁标签使用。
- 对自定义 capability,运行时使用该 rule 的 keywords[] / regex_patterns[] 匹配当前用户消息;没有启用对应 rule 时,挂载保持旧行为,不额外拦截。
- 当 Agent 没有启用 tracking 的 intent_gate_rules[] 时,运行时会继续回退到内置默认 matcher,保持旧 Agent 行为不变。
- message_key_responses[].message_key 采用去首尾空格、大小写不敏感的精确匹配;同一 message_type 下归一化后不得重复。
- message_key_responses[] 中的 message_key 与 response_text 都必须为非空字符串;若默认兜底 enabled=true,则仍必须提供非空 response_text。
- 当 POST /stream 携带 agent_id 且当前 message_type 命中该 Agent 的固定响应配置时,ai-service 会先尝试 message_key_responses[],未命中时再回退到默认兜底文案,并继续沿用现有 SSE token / done 事件格式;该短路路径不会触发 orchestrator/LLM,也不会更新会话模型覆盖配置。WebSocket chat session 使用同一匹配语义:客户端可继续用 [message_type=form]\n... 这类 tagged content 表达非 user_chat 类型,服务端会在进入 orchestrator 前解析 tag、剥离正文用于 key 匹配,并在命中后广播正常 assistant message。
- 命中 message_type_response_config.{rule|form|other} 的 fixed response 会继续写入 messages、conversation_turns 与 turn_context_snapshots,但该 turn 不计入 Request Limit 统计,因此不会消耗 max_total_requests、max_requests_per_day 或 per-user request limit 配额。
- 当 POST /stream 携带 agent_id、message_type=user_chat 且命中该 Agent 的 mcp_response_config.quick_match_rules[] 时,ai-service 会在 API 短路层直接调用一次已挂载 MCP 工具,并返回 direct-response 格式化结果或 raw JSON;该快路径不会进入 orchestrator / 最终 LLM。
- model_routing_config 会随 Agent 版本快照一起持久化,并在回滚时恢复。
- mcp_response_config 会随 Agent 版本快照一起持久化,并在回滚时恢复。
- response_grounding_config 会随 Agent 版本快照一起持久化,并在回滚时恢复。
- judge_prompt 会随 Agent 版本快照一起持久化,并在回滚时恢复;响应中的 judge_prompt_version 为根据当前保存的 prompt 文本派生出的只读版本号。
知识源管理端点
| 方法 |
路径 |
说明 |
| POST |
/knowledge-sources |
创建知识源 |
| GET |
/knowledge-sources |
获取知识源列表 |
| GET |
/knowledge-sources/{source_id} |
获取知识源详情 |
| PATCH |
/knowledge-sources/{source_id} |
更新知识源 |
补充说明:
- 本节全部端点要求管理员登录态;读取与写入分别受 knowledge.read / knowledge.write 控制。
Agent 知识挂载端点
| 方法 |
路径 |
说明 |
| POST |
/agents/{agent_id}/mounts |
挂载知识源到 Agent |
| GET |
/agents/{agent_id}/mounts |
获取 Agent 挂载列表 |
| DELETE |
/agents/{agent_id}/mounts/{mount_id} |
解除知识源挂载 |
补充说明:
- 本节端点要求管理员登录态,并沿用 knowledge.write 权限保护。
- mount_id 是知识库挂载删除的规范参数;兼容期内服务端仍会在未命中挂载主键时回退按 (agent_id, source_id) 删除,供旧调用方过渡。
- managed_correction 知识源只能由会话纠错发布流程自动挂载到其 owning agent;通用 POST /agents/{agent_id}/mounts 与 DELETE /agents/{agent_id}/mounts/{source_id} 不允许手工挂载、跨 Agent 挂载或卸载这类来源。
评测数据集端点
| 方法 |
路径 |
说明 |
| POST |
/evaluation-datasets |
创建评测数据集 |
| GET |
/evaluation-datasets |
获取评测数据集列表 |
| GET |
/evaluation-datasets/{dataset_id} |
获取评测数据集详情 |
| DELETE |
/evaluation-datasets/{dataset_id} |
删除评测数据集(若存在 run 引用或子快照则拒绝) |
| POST |
/evaluation-datasets/{dataset_id}/import |
上传 CSV 并覆盖导入数据集样本 |
| POST |
/evaluation-datasets/{dataset_id}/document-recognition-runs/import |
将已 reviewed 的 document-recognition runs 提升为评测样本 |
| POST |
/evaluation-datasets/{dataset_id}/freeze |
冻结数据集并创建不可变快照版本 |
| GET |
/evaluation-datasets/{dataset_id}/source-csv |
下载当前数据集持久化的源 CSV |
| GET |
/evaluation-datasets/{dataset_id}/items |
分页获取数据集样本 |
| GET |
/evaluation-datasets/{dataset_id}/runs |
获取该数据集的最近评测 Run 列表 |
删除冲突补充:
- 本节全部端点要求管理员登录态;读取与写入分别受 evaluation.read / evaluation.write 控制。
- 当 DELETE /evaluation-datasets/{dataset_id} 因评测 Run 引用返回 409 时,detail 会返回结构化对象,包含 code=DATASET_REFERENCED_BY_EVALUATION_RUNS、evaluation_run_count 与 referencing_agents(含 agent_id/agent_name/run_count/last_run_at)。
- GET /evaluation-datasets/{dataset_id}/runs 会先按 dataset_id 过滤,再按 created_at desc 排序并应用 limit,适合 Dataset Detail 的 Recent Runs 面板,避免从 capped per-agent history 二次过滤导致静默漏数。
- POST /evaluation-datasets/{dataset_id}/import 现在会同时持久化当前原始 CSV 文件;GET /evaluation-datasets* 响应会额外返回 source_csv_filename、source_csv_content_type、source_csv_size_bytes、source_csv_uploaded_at、source_csv_download_url、source_csv_download_mode 与 source_csv_download_warning。
- POST /evaluation-datasets/{dataset_id}/document-recognition-runs/import 只接受 task_type=document_recognition 且未冻结的数据集,请求体为 {"run_id_list":["..."]}。每个 run 必须已完成 reviewed 状态,且同一 source_run_id 不能重复加入同一数据集;服务端会复制源文档并持久化 reviewed field truth、page/bbox 诊断与 source lineage。
- POST /evaluation-datasets/{dataset_id}/freeze 会把当前源 CSV 一起复制到冻结快照;若数据集已经有 items 但缺少持久化源 CSV,接口会返回 400,避免生成不可复现的快照。
- task_type=document_recognition 的 freeze 会复制 item 级源文档到 snapshot-local object key;这类数据集没有 source CSV,前端应使用 reviewed-run promotion 作为主入口。
- GET /evaluation-datasets/{dataset_id}/source-csv 会返回附件下载;当对象存储公网下载不可用时,前端可以无缝回退到同域 API 代理。
Agent 测评运行端点
| 方法 |
路径 |
说明 |
| POST |
/agents/{agent_id}/evaluation-runs |
创建并触发异步测评 Run(仅允许冻结数据集快照) |
| GET |
/agents/{agent_id}/evaluation-runs |
获取 Agent 测评 Run 列表 |
| GET |
/agents/{agent_id}/evaluation-runs/{run_id} |
获取单个 Run 概要 |
| GET |
/agents/{agent_id}/evaluation-runs/{run_id}/results |
分页获取 Run 样本级结果 |
| GET |
/agents/{agent_id}/evaluation-runs/{run_id}/results.csv |
导出 Run 样本级结果 CSV |
| POST |
/agents/{agent_id}/evaluation-runs/{run_id}/evaluate-gate |
评估并持久化 Run 质量门禁结论 |
| GET |
/agents/{agent_id}/evaluation-runs/{run_id}/slices |
按 domain/difficulty/source 查看分片聚合指标 |
补充说明:
- 本节全部端点要求管理员登录态;读取与写入分别受 evaluation.read / evaluation.write 控制。
- POST /agents/{agent_id}/evaluation-runs 会创建 queued Run,并记录本次执行的 Agent 模型快照与 Judge runtime 快照;同时会冻结当时的 Judge prompt 文本和 judge_prompt_version。实际执行由后台 dispatcher 从数据库队列领取。
- 如果 Agent 的 judge_prompt 留空,Run 创建时也会把当时生效的内置默认 Judge prompt 文本展开后落库,而不是只存 None,避免排队中的历史 Run 被后续默认 prompt 变更污染。
- 当评测请求未显式提供 model_* 覆盖时,Run 会同时快照 Agent 当前的 model_routing_config;若显式提供 model_*,则本次评测折叠为单模型运行,Run 的 model_routing_config 保持为空。
- API 启动时会自动启动后台 evaluation supervisor;supervisor 会尽力立即执行一次 stale recovery,但即使首次巡检瞬时失败也会继续保活后台 loop,并以固定周期保活 dispatcher / 回退心跳超时的 running Run。
- runner 在单个 evaluation item 执行期间也会持续刷新 worker_heartbeat_at,因此慢样本不会仅因长时间未完成单条执行而被 supervisor 误判为 stale run。
- evaluation 复用统一的 timeouts.model_request_seconds 出站 LLM 超时;若单条样本中的模型或 Judge 请求卡住,该样本会在超时后失败,而不是依赖 stale-heartbeat recovery。
- 部分 Evaluation 读取接口仍会以节流方式补做一次 stale-run recovery,因此管理台持续轮询时,心跳超时的 running Run 不需要等服务重启才会恢复重试;前端轮询本身只负责刷新展示,不直接调度后台 worker。
- GET /agents/{agent_id}/evaluation-runs 与 GET /agents/{agent_id}/evaluation-runs/{run_id} 的响应会额外返回派生字段 execution_state 与 heartbeat_stale,便于前端直接区分 queued、recovering、running、heartbeat_expired、completed、failed。
- GET /agents/{agent_id}/evaluation-runs 与 GET /agents/{agent_id}/evaluation-runs/{run_id} 都会返回 started_at 和 completed_at;其中 completed_at 是 dataset evaluation run 的规范结束时间字段。
- completed_at 只用于表达 Run 终态时间:completed / failed Run 应尽量返回非空值,queued / running Run 必须保持为空;不要新增或依赖 ended_at、finished_at 等同义字段。
- worker_heartbeat_at 仅表示 worker 活跃度,不可当作 Run 的结束时间。
- GET /agents/{agent_id}/evaluation-runs 与 GET /agents/{agent_id}/evaluation-runs/{run_id} 现在还会返回:
- generation_usage_rollup
- judge_usage_rollup
- combined_total_tokens
其中 rollup 同时包含总量和 provider_reported/tokenizer_estimated/no_model_invocation/unavailable 四类来源计数。
- GET /agents/{agent_id}/evaluation-runs/{run_id}/results 支持 offset / limit 分页,rule_score 为强类型结构:
- exact_match
- token_f1
- pass_rate
- matched_expected_answer_index
- GET /agents/{agent_id}/evaluation-runs/{run_id}/results 的每条样本还会返回 generation_usage 与 judge_usage,成功和失败样本都遵循同一写时 fallback 规则。
- GET /agents/{agent_id}/evaluation-runs/{run_id}/results.csv 会以流式响应导出该 Run 当前所有已落库样本结果,返回 UTF-8 CSV 下载文件;主要列包含输入/期望/预测文本、原始 JSON、规则评分、Judge 评分细项、延迟、错误信息与时间戳。
- CSV 额外包含 generation_* 与 judge_* 两组 token 列,以及对应的 *_usage_source,供离线排查异常样本或高消耗样本。
- 为降低 Excel / Sheets 打开 CSV 时的公式注入风险,所有以 =, +, -, @ 开头的文本单元格都会在导出时自动加前缀转义。
- 同一结果里的 judge_score 也为强类型结构:
- score
- reason
- issues
- improvement_suggestions
- suggested_better_answer
- confidence
- rubric_version
- raw_response_text
- POST /agents/{agent_id}/evaluation-runs/{run_id}/evaluate-gate 允许提交 policy override:minimum_items、score_pass_rate_min、score_f1_min、max_failed_item_ratio、llm_judge_min。
- 评测运行会沿用 Agent 当前的 orchestrator_key,因此同一数据集可以用于比较不同聊天运行时。
- GET /agents/{agent_id}/evaluation-runs 与 GET /agents/{agent_id}/evaluation-runs/{run_id} 的响应都会返回 model_routing_config,便于控制面回显本次运行的角色路由策略快照。
- 建议将 langgraph_react_agent_v1 这类实验运行时保持为非默认值,直到其评测切片和质量门禁结果达到预期阈值。
- 运行时级汇总推荐通过 ai_service.services.evaluation.runner.summarize_runtime_evaluation_slices(...) 聚合同一 runtime 的门禁通过率与平均指标。
Agent 文件作业端点
| 方法 |
路径 |
说明 |
| POST |
/agents/{agent_id}/etl-jobs |
上传 source CSV 与 target schema CSV,并创建 ETL Job |
| GET |
/agents/{agent_id}/etl-jobs |
获取 ETL Job 列表 |
| GET |
/agents/{agent_id}/etl-jobs/{job_id} |
获取 ETL Job 详情(含 source/target/output 下载元数据) |
| GET |
/agents/{agent_id}/etl-jobs/{job_id}/source-csv |
通过同域 API 代理下载 ETL source CSV |
| GET |
/agents/{agent_id}/etl-jobs/{job_id}/target-schema-csv |
通过同域 API 代理下载 ETL target schema CSV |
| GET |
/agents/{agent_id}/etl-jobs/{job_id}/download |
通过同域 API 代理下载 ETL output CSV |
| DELETE |
/agents/{agent_id}/etl-jobs/{job_id} |
删除 ETL Job |
| GET |
/document-recognition/runtime-agents |
获取已注册的单证识别 runtime agent 列表 |
| GET |
/document-recognition/runtime-agents/{runtime_agent_id} |
获取单个 runtime agent 的 published 版本、上传槽位解析与执行策略摘要 |
| POST |
/document-recognition/runs |
通过 canonical document-recognition 入口上传文件并创建 run |
| GET |
/document-recognition/runs |
获取单证识别 run 投影列表 |
| GET |
/document-recognition/runs/{run_id} |
获取单个单证识别 run 详情(含 source/result 下载元数据、字段回顾 summary 与 workspace_output) |
| PATCH |
/document-recognition/runs/{run_id}/field-reviews/{field_id} |
更新字段级人工回顾结果;有效变更会追加 append-only revision ledger |
| GET |
/document-recognition/runs/{run_id}/field-reviews/{field_id}/revisions |
按需读取单字段 revision timeline,返回 baseline 快照与 ledger |
| GET |
/document-recognition/runs/{run_id}/source-document |
通过同域 API 代理下载 source document |
| GET |
/document-recognition/runs/{run_id}/source-pdf |
通过同域 API 代理下载 PDF source |
| GET |
/document-recognition/runs/{run_id}/result |
通过同域 API 代理下载 structured result JSON |
补充说明:
- Demo 公开别名保持与受保护作业接口同形:/public/agents/{agent_id}/etl-jobs* 复用相同的创建、查询、下载与删除能力,供 demo-backend / demo-frontend 使用。
- ETL job 端点要求管理员登录态;读取与写入分别受 jobs.read / jobs.write 控制。
- /document-recognition/runtime-agents* 与 /document-recognition/runs* canonical routes 当前直接公开提供,不再维护额外的前缀别名。
- 管理端 /admin/document-recognition/runtime-agents/{agent_id} registry 写入要求 document_recognition.write 并写入审计,不要求 x-admin-challenge-token。
- GET /document-recognition/runs/{run_id} 中每个 field_reviews[] 只返回轻量 revision summary:revision_count、is_changed_from_extracted、last_revised_at、last_revised_by。
- PATCH /document-recognition/runs/{run_id}/field-reviews/{field_id} 请求体允许附带可选 reviewer_identity,服务端仅把它当展示型快照写入 revision ledger 与 run projection。
- GET /document-recognition/runs/{run_id}/field-reviews/{field_id}/revisions 会对没有 ledger 的旧 run 返回 history_status=unrecorded,同时保留 baseline 字段快照,避免前端出现空白或报错。
- ETL Job 响应会返回三组下载元数据:download_url/download_mode/download_warning(output CSV)、source_download_url/source_download_mode/source_download_warning(source CSV)、target_schema_download_url/target_schema_download_mode/target_schema_download_warning(target schema CSV)。
- 单证识别 run 响应会返回 Fusion runtime snapshot 字段(如 runtime_agent_id、runtime_agent_version_id、runtime_binding_snapshot)、字段回顾投影、canonical workspace_output、issue 列表,以及 source/result 下载元数据。
- 所有对象存储文件下载都遵循同一模式:优先暴露公网可下载 URL;若 MINIO_PUBLIC_ENDPOINT 未配置或 presign 失败,则自动回退到同域 API 代理,并通过 *_download_mode=minio_proxy 与 *_download_warning 告知客户端。
MCP Server 管理端点
| 方法 |
路径 |
说明 |
| POST |
/mcp-servers |
创建 MCP Server |
| GET |
/mcp-servers |
获取 MCP Server 列表 |
| GET |
/mcp-servers/{mcp_server_id} |
获取 MCP Server 详情 |
| PATCH |
/mcp-servers/{mcp_server_id} |
更新 MCP Server |
| DELETE |
/mcp-servers/{mcp_server_id} |
删除 MCP Server |
| POST |
/mcp-servers/{mcp_server_id}/health-check |
运行连接健康检查 |
| POST |
/mcp-servers/{mcp_server_id}/test-call |
在控制面直接测试 tools/list 或 tools/call |
约束说明:
- 本节全部端点要求管理员登录态;读取与写入分别受 mcp.read / mcp.write 控制。
- stdio 必填 connection_config.command
- http_sse 必填 connection_config.url
- http_sse 可选 import_mode=url 以导入 GET/POST URL 为单工具
- test-call 请求体字段:
- action:tools/list 或 tools/call
- tools/call 场景必填 tool_name
- 可选 arguments、credential_id、timeout_ms
MCP 凭据管理端点
| 方法 |
路径 |
说明 |
| POST |
/mcp-credentials |
创建加密 MCP 凭据 |
| GET |
/mcp-credentials |
获取 MCP 凭据列表 |
| GET |
/mcp-credentials/{credential_id} |
获取 MCP 凭据详情(不返回明文) |
| PATCH |
/mcp-credentials/{credential_id} |
更新 MCP 凭据元数据 |
| DELETE |
/mcp-credentials/{credential_id} |
删除 MCP 凭据 |
| POST |
/mcp-credentials/{credential_id}/rotate |
轮换 MCP 凭据密文 |
补充说明:
- 本节端点要求管理员登录态,并沿用 mcp.write 权限保护。
Agent MCP 挂载端点
| 方法 |
路径 |
说明 |
| POST |
/agents/{agent_id}/mcp-mounts |
挂载 MCP Server 到 Agent |
| GET |
/agents/{agent_id}/mcp-mounts |
获取 Agent MCP 挂载列表 |
| PATCH |
/agents/{agent_id}/mcp-mounts/{mount_id} |
更新 MCP 挂载策略 |
| DELETE |
/agents/{agent_id}/mcp-mounts/{mount_id} |
解除 MCP 挂载 |
补充说明:
- 本节端点要求管理员登录态;读取与写入分别受 mcp.read / mcp.write 控制。
- POST /agents/{agent_id}/mcp-response-preview 仅对 chat Agent 生效。
- 预览请求体包含 mcp_server_id、tool_name、arguments。
- 预览响应返回 status、latency_ms、raw_response_payload、business_response_payload、field_catalog[]、error_message。
- MCP mount create / patch 请求现在支持可选 tool_capability 字段;服务端会做去空格、小写归一化。
- 挂载响应会返回 tool_capability,供管理员界面展示当前 capability 标签。
MCP 调用审计端点
| 方法 |
路径 |
说明 |
| GET |
/sessions/{session_id}/mcp-calls |
按会话查询 MCP 调用审计 |
| GET |
/agents/{agent_id}/mcp-calls |
按 Agent 查询 MCP 调用审计 |
补充说明:
- 本节端点要求管理员登录态,并沿用 mcp.read 权限保护。
Skill 资产管理端点
| 方法 |
路径 |
说明 |
| POST |
/skills |
创建 Skill 资产 |
| GET |
/skills |
获取 Skill 资产列表(支持 status 过滤) |
| GET |
/skills/{skill_id} |
获取 Skill 资产详情 |
| PATCH |
/skills/{skill_id} |
更新 Skill 资产 |
Skill 版本端点
| 方法 |
路径 |
说明 |
| POST |
/skills/{skill_id}/versions |
创建 SkillVersion(默认 draft) |
| GET |
/skills/{skill_id}/versions |
获取 SkillVersion 列表(支持 released_only) |
| PATCH |
/skills/{skill_id}/versions/{version_id} |
更新草稿版本 |
| POST |
/skills/{skill_id}/versions/{version_id}/release |
发布版本(不可变) |
Agent Skill 挂载端点
| 方法 |
路径 |
说明 |
| POST |
/agents/{agent_id}/skill-mounts |
挂载已发布 SkillVersion |
| GET |
/agents/{agent_id}/skill-mounts |
获取 Agent Skill 挂载列表 |
| PATCH |
/agents/{agent_id}/skill-mounts/{mount_id} |
更新 Skill 挂载策略 |
| DELETE |
/agents/{agent_id}/skill-mounts/{mount_id} |
解除 Skill 挂载 |
Skill 调用审计端点
| 方法 |
路径 |
说明 |
| GET |
/sessions/{session_id}/skill-calls |
按会话查询 Skill 执行审计 |
| GET |
/agents/{agent_id}/skill-calls |
按 Agent 查询 Skill 执行审计 |
文档与摄取端点
| 方法 |
路径 |
说明 |
| POST |
/knowledge-sources/{source_id}/documents |
上传文档 |
| GET |
/knowledge-sources/{source_id}/documents |
获取文档列表 |
| GET |
/knowledge-sources/{source_id}/documents/{document_id} |
获取文档详情 |
| GET |
/knowledge-sources/{source_id}/documents/{document_id}/download |
通过同域 API 代理下载原始文档 |
| DELETE |
/knowledge-sources/{source_id}/documents/{document_id} |
删除文档 |
| GET |
/knowledge-sources/{source_id}/corrections |
获取该知识源下的纠错发布台账 |
| POST |
/embedding-model/check-readiness |
检查并预热 Embedding 模型(返回 backend_type/provider/model/dim/错误信息) |
| POST |
/knowledge-sources/{source_id}/ingest |
触发摄取任务 |
| GET |
/knowledge-sources/{source_id}/ingestion-jobs |
列出摄取任务 |
| GET |
/ingestion-jobs/{job_id} |
获取摄取任务状态 |
| POST |
/knowledge-sources/{source_id}/inspect-runs |
创建并启动一次手动 Inspect Run |
| GET |
/knowledge-sources/{source_id}/inspect-runs |
获取知识源下的 Inspect Run 历史 |
| GET |
/knowledge-sources/{source_id}/inspect-runs/{run_id} |
获取单次 Inspect Run 摘要与文档级结果 |
| POST |
/knowledge-sources/{source_id}/documents/{document_id}/rebuild-from-snapshot |
基于 parse snapshot 直接重建单个文档的 chunk/vector |
文档详情与列表响应会同时返回两类状态字段:
status / processing_status:文档处理链路状态(uploaded / processing / indexed / failed)
vector_status:检索向量健康状态(pending_verification / indexed / reindex_required / verification_failed);当处理链路已经 failed 时,这个字段不会再表示“等待中”,而会保留一个终态
expected_point_count、actual_point_count、vector_verified_at:用于前端直接展示 Retrieval 健康度与最近一次核验结果
- 文档列表与详情响应还会返回
download_url、download_mode 与 download_warning,用于暴露原始文档下载入口。
KnowledgeSourceResponse 现在包含 source_kind 与 managed_for_agent_id,用于区分普通上传知识源和系统托管纠错知识源。
- 由会话纠错自动生成的文档会在
metadata_json 中写入 knowledge_correction_id、source_turn_id、source_session_id 与 document_origin="managed_correction"。
- 当
source_kind="managed_correction" 时,通用 PATCH /knowledge-sources/{source_id}、POST /knowledge-sources/{source_id}/documents、DELETE /knowledge-sources/{source_id}/documents/{document_id} 与 POST /knowledge-sources/{source_id}/ingest 会拒绝手工修改;这类来源只能通过 Conversations 纠错发布流程更新。
GET /knowledge-sources/{source_id}/documents/{document_id}/download 会保留原始 filename 与 content_type,并在公网对象下载不可用时作为同域代理兜底。
POST /embedding-model/check-readiness 属于预热型写操作,要求 knowledge.write;GET /ingestion-jobs/{job_id} 属于摄取状态读取,要求 knowledge.read。
POST /knowledge-sources/{source_id}/inspect-runs 同样要求 knowledge.write;GET /knowledge-sources/{source_id}/inspect-runs* 属于 Inspect 历史/结果读取,要求 knowledge.read。
POST /knowledge-sources/{source_id}/documents/{document_id}/rebuild-from-snapshot 也要求 knowledge.write;请求体可选 chunking_strategy / chunking_params 覆盖,用于把 chunking_preview 的候选策略直接应用到当前文档。
vector_health 模式会复用 live 向量核验逻辑,并允许回写 documents.vector_status、point 计数与 vector_verified_at;当 document_ids[] 为空时,它只检查当前 source 下 status = indexed 的文档,不代表 uploaded / failed 文档也被覆盖。若 run 被 scoped 到尚未 indexed 的文档,结果会保留该文档并给出 run_ingestion 建议,而不是静默跳过。chunking_preview 模式只读取 document_parse_snapshots,不会写入 document_chunks、Qdrant points 或 live hypothetical 字段。
chunking_preview 请求体要求 inspection_mode=chunking_preview 且提供 candidate_chunking_strategy;可选的 document_ids[] 可把 Inspect 缩小到一个 knowledge source 内的局部文档。
- 当 Inspect 结果返回
rebuild_from_snapshot recommendation 时,管理台现在会在结果表格里直接渲染 Rebuild From Snapshot 操作按钮,而不是只留下脚本级建议。
- Inspect 结果会保留
document_filename 等审计快照;如果源文档之后被删除,results[].document_id 可能为 null,但历史 run/result 仍可继续查询。