短剧《拥有纯阳仙体,我无敌了》剧情介绍
2026-07-23 3419969
2026-07-23 0
前面几轮开发里,我给自己的 QQ AI Chatbot 做了一个本地 Web Owner Console。

最初它很克制:
只读取任务、审批、配置和运行观测。不执行工具。不修改配置。不写业务数据库。前端请求受 GET allowlist 约束。
这套只读边界解决了“主人怎样看见系统”的问题,但很快又暴露出另一个问题:
看见配置开启,不等于功能真的可用。看见索引计数,不等于一次真实检索能够完成。看见服务地址,不等于依赖链已经跑通。
尤其是 Diagnostics 页面,即使把中英文状态、原始 code 和区块层级整理得很清楚,它仍然更像一份配置目录。
于是我开始做下一步:允许主人在页面上显式触发少量、后端固定、可证明边界的手动诊断。
这一篇记录我怎样从只读页面走到真实探针,又怎样避免“加一个诊断按钮”演变成任意操作入口。
在开放手动动作之前,我先重做了 Reliability 和 Diagnostics 页面的信息层级。
Reliability 页面保留英文原始证据:
componentoperationcategorycoderecovery_state
中文只负责解释,不覆盖这些值。确定性总结只根据结构化数据生成,不调用 LLM,也不会在缺少等长对比窗口时武断地说“故障上升”或“故障下降”。
Diagnostics 页面也采用同样原则:
中文含义解释值原始英文证据
页面变得好读以后,主人给了一个很准确的反馈:它仍然主要在展示开关和快照,没有真正执行诊断,也不能判断某条实际链路是否工作。
这个反馈让我重新区分了两个概念:
read snapshot读取已有状态,适合自动刷新。manual diagnostic action主人显式批准后,执行一次有真实成本或真实外部调用的固定动作。
第二类动作不能伪装成普通 GET,也不能因为名字叫“诊断”就默认安全。
我没有给页面增加这些输入框:
自由 prompt模型名称Base URLSQL工具名top_k超时重试次数
因为一旦接受这些字段,Owner Console 就不再是在运行“已注册诊断”,而是在提供一个通用执行器。
我最终采用的是固定工作流注册模型:
前端只知道工作流名称和说明。后端拥有完整输入、预算和执行逻辑。请求体只携带固定 confirmation。每次动作只执行一个已注册工作流。
首批开放的是:
project_doc_rag_fixed_retrievalmemory_rag_index_consistency
它们都属于 RAG,但安全边界完全不同,所以没有强行塞进一个“通用 RAG 测试”接口。
本地控制台只监听 loopback,并不意味着 POST 可以随便开放。
每个手动诊断都要经过这些条件:
服务启动时显式启用对应工作流。页面第一次点击只展开风险说明。主人第二次点击才真正确认。请求必须来自允许的同源 Origin。请求必须携带进程内动作 Cookie。请求必须使用固定动作 Header。Content-Type 必须正确。JSON body 必须精确匹配固定 confirmation。多余字段也会被拒绝。
动作 Cookie 通过同源 GET 获得,设置为:
HttpOnlySameSite=Strict
服务每次启动生成新的进程内动作 session。仅知道 POST 路径还不够,旧进程的 Cookie 也不能拿到新进程继续使用。
前端原有 guard 也从“只允许 GET”升级为精确 allowlist:
允许已有只读 GET。只额外允许已注册的固定 POST。未知 POST、动态路径和自由请求仍然失败。
这不是把整个控制台改成可写,而是在只读控制台上切出几个非常窄的动作孔径。
手动动作还有一个容易被忽略的问题:并发。
如果主人连续点击两个工作流,系统可能同时执行 embedding、SQLite 扫描或 LLM 请求。即使每个动作单独看都安全,并发后也会让结果、资源消耗和最近运行状态变得难以解释。
所以这些工作流共享同一个进程内全局运行锁:
正在运行一个工作流时,其他工作流直接返回 busy。不排队。不自动等待。不自动重试。完成后也不自动串行启动下一个工作流。
最近结果只存在 Owner Console 进程内。重启后自然清空,不写入:
聊天历史Agent taskapprovalreliability event业务诊断表
对这种主人临时确认的本机探针来说,进程内状态反而让边界更清楚。
第一个工作流要回答的问题很朴素:
当前 ProjectDocRAG 能不能对后端固定问题生成向量,并从现有项目文档索引中返回固定前五项?
审计现有检索入口后,我没有直接复用它。原因是生产检索链会经过数据库初始化和普通可提交连接,无法证明 database_write=false。
因此这个工作流使用专用路径:
固定问题只存在后端局部内存。当前 embedding provider 只调用一次。不做 legacy fallback。不自动重试。SQLite 使用 URI mode=ro。只查询 source_id、chunk_index 和 embedding。本地计算相似度并取 top 5。
页面不显示固定问题、文档正文、片段内容、文件路径或原始异常,只展示完成判断所需的有限证据:
活动片段数当前 provider/model 的有效向量数返回数量固定目标是否命中最高相似度workflow / stage / code零副作用字段
还有一个实际踩到的坑:生产配置里的 enable_project_doc_rag=false,最初被我当成手动探针的硬阻断。
但这两个开关语义不同:
生产功能开关控制普通运行链是否使用 ProjectDocRAG。手动探针开关主人是否在本次 Owner Console 启动中批准固定诊断。
最终实现把生产开关保留为 runtime_feature_enabled 证据,但不让它覆盖主人对固定动作的独立授权。
真实页面验收中,这个工作流完成了:
一次真实 embedding一次 SQLite mode=ro 检索top 5 返回固定目标命中数据库大小和 mtime 不变
这才是“真实检索通过”,而不只是“索引看起来存在”。
第二个工作流故意没有做真实私人记忆检索。
我想先回答一个更基础、也更容易控制暴露面的事实问题:
活动 MemoryRAG 文档与当前有效向量是否一致?
专用 SQL 仍然使用 SQLite mode=ro,并且不选择:
contentsummary其他私人正文列
它只统计:
活动文档数量当前 provider/model/content_hash 的有效向量数量manual_fact、preference、session_summary 各自缺失数量来源映射缺口软删除历史文档所带向量数量
这个工作流不会:
生成查询向量调用 embedding执行 retrieve_memory读取私人记忆正文调用 ProjectDocRAG、DevContext 或 CombinedRAG重建索引补写缺失向量自动创建修复任务
真实结果发现:
活动文档 37有效向量 35缺失向量 2两条缺失都属于 manual_fact来源缺失 0软删除历史向量 5
页面给出的结论是:
outcome=attentionstage=result_validationcode=memory_rag_active_embedding_gap
注意,这不是工作流失败。
工作流成功完成了只读一致性检查,并发现了一个真实缺口。因此它需要关注,但不应该标成“执行失败”。
手动诊断最容易把两件事混在一起:
诊断程序有没有正常完成?被诊断对象有没有完全满足期望?
我最终采用三类结果:
succeeded工作流完成,目标合同满足。attention工作流完成,但发现兼容性、性能或一致性问题。failed工作流本身没有完成,例如配置缺失、连接失败、超时或内部错误。
并且每个结果必须保留英文定位证据:
workflowstagecode
中文可以写“需要关注”,但不能把 memory_rag_active_embedding_gap 藏掉。否则后续排障只能依赖页面文案,接口合同会重新退化成不可搜索的自然语言。
看到两条缺失向量时,最诱人的下一步是:
自动补一下。
但“知道缺少两条向量”和“批准读取相应正文并调用 embedding 写回数据库”是两种完全不同的授权。
自动修复至少会扩大这些边界:
读取私人内容调用外部或本地模型产生新的向量数据修改数据库处理部分成功和失败恢复决定是否重试
所以本轮只记录事实,不创建修复任务,也不在页面放一个看似方便的“立即修复”按钮。
诊断的职责是让问题变得可验证,不是替主人扩大授权。
这类功能的测试不能只断言响应是 200。
我给它补了几类负向合同:
错误 Origin、Cookie、Header、Content-Type 或 confirmation 必须被拒绝。多余 JSON 字段必须被拒绝。页面一次确认只能产生一个 POST。两个工作流不能并发。SQLite 查询前后文件大小和 mtime 不变。MemoryRAG 查询不选择正文列。MemoryRAG provider 不能调用 embedding。ProjectDocRAG embedding 只能调用一次。前端 guard 只能放行注册过的固定 POST。
最终回归覆盖了后端、前端、TypeScript、生产构建、固定 POST guard、Python AST、依赖一致性和 git diff --check。
真实页面验收时,我还单独核对了访问日志中的 POST 次数、最近运行 ID、数据库文件大小与 mtime,以及后端日志中的 ERROR、Traceback 和 Exception。
这次改造让我对“只读控制台”有了一个更细的理解。
一个控制台可以默认只读,同时允许少量主人批准的真实诊断;关键不在于 HTTP 方法是不是 POST,而在于动作是否满足这些条件:
输入后端固定。能力启动时显式启用。主人二次确认。接口精确 allowlist。执行预算有上限。不同工作流共享并发锁。结果区分 succeeded、attention 和 failed。原始英文证据可见。不自动重试、修复或启动后续动作。
ProjectDocRAG 的价值是证明一次真实 embedding 和只读检索能跑通。
MemoryRAG 一致性检查的价值是发现两条真实缺口,同时证明私人正文没有被读取、向量没有被补建、数据库没有被修改。
好的诊断不只告诉我系统做了什么,也要让我能够确认:
它这次没有越过哪些边界。