# AI Core 与 Agent Core 开发说明 > 本文档用于团队开发和模块联调,记录当前已经落地的核心边界与使用方式。 > 更新日期:2026-09-02。第一阶段 AI Core、Agent Core、Extension Core 和 Model Core 主链路已经完成;第二阶段 Agent Trace 持久化、可恢复 SSE、stdio MCP Bridge、隔离 Plugin Host 以及 Plugin Command/Settings 已落地,后端当前回归基线为 126 项测试通过。 ## 当前实现 当前已经建立第一条可运行链路: ```text FastAPI → Provider Registry → Agent Runtime → Permission Manager → Tool Registry → Skill Runtime / Plugin Runtime → Agent Trace / SSE ``` 对应代码: ```text backend/app/ ├── providers/ │ ├── base.py Provider Protocol 与统一 Turn │ ├── registry.py Provider 注册、发现、模型列表和连接测试 │ └── mock.py 离线开发 Provider ├── agent/ │ ├── runtime.py Agent Loop、限制、取消、Trace 和 SSE │ ├── trace_repository.py Run/Event SQLite 持久化、分页、摘要与脱敏 │ ├── tools.py Tool 注册、参数校验、隔离执行和结果转换 │ ├── permissions.py 权限策略、确认请求和会话授权 │ └── builtin_tools.py 无副作用的内置开发 Tool ├── extensions/ │ ├── runtime.py Skill/Plugin Manifest、生命周期、依赖与 Tool Contribution │ └── mcp.py stdio JSON-RPC、MCP 生命周期、发现、调用与 Host 隔离 └── container.py AI Core 依赖组装 backend/extensions/ ├── skills/knowledge-assistant/ 内置知识库 Skill ├── plugins/text-tools/ 内置声明式 Plugin └── fixtures/mcp-echo/ 离线 MCP Server 联调 Fixture ``` Router 只负责 HTTP/SSE 与错误转换,不实现 Agent、Tool 或 Provider 业务逻辑。 ## 模块边界 当前实现属于范涵宇负责的 AI Core / Agent Core: - Provider 抽象与注册; - Agent Run 生命周期; - Tool Registry; - Tool 参数校验与执行隔离; - Permission; - Step、Timeout、Token Budget、取消; - Tool 并发上限与 run 级网络权限; - SQLite Trace、分页快照与可恢复 SSE; - Skill Manifest、Prompt、Tool/Permission/模型能力解析; - Plugin Manifest、生命周期和 Tool Contribution; - stdio MCP Bridge、隔离进程生命周期、Tool 映射与 Host 健康状态; - Skill 调用内置 Tool 与 Plugin Tool; - 公共 Contract 和 API 接入。 以下内容保持接口,不在本模块实现: - Note、NoteBlock、Markdown Parser:由 Knowledge Core 提供; - FTS5、Vector、RRF、Reranker、Citation:由 Retrieval Core 提供; - 文件系统和 API Key 明文读取:由 Rust Host 提供; - Frontend Extension Slot 与 Plugin Command/Settings UI:后端 Contract 与前端 Service 已完成,页面由前端后续联调。 ## Provider 默认注册离线 Provider: ```text provider_id = mock model = mock-1 ``` 它支持: ```text chat tool_calling streaming ``` 普通 Chat 请求: ```json { "provider_id": "mock", "model": "mock-1", "messages": [ {"role": "user", "content": "hello"} ] } ``` `POST /api/chat` 返回 ModelEvent SSE。OpenAI-Compatible Adapter 直接消费上游 SSE,Ollama Adapter 直接消费 JSONL,`TextDelta` 是真实增量内容,不再等待整段回答完成。 另外已经实现以下可配置 Adapter: ```text openai_chat / openai_compatible ollama ``` 创建 Ollama Provider: ```json { "provider_type": "ollama", "name": "Local Ollama", "base_url": "http://127.0.0.1:11434", "default_model": "qwen3:latest" } ``` 创建 OpenAI-Compatible Provider: ```json { "provider_type": "openai_compatible", "name": "OpenAI Compatible", "base_url": "https://api.openai.com/v1", "default_model": "", "credential_id": "openai-main" } ``` 凭证 ID `openai-main` 可以对应开发环境变量 `AINOTE_CREDENTIAL_OPENAI_MAIN`。当前 Web 联调版也允许设置页通过 Credential API 提交 API Key,由 `EncryptedCredentialStore` 使用 Fernet 加密保存;前端 Store、Provider Config、日志和读取响应都不保存或返回明文。未来接入 Tauri 后,由 Rust Host 从 Stronghold 注入或替换存储实现。 Provider 配置生命周期接口已经可用: ```text GET /api/providers GET /api/providers/presets POST /api/providers GET /api/providers/{provider_id} PATCH /api/providers/{provider_id} DELETE /api/providers/{provider_id} GET /api/providers/{provider_id}/models POST /api/providers/test GET /api/credentials/{credential_id} PUT /api/credentials/{credential_id} DELETE /api/credentials/{credential_id} ``` 设置页现已提供 OpenAI、DeepSeek 和 Ollama 预设,并在保存后自动获取、排序和去重模型列表。模型发现会区分凭据缺失、鉴权失败、限流、超时和上游不可用等错误。 ## Agent Run 创建普通 Agent Run: ```json { "input": "hello", "provider_id": "mock", "model": "mock-1", "max_steps": 10 } ``` 请求: ```text POST /api/agent/runs ``` 创建后通过以下接口读取状态和事件: ```text GET /api/agent/runs/{run_id} GET /api/agent/runs/{run_id}/events GET /api/agent/runs/{run_id}/trace?after_sequence=-1&limit=200 POST /api/agent/runs/{run_id}/cancel ``` Run 与 AgentEvent 已写入 SQLite,`run_id + sequence` 是幂等键。SSE 每帧包含 `id: sequence`;客户端可以通过 `Last-Event-ID` 请求头或 `after_sequence` 查询参数恢复缺失事件。Trace API 返回平铺事件、下一游标、分页状态、模型/工具调用统计、耗时、Token Usage 和创建 Run 时的配置快照,不负责生成前端树形布局。 运行时内存仍只保留最近 2000 个事件用于实时订阅,完整 Trace 以 SQLite 为准。AI Core 重启后,已经终止的 Run 可以继续查询和回放;重启前未终止的 Run 会收束为 `AGENT_PROCESS_RESTARTED`,避免永久停在 `running`。API Key、Authorization、Password、Secret、常见 `sk-`/Bearer 值在入库前脱敏。Event、Request 和配置快照中的超长字符串与集合会截断;作为查询事实来源的 `AgentRun` 只脱敏、不限长,保证重启前后 input/output 内容一致。 ## Tool Calling 当前注册以下内置 Tool: ```text system.echo math.add notes.search rag.search notes.read notes.create notes.update notes.list notes.move tasks.create tasks.update tasks.list attachments.read audio.transcribe ``` Mock Provider 使用下面的开发语法产生 Tool Call: ```text /tool system.echo {"text":"hello tool"} /tool math.add {"left":1,"right":2} ``` Agent Run 需要显式声明 `allowed_tools`: ```json { "input": "/tool math.add {\"left\":1,\"right\":2}", "provider_id": "mock", "model": "mock-1", "allowed_tools": ["math.add"] } ``` Tool 参数由独立 Pydantic Model 再次校验。Tool 的异常、非法参数、超时和权限拒绝统一转换为 `ToolResult`,不会直接打断 API 进程。 `notes.search` / `rag.search` 返回的 Citation 会由 Agent Runtime 收集到 `AgentRun.citations`,并产生 `Citation` Trace Event。Note 写操作调用 `note_service`,检索调用 Retrieval Engine,不直接访问 SQLite。 ## Permission Permission Policy 当前支持: ```text allow confirm deny ``` 需要确认时,Agent 状态进入 `waiting_permission`,并发出 `PermissionRequired` 事件。前端使用: ```text POST /api/agent/runs/{run_id}/permissions/{request_id} ``` 提交以下决策之一: ```json {"decision":"allow_once"} {"decision":"allow_session"} {"decision":"deny"} ``` 默认需要确认的高影响权限包括 `notes.write`、`notes.delete`、`tasks.write`、`network.request` 和 `secrets.use`。权限命名空间采用白名单,未知权限默认拒绝。 ## Knowledge / Retrieval 接入 Knowledge Core 与 Retrieval Core 已通过 Tool Registry 接入 Agent。Agent Runtime 仍只依赖 Tool Contract,不直接依赖具体服务: ```python tool_registry.register( definition=tool_definition, arguments_model=arguments_model, executor=executor, ) ``` 第一批已经接入: ```text notes.search notes.read notes.create notes.update notes.list rag.search ``` 写操作 Executor 调用 Knowledge Core Service,不直接访问 SQLite;检索 Executor 调用 Retrieval Core Service,不直接拼接 FTS5 或 sqlite-vec SQL。 ## Extension Core ### Skill Runtime Skill Package 由 `skill.yaml` 和可选 `prompt.md` 组成。安装时使用 Pydantic 校验 Manifest,并解析: ```text permissions tools retrieval model.required_capabilities ``` Skill 启用前检查 Tool 是否已注册、Tool 所需权限是否已在 Manifest 声明。创建 Agent Run 时,Skill Runtime 生成 Agent Configuration,注入 System Prompt、允许的 Tool、权限和 Retrieval Config。模型缺少 `chat`、`tool_calling` 等必要 Capability 时拒绝启动。 生命周期接口: ```text GET /api/skills POST /api/skills/install GET /api/skills/{skill_id} POST /api/skills/{skill_id}/enable POST /api/skills/{skill_id}/disable DELETE /api/skills/{skill_id} ``` ### Plugin Runtime 第一阶段 Plugin Runtime 完成 Manifest 校验、安装、启用、停用、卸载和声明式 Tool Contribution。阶段 C 增加 stdio MCP Bridge:第三方代码不会直接 import 到 AI Core,而由独立子进程运行,通过换行分隔 JSON-RPC 完成 initialize、Tool 发现和调用。 启用 Plugin 时将 Tool 注册到统一 Tool Registry,并标记 `source=plugin`;停用或异常时注销 Tool。启用中的 Skill 依赖某 Plugin Tool 时,Plugin 不能直接卸载。 生命周期接口: ```text GET /api/plugins POST /api/plugins/install GET /api/plugins/{plugin_id} POST /api/plugins/{plugin_id}/enable POST /api/plugins/{plugin_id}/disable PUT /api/plugins/{plugin_id}/permissions GET /api/plugins/{plugin_id}/host POST /api/plugins/{plugin_id}/host/restart DELETE /api/plugins/{plugin_id} ``` Plugin Manifest 中的权限只是声明,不代表已经授权。带权限的 Plugin 安装后进入 `permission_required`,Host 必须通过权限接口记录用户授权,之后才能启用。JSON Schema 在安装阶段校验,Tool 调用时再次校验实际参数。 MCP Tool 进入 Registry 前统一增加 `.` 命名空间。Server 声明的 `notesagent/permission` 必须属于已知权限并出现在 Plugin Manifest;发现集合还必须与 Manifest Contribution 完全一致。启用失败会回滚全部 Tool 并关闭子进程,异常退出会把 Plugin 标记为 `error` 并立即注销对应 Tool。详细实现和 Fixture 操作见 [MCP Bridge 与 Plugin Host 开发说明](MCP-Bridge与Plugin-Host开发说明.md)。 内置示例 `text-tools` 注册 `text.uppercase`。内置 `knowledge-assistant` Skill 同时声明 `notes.search` 和 `text.uppercase`,用于验证完整链路: ```text Skill Manifest → Agent Configuration → Tool Registry → Plugin Tool → Tool Result → Agent Loop ``` ## 当前限制与下一步 前端智能体页面已经完成中文联调:运行状态、Agent Event、内置 Tool、Permission 和常用事件详情字段均通过集中标签映射展示中文;`notes.search` 等技术 ID 继续保留,便于与后端 Trace、日志和接口契约对应。 - 已实现 Mock、OpenAI-Compatible Chat Completions 与 Ollama Adapter;OpenAI Responses 和 Anthropic Messages 尚未实现。 - Provider 配置暂存内存,后续通过 Repository 接入 SQLite;PATCH 已支持用显式 `null` 清空 base URL、默认模型和凭据引用。 - Run/Trace 已通过 Repository 接入 SQLite;后续增加按保留策略归档和 Benchmark 引用保护。 - Permission 已有核心等待/恢复机制,前端确认 UI 已完成联调和中文展示。 - Task 已持久化到 SQLite;Attachment Tool 读取 Host 管理目录中的 UTF-8 文件。 - `audio.transcribe` 当前消费 Host 预生成的 transcript;faster-whisper 与说话人分离仍按技术基线在第二阶段接入。 - Extension 安装记录暂存内存;后续接入持久化 Registry 与版本升级流程。 - 当前 Plugin Host 支持内置声明式 handler、本地 stdio MCP Server 以及 Plugin Command/Settings;Streamable HTTP、OS 级沙箱与 UI Contribution 留在后续阶段。