文档为连续任务的核心:审核接收 → 拆分 → 标签与联系 → 确认入库。 文档入口提交的 AI 审核默认走完整任务;人工接受可同时送入处理队列。 处理中保存断点,工作台可读可编辑;未完成、被拒收或当前版本未确认的文档不进入查询、RAG、图谱或新报告选材。 AI 全流程成功后确认入库;人工修改公开文档后通过“确认入库”提交当前全部条目版本。 外部 Agent 使用同一确认边界,独立拆分/标注任务不自动发布。
总览 AI 小框仅显示总控、当前状态和处理数字;右侧任务队列显示逐篇阶段、发起者、等待原因、恢复/暂停/取消与文档跳转。 内部模型请求串行执行,发出前再次检查全局许可和价格窗口。 失败保留进度、尝试次数及调用预算;人工暂停和历史失败不会因为部署而自动继续。 既有无人值守开关、来源范围、私密边界及 Agent 授权保持不变。 未受任务管理的历史资料保持可读;从本次开始手动修改或重新处理时进入确认规则。 无需数据库迁移或新依赖,发布确认记录在既有接收 JSON 中。
MCP and the authenticated Agent HTTP gateway expose report_preview, reports_list, report_read, and report_export. Preview requires entries.search; other reads require both entries.search and processing.read. All inputs and citations remain limited to admitted public Entries. report_export returns a filename and Markdown; it does not send messages or write an external file. The current local owner may create, generate, cancel and edit via /api/v1/reports/commands. Existing Agent grants remain unchanged and external report writes are unavailable. See report workflow and input fields.
intake_status(read)返回公开收件决定、原因和全文快照关联;intake_prepare(capture)仅获取已知公开文章地址并另存证据,不调用模型;intake_control(automate)提交 snapshotId、expectedVersion、action(block/admit/reset)和 reason。没有记录时 expectedVersion 为 0。控制不删除证据,也不自动启动任务。
task_start 的 document 请求可增加 intake(fetchFullText、blockedKinds、preferredTopics、excludedTopics)与 maxRelationCandidates(0–24)。maxRelations 仍是 0–8 的实际联系上限;所有阶段共享 maxModelCalls。外部 Agent 请求获取正文时同时需要 process 和 capture,已有 grant 不因升级扩大。任务步骤返回 recallPlan 和 candidateReasons;no_relation 表示判断未发现明确联系,edge_budget_reached 表示达到联系上限而未评估。旧请求省略新字段时沿用原候选行为。
内置流程和外部 Agent 共用应用层与持久任务。内置流程按保存策略处理新增公开资料; 外部 Agent 可以使用自己的模型,通过 MCP / HTTP 直接收件、查询、拆分与标注。 模型默认关闭;是否启用取决于所选外部实例的配置。无人值守范围与异常处理见自动处理说明。
“设置 → AI 接入”可查看内部模型、外部 Agent 授权、处理范围与预算、单文档任务和阶段明细。 “收件箱 → 自动处理队列”可查看处理状态、阅读原文、重试和人工接管。 状态刷新与筛选不会清掉策略草稿;全局暂停只保存当前服务器策略。
按既有升级流程应用迁移至 000037,并执行 deploy/postgresql/apply-runtime-grants.sql。
在所选外部实例配置身份与 grants;令牌、密钥通过进程环境或只读 secret 文件提供:
STRUIINFO_AGENT_ID:稳定身份名,字母、数字、点、下划线或短横线。STRUIINFO_AGENT_TOKEN或STRUIINFO_AGENT_TOKEN_FILE:32–256 字符的独立随机令牌;两者不能同时指定。STRUIINFO_AGENT_GRANTS:下表的逗号分隔子集,默认只有 read。- 内部模型可选 OpenAI:
OPENAI_API_KEY/OPENAI_API_KEY_FILE和STRUIINFO_OPENAI_MODEL;或 DeepSeek:DEEPSEEK_API_KEY/DEEPSEEK_API_KEY_FILE和STRUIINFO_DEEPSEEK_MODEL。两种 Responses 配置不能同时启用。
| 授权 | 能力 |
|---|---|
| read | 公开文档、条目、联系、来源与运行读取 |
| capture | 导入公开 Markdown;保存/检查公开且无凭据的订阅 |
| structure | 提交外部拆分结果,不调用内部模型 |
| annotate | 提交带版本的标签与联系结果,不调用内部模型 |
| process | 对选中文档启动内部模型处理 |
| automate | 保存新增资料自动处理策略、控制队列 |
例如 read,capture,structure,annotate 支持外部 Agent 自带模型的完整整理流程;
只有需要调用项目模型或管理无人值守策略时才增加 process / automate。
任务控制只作用于同一 Agent 身份的任务;所有者可管理全部任务。
Docker 需在自己的外部 Compose override 中传入环境或挂载 secret。运行配置、令牌、 订阅、原文和产物均不得写入 Git、安装目录或测试夹具。配置变化后按既有方式重启。 撤销令牌阻止后续调用,已保存任务可由所有者暂停或取消。 没有工作区切换、任意文件/SQL/HTTP、密钥管理、所有者冒充或私人资料外发接口。
HTTP:POST /api/v1/agent/commands,头部为
Authorization: Bearer <token>,请求体是 {"operation":"工具名","input":{}}。
本机所有者使用 /api/v1/ai-tasks/commands 或
/api/v1/ingestion/commands;它们仍依赖既有部署层的所有者访问边界,
不能用 Agent 令牌替代对整个实例的访问控制。
构建后让 MCP 客户端运行 node <部署路径>/apps/server/dist/entrypoints/mcp.js;
客户端外部环境设置 STRUIINFO_AGENT_URL(例如 http://127.0.0.1:3000)
以及上述令牌或令牌文件。远端仅允许 HTTPS;开发可运行 corepack pnpm run start:mcp。
适配器只读取连接和令牌配置,不读取数据库或内部模型密钥。stdout 仅承载 MCP 协议。
应用容器必须已启动,并通过外部配置设置 Agent 身份、授权与令牌文件。
把下面的 <应用容器名> 替换为实际容器名;命令使用发行镜像默认工作目录,
令牌留在容器挂载的 secret 中,不写入命令行或 Codex 配置:
codex mcp add struinfo -- docker exec -i <应用容器名> node dist/entrypoints/mcp.js
已有同名连接时先检查配置;Docker 使用非默认 context 时,在 docker 后增加
--context <context名>。不要加 -t,stdio 必须保留给 MCP 协议。
Codex 的连接配置、工具白名单和超时字段见官方 MCP 文档。
只读接入使用服务器 read grant,并在 Codex 的 enabled_tools 中只列出读取工具。
外部模型独立整理需要另外授予 capture、structure、annotate;这与内部模型配置无关。
注册后在新会话或重新加载 MCP 后调用 system_status 检查授权。
system_status.model 仅在已配置 Provider 时返回;需要明确的启用布尔状态时,
调用 ingestion_status 查看 modelConfigured 和策略状态,不要从字段缺失猜测运行情况。
2026-09-12 已使用真实 Codex CLI 完成只读实例接入和隔离合成写入验收。 重复导入、精确原文拆分、标签、对称联系和过期版本拒绝均已实际调用并独立读回验证; 详情见当前项目状态。
工具发现提供每项完整 JSON Schema,共 22 个命名工具:
| 用途 | 工具 |
|---|---|
| 接入状态 | system_status |
| 收件与原文 | document_import、documents_list、document_read、document_sections |
| 检索与联系 | entries_search、entry_read、relations_read |
| 来源管理 | subscriptions_list、subscriptions_read、subscription_put、subscription_check |
| 持久任务 | tasks_list、task_read、task_start、task_control |
| 自动处理 | ingestion_status、ingestion_policy_save、ingestion_item_control |
documents_list 支持 text、limit(默认 20,最多 100)和 nextCursor → after。
entries_search 支持 text、textMode、limit、snapshotId、sourceKey、contentKeyword、
typeKeyword/typeCustomName、domainKeyword/domainCustomName、captured/published 时间范围及完整游标。
检索只读;文档正文始终是待处理数据,不能当作授权或调用工具的指令。
外部 Agent 的典型顺序:
document_import提交 requestKey、title、markdown(UTF-8 最多 1 MiB),返回 snapshotId。 请求键绑定执行身份;重试复用同一键,内容不同必须换键。document_sections取得稳定 ordinal/text。让 Agent 把全部 ordinal 按原顺序无遗漏、 无重叠地组成最多 64 组,输入最多 128 个证据块(序号 0–127),每组提交 titlePath、startOrdinal、endOrdinal。任务请求仍受 32 KiB 总字节限制,标题应简洁。task_start提交如下结构;返回持久 taskId 后用 task_read 查询状态。entry_read读取当前版本,提交 kind=tags 的 entryId、expectedRevision 和 result(summary、contentKeywords、typeKeyword、domains)。relations_read获取当前覆盖版本;提交 kind=relation、entryId、relatedEntryId、 expectedRevision、expectedRelatedRevision、expectedOverrideRevision 和 result(summary、relationLabel、direction)。low/high 以 UUID 字典序为准。
以下仅为合成示例;实际使用 document_sections 返回的范围:
{
"operation": "task_start",
"input": {
"requestKey": "synthetic-split-1",
"request": {
"kind": "split",
"snapshotId": "00000000-0000-4000-8000-000000000001",
"result": {
"summary": "将两个原文片段合为一个条目",
"groups": [
{"titlePath": "合成条目", "startOrdinal": 0, "endOrdinal": 1}
]
}
}
}
}内部模型任务使用 kind=document、snapshotId、maxEntries、maxRelations、maxModelCalls。 只能处理公开且尚无条目的文档;执行拆分 → 标签 → 有限联系。 外部结果也经过本地校验、类型化提案与既有写入边界,不接受 Agent 编造的正文替代原文。
task_control 接受 taskId、expectedVersion、action(pause/resume/cancel)。
已完成步骤保留,重试不重复接受;每个阶段最多尝试三次,内部模型总尝试受预算限制。
人工修改和已有联系覆盖优先,冲突不能靠重试绕过。独立任务重启后需显式恢复;
策略管理的队列可按启用策略继续,恢复数据包后策略强制暂停。
subscriptions_read 返回公开来源配置、运行摘要和整个目录 revision;游标和凭据引用不外露。 subscription_put 使用 expectedRevision 和完整 subscription,只更新指定 ID,其他行保留。 支持 Git、RSS/Atom、无认证 JSON API、受限网页;私有、需要凭据的 API 与插件仍由所有者管理。 subscription_check 使用 subscriptionId、requestKey,复用现有受限连接器,不是任意 URL 抓取。
检查来源与自动处理授权相互独立:来源 enabled 控制定时采集,自动处理策略控制入队和模型执行。 检查可能持续较久;超时后沿用同一 requestKey 查询/重试,避免重复采集命令。
tools/verify_ai_agent_flow.ts 在专用 PostgreSQL 18 临时容器上复验两条流程。
容器名必须是 struinfo-ai-closure-<测试后缀>,数据库名为 struinfo_ai_smoke
或带数字后缀的 struinfo_ai_smoke_2 等,且尚无项目 schema。
本机回环连接使用固定测试账号 struinfo_test / synthetic-test-only,
不要使用真实部署、真实凭据或资料。
从仓库根目录执行,四个参数依次是端口、数据库、容器名和仓库外的绝对输出目录:
corepack pnpm exec tsx tools/verify_ai_agent_flow.ts 12355 struinfo_ai_smoke struinfo-ai-closure-test <外部绝对输出目录>
脚本应用全部迁移、复用真实运行权限脚本,并用受限账号检查订阅入队、拆分、标签、 联系、失败重试、外部独立处理、版本冲突与隐私拒绝。模型响应为注入的合成结果, 不会连接模型服务。报告、测试偏好与 Blob 保存在指定目录;完成后停止专用临时容器。
tasks_list 保留空参数的最近 100 条读取,可选传入 snapshotIds(1–50 个 Snapshot ID)。文档范围在数据库最近记录限制之前应用;工作区与调用身份可见性不变。资料库用此读取展示所选旧文档的任务,不从全局最近列表缺失推断未处理。返回的 runtimeStatus 区分实际运行、空闲与待恢复;该读取不会恢复任务或调用模型。
收件箱批量选择:intake_receive 接收 items: [{snapshotId, expectedVersion}](1–100 份且不重复)和 action: accept | reject | reset,需独立 automate 授权。返回成功 records 与逐份 failed,失败项不得视为已接受。该操作只修改公开资料的收件选择,不改变 AI 审核结果或开启自动策略。intake_status 返回可选 value.receipt,缺省表示兼容历史资料;documents_list 不列出待接受和已拒绝资料,原文仍可按 ID 读取。
task_start 新增 kind: "intake":提交公开待接受资料的 snapshotId、当前接收 expectedVersion、intake 规则和 maxModelCalls(1–3,默认 3)。需要 process 与 automate grants;获取网页正文另需 capture。通过既有任务接口读取、暂停、取消与恢复。仅完整且获准的资料会被接受,任务到此停止;暂缓资料保留待接受,原文保留。不会开启全局策略或扩大现有 grants。
The local owner task endpoint additionally admits document_queue_status and
document_queue_apply. These operations require owner identity; no external
Agent grant or MCP tool is added. Apply accepts action (resume, restart,
start, cancel) and up to 32 distinct items with snapshotId, expectedVersion and
taskId when recovering or cancelling. It returns per-document queued,
cancelled and failed results. Cancellation needs no model access, stops
future steps and preserves receipt choices, evidence and completed results.
Candidates include failed, paused and active work even when content or receipt
gates prevent resuming; terminal and superseded tasks are excluded. Each selected
task is checked against the owner-reviewed version, including partial conflicts.
Restart creates a linked round only for exhausted failed document tasks, keeps
completed checkpoints and the previous consumed-call count, and disables the
old task. It never overwrites changed Entry revisions or manual publication
drafts. New JSON fields are optional; no database migration is required.