产出 docs/NL_develop交付说明-评审意见.md(可直接转给组员),以及一个只读探查工具 tools/probe_knowledge_collections.py(Milvus 集合 schema 与行数)。 核查中发现的硬矛盾,都有可复核的证据: 1. 配置库不是同一个。对方说 active=216、合并前生效版本是 186;我这边实测 active=201, 最近 5 条 id 就是 201/198/197/196/195 —— release.id 自增,同库不可能一边 216 一边 201。 所以他以为已发布的 customer_service:faq=[search_knowledge, query_customer_profile] 在这边并不存在,而他的画像出口复用的正是这个 key ⇒ 合并后被 ToolExecutor 失败关闭。 同理他说的 fund_query_demo:fund_quote 缺失,我这边是存在的。 2. Milvus 也不是同一个。对方说现库字段是 knowledge_id/snippet、无 visibility、行数 106/177/73;我这边实测是 doc_id/content/chapter/section/.../visibility 共 15 个字段、 行数 125/297/214,且与 knowledge_search_service.py 的 OUTPUT_FIELDS 逐字一致。 他这次的字段映射改动(doc_id→knowledge_id)在这边会直接报 field knowledge_id not exist,把客服知识检索整条打挂 —— 比他自述的"关闭 visibility 隔离"严重得多。 建议不是 A/B/C 三选一,而是第四种:运行时探测字段名,两套 schema 都能跑。 3. 解释器不同。他用 .venv(项目里不存在,那是他机器上的 gitignore 目录),约定是 D:\conda\envs\jr_py313。所以"mypy 151→181"跑不到本基线 —— 这边是 138 文件 0 错。 另指出:docs/26-JWT密钥管理与轮换.md 会与已存在的 docs/21-JWT密钥管理与轮换.md 重复, 建议并入 21;驳回删除 docs/04/06/10/13/99。 四项待裁决的答复:同意 agent_type 方案(要求补审计);字段映射改为运行时探测; 驳回删除编号文档;26 并入 21。
113 lines
3.5 KiB
Python
113 lines
3.5 KiB
Python
"""只读探查:当前 active 配置发布与配置项数量(用于同步 docs/24 的"当前状态"表)。
|
||
|
||
只做 SELECT,结果写 `docs/evidence/release-state.json`:
|
||
|
||
python tools/probe_release_state.py
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import asyncio
|
||
import json
|
||
from pathlib import Path
|
||
from typing import Any
|
||
|
||
from sqlalchemy import text
|
||
|
||
from app.infrastructure.db import SessionFactory
|
||
|
||
OUTPUT = Path("docs/evidence/release-state.json")
|
||
|
||
|
||
async def collect() -> dict[str, Any]:
|
||
report: dict[str, Any] = {}
|
||
async with SessionFactory() as session:
|
||
report["recent_releases"] = [
|
||
dict(row)
|
||
for row in (
|
||
(
|
||
await session.execute(
|
||
text(
|
||
"""
|
||
SELECT id, release_no, title, status, created_at, activated_at
|
||
FROM config_release
|
||
ORDER BY id DESC
|
||
LIMIT 5
|
||
"""
|
||
)
|
||
)
|
||
)
|
||
.mappings()
|
||
.all()
|
||
)
|
||
]
|
||
report["active_items"] = [
|
||
dict(row)
|
||
for row in (
|
||
(
|
||
await session.execute(
|
||
text(
|
||
"""
|
||
SELECT i.namespace, COUNT(*) AS items
|
||
FROM platform_config_item i
|
||
JOIN config_release r ON r.id = i.release_id
|
||
WHERE r.status = 'active'
|
||
GROUP BY i.namespace
|
||
ORDER BY i.namespace
|
||
"""
|
||
)
|
||
)
|
||
)
|
||
.mappings()
|
||
.all()
|
||
)
|
||
]
|
||
report["active_prompt_versions"] = (
|
||
await session.execute(
|
||
text(
|
||
"""
|
||
SELECT COUNT(*) FROM prompt_template_version p
|
||
JOIN config_release r ON r.id = p.release_id
|
||
WHERE r.status = 'active'
|
||
"""
|
||
)
|
||
)
|
||
).scalar_one()
|
||
# 工具白名单的**具体内容**:它必须与代码里的 allowed_tools 交集非空,
|
||
# 否则 ToolExecutor 失败关闭,Agent 任何工具调用都被拒。
|
||
report["active_agent_tools"] = [
|
||
dict(row)
|
||
for row in (
|
||
(
|
||
await session.execute(
|
||
text(
|
||
"""
|
||
SELECT i.config_key, i.value_json, i.schema_version
|
||
FROM platform_config_item i
|
||
JOIN config_release r ON r.id = i.release_id
|
||
WHERE r.status = 'active' AND i.namespace = 'agent_tools'
|
||
ORDER BY i.config_key
|
||
"""
|
||
)
|
||
)
|
||
)
|
||
.mappings()
|
||
.all()
|
||
)
|
||
]
|
||
return report
|
||
|
||
|
||
async def main() -> None:
|
||
report = await collect()
|
||
OUTPUT.parent.mkdir(parents=True, exist_ok=True)
|
||
OUTPUT.write_text(
|
||
json.dumps(report, ensure_ascii=False, indent=2, default=str),
|
||
encoding="utf-8",
|
||
)
|
||
print(f"wrote {OUTPUT}")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
asyncio.run(main())
|