1. 阅读本手册
本手册从入门到架构、路由、请求、数据、视图和扩展的编排方式。先读第 2~5 章并启动网站,再按要修改的功能查后面的章节。
阅读代码时,先定位页面或接口,再找到服务、数据模型和测试。不要仅凭页面名称猜测实际业务入口。仓库中的 README.md 适合初次安装,docs/ 记录专题细节,根目录 AGENTS.md 是开发约定;三者和本手册一起使用。示例路径均相对于项目根目录。
2. 项目是什么
TangGaoCMS 是带 AI 助手的网站管理系统。网站展示文章、产品、单页和栏目;管理员在后台维护内容、模板、媒体和用户,也可以向唯一的系统 Agent 发出管理指令。
技术组成如下:
| 技术 | 在项目中的职责 |
|---|---|
| .NET 10、ASP.NET Core | 启动 Web 宿主、处理 HTTP 和依赖注入 |
| Blazor Web App | 网站会员页与管理后台交互 |
| EF Core、MySQL | 读取和保存业务、账号数据 |
| ASP.NET Core Identity | 登录、角色与账号管理 |
| Microsoft Agents AI、Agent.Runtime | 模型对话、工具调用和任务运行 |
| Vue、TypeScript、Vite | 模板代码编辑器 |
| LightRAG、MCP | 按需启用的知识检索与外部工具能力 |
只有 Web 可以作为完整网站启动。 Single 和 Orchestrator 是业务类库。浏览器访问 Web,它再连接 MySQL、模型 Provider,以及启用的插件和服务。
浏览器 ──> Web(网站 / 后台 / 编辑器 / API) ├─> MySQL ├─> 模型 Provider ├─> 可选 LightRAG └─> 可选 MCP 服务
3. 环境、安装与首次启动
3.1 准备工具
本地开发需要 .NET 10 SDK、MySQL 8、PowerShell;修改或重新构建模板编辑器时还需要 Node.js 与 npm。首次构建需联网还原 NuGet 和 npm 依赖。检查版本:
dotnet --version node --version npm --version
dotnet --version 应显示 10.x。项目中的 Agent.Runtime 是配套运行库;使用开源导出包时,应确认包内 runtime/ 的 DLL 与源码版本一致。
3.2 初始化空数据库
先在 MySQL 创建一个 UTF-8 数据库,再导入 database/TanggaoCMS.sql。开源导出包使用根目录的 TanggaoCMS.sql,内容是同一份安装文件。
CREATE DATABASE agentOne CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
安装 SQL 只适用于空库。已有网站升级时先备份,执行对应版本的增量 SQL;应用不会在启动时自动迁移数据库。数据库连接填写在配置键 ConnectionStrings:DefaultConnection,账号需有安装和业务运行所需权限。
3.3 配置与启动
配置文件位于 Web/appsettings.json,也可通过环境配置覆盖。至少核对数据库连接,以及 Provider 中的名称、密钥和默认模型。API Key、数据库密码等真实凭据不要提交到公开仓库。
.\start.ps1 -Build
以终端打印的监听地址为准。网站入口是 /,后台路径默认 /admin/,但实际路径由 Admin:Path 决定;本地配置可能已经改过。编辑器由后台的模板编辑入口打开,公开 API 位于 /api/。旧的 /chat/、/share/、/web/ 前端入口已移除。
启动后依次确认:首页能打开、管理员能登录、后台能读取内容、AI 能回复一条普通消息。模型聊天失败时先核对 Provider 配置和终端日志,不要先修改 CMS 代码。
4. 源码目录与职责
| 路径 | 主要职责 | 常见修改 |
|---|---|---|
Web/ | 唯一宿主,路由、认证、静态文件、站点页面 | 启动、中间件、CMS 页面 |
Admin/Admin.Client/ | 后台 Blazor 页面、组件和 API 客户端 | 管理界面 |
Admin/TemplateEditor/ | Vue 模板代码编辑器源码 | 文件树、预览、编辑交互 |
Single/ | 唯一 Agent 的入口与服务注册 | Agent 对话、配置、访问 |
Orchestrator/ | 控制器、服务、实体、CMS 业务 | 大部分后端功能 |
Common/ | 前后端共享 DTO、路由等契约 | 请求与响应格式 |
Agent.Abstractions/ | Agent 可复用接口 | 跨模块接口 |
Agent.Runtime/ | Agent 运行时、授权、任务与技能基础能力 | 运行机制 |
Plugin.Abstractions/、Plugins/ | 插件契约和内置插件 | 新插件或知识库 |
AITools/ | 简单的内置 AI 工具 | 无复杂业务依赖的小工具 |
Single.Tests/ | 自动化测试 | 功能回归 |
template/default/ | 默认网站模板 | 模板文件和标签 |
skills/ | Agent 可发现的技能说明 | 新技能与素材 |
查找功能时,通常沿着“页面或 HTTP 路由 → 客户端 Service / Controller → 后端 Service → DbContext / 外部服务”阅读。新增代码沿用相邻模块的命名、注册和异常处理方式。
5. 一次请求怎样走完
5.1 网站页面
Web/Program.cs 注册服务、中间件、控制器和 Blazor 路由。CMS 页面请求由站点路由和 MapCmsEndpoints() 处理,服务层读取内容与模板,最终生成 HTML。静态图片通常从 /static/upload/... 提供。CMS 兜底路由必须避开后台前缀,否则后台可能被当成网站页面。
5.2 后台操作
后台使用独立 Blazor Router。组件放在 Admin/Admin.Client/Pages/,共享组件放 Components/,HTTP 访问放 Services/。管理员点击保存时,客户端 Service 请求 /api/*;Controller 负责认证、参数与 HTTP 结果;业务 Service 校验规则并调用 EF Core。
后台页面 → Client/Services → /api/* Controller → Services → DbContext → MySQL
页面要显示加载、空数据、失败、禁用与提交中状态,异步保存完成前阻止重复提交。不要在多个 Razor 组件内重复拼 URL、发送请求和反序列化。
6. 配置与依赖注入
Web/Program.cs 配置宿主、Identity、路由和 UI;Single/AgentServiceCollectionExtensions.cs 注册后端业务服务、Controller、Agent 能力和插件。新增业务服务通常在后者注册,宿主专用服务在前者注册。
| 配置键 | 用途 |
|---|---|
ConnectionStrings:DefaultConnection | MySQL 连接 |
Provider:* | 默认对话模型及服务地址 |
SingleAgent:* | 输入、历史与超时限制 |
Admin:Path | 后台公开 URL 前缀,重启生效 |
Cms:Directory | CMS 运行数据与模板目录 |
Cms:BootstrapTemplateDirectory | 默认模板来源 |
Cms:UploadDirectory | 上传文件目录,可选 |
Storage:DataDirectory、Storage:KeyDirectory | 本机数据和 Data Protection 密钥 |
ImageGeneration:*、VideoGeneration:* | 图片与视频服务设置 |
Skills:Directory | 技能目录,可选 |
新增配置先查看对应 Options 类型和当前绑定方式;使用绝对路径前确认部署机器也有该目录。Data Protection 应用名是 NTGAgent,变更 Cookie 或密钥路径可能使已有登录失效。图像、视频、LightRAG 和 MCP 可以按需配置,不应使未使用这些功能的普通聊天失效。
7. 路由、地址与导航
网站路由和后台路由分别由各自 Router 渲染。后台页面在源码中始终声明规范路径 /admin/...,宿主将其映射到配置的公开前缀。生成后台链接使用 AdminRoutes.Url(...);判断路径先用 AdminRoutes.Canonical(...)。API、静态资源、上传地址和会员路由不附加后台前缀。
| 地址 | 含义 |
|---|---|
/ | CMS 网站 |
/admin/... | 后台规范路由,公开前缀可配置 |
/editor/... | 模板编辑器静态页面 |
/api/... | HTTP API,前缀固定 |
/cms-member/... | 网站会员登录及资料 |
/mcp | 启用时的 MCP HTTP 端点 |
改动后台路径后重启 Web,再从当前配置的入口登录。不要把当前机器的 admin2 等实际前缀硬编码到菜单、API 或数据库菜单记录里。新增 Controller 沿用邻近接口的路由和状态码约定。
8. 请求、响应与 DTO
Controller 只处理 HTTP 契约、认证授权、基本参数校验和状态码。业务规则在 Orchestrator/Services/。需要前后端共用的请求和响应类型放 Common/Dtos/;仅后端使用的类型留在业务目录或 Orchestrator/Dtos/。不要把 EF 实体直接作为公开 API 响应。
一般开发步骤:
在
Common/Dtos/定义稳定的请求与响应字段,区分必填和可空值。在 Controller 校验参数、从认证上下文取当前用户,并调用 Service。
在 Service 实现业务、传递
CancellationToken、处理预期失败。在后台 Client Service 封装 HTTP 调用,再供页面使用。
针对成功、越权、无数据与冲突等真实行为补充必要测试。
普通用户接口必须校验资源归属;管理接口保留管理员和菜单策略。API 未登录返回 401、无权返回 403 的行为由宿主认证配置统一处理。请求体中的用户 ID 不能代替认证身份。
9. 数据库、实体与升级
本项目有两个 DbContext:AgentDbContext 管业务数据,AppIdentityDbContext 管 Identity 账号和角色。Provider 是 MySql.EntityFrameworkCore。优先写 EF Core 参数化查询;原始 SQL 中的数据值必须参数化,动态列名和排序项必须经白名单验证。
改实体字段时,逐项检查:实体和 EF 映射、DTO、Service、Controller、后台页面、测试、database/TanggaoCMS.sql。已有网站还需要独立的增量 SQL 和明确升级步骤。历史 EF 迁移目录已清理,不要恢复旧迁移或在启动时自动迁移。
涉及多表状态、配额、Token 使用量、文档摄取状态时使用事务。后台任务和接口可能重试,应明确幂等条件;并发更新要处理版本冲突或重复请求。初始化脚本不是备份文件,不能导入到已有网站覆盖业务数据。
10. 身份、权限和会员
后台与网站会员共享 Identity 用户库,使用 ApplicationUser 和 AppIdentityDbContext。后台策略为 Admin,部分页面和接口还有 Menu:<菜单键> 权限。普通会员不因登录而自动拥有后台权限。
用户从会员页面登录使用 /cms-member/login,后台登录使用当前后台前缀对应的登录页。开发权限功能时同时检查页面可见性和服务端授权;隐藏按钮不能替代 Controller 的权限检查。角色、菜单与 Agent 访问控制各有用途,不要把管理员限制设置为全站默认策略。
授权相关接口和插件还可通过 ILicenseStatusProvider.GetStatusAsync(ct) 查询当前免费授权状态。查询返回状态 DTO,不替代受保护操作入口的 CommercialLicenseGuard.RequireAsync(ct)。详情见 docs/commercial-licensing.md。
11. CMS 内容、栏目与媒体
CMS 的文章、产品、单页、栏目、导航、表单、留言、站点设置和媒体主要在 Orchestrator/Services/Cms/ 实现;管理 API 在 Orchestrator/Controllers/Cms/,后台页面在 Admin/Admin.Client/Pages/Cms/。
新增一种内容操作时,先确定它是公开读取、后台管理,还是 AI 可调用动作。公开读取应考虑发布状态、栏目范围、分页和缓存;写入应验证字段、权限、关联资源及缓存失效。媒体保存要使用现有文件策略和存储服务,避免把客户端文件名直接当成磁盘路径。
运行中的模板文件位于 Cms:Directory 下的模板目录,上传文件默认位于 Web/wwwroot/static/upload/,也可通过配置调整。数据库备份只保存数据库;模板、上传文件、配置、密钥和外部知识库数据需要另行备份。
12. 模板、站点渲染与编辑器
默认模板源文件在 template/default/。启动时 CmsTemplateBootstrapService 会按规则同步默认模板到运行目录;自定义模板与运行目录中的实际文件也必须一致。模板渲染代码位于 Orchestrator/Services/Cms/Templates/,Pboot 兼容标签位于其 Pboot/ 子目录。
后台模板管理与代码编辑器是两部分:模板管理页负责列表和设置;Admin/TemplateEditor/ 是 Vue 源码,构建后由 Web/wwwroot/editor/ 提供。修改编辑器后,在其目录中执行:
npm ci npm test npm run build
模板标签兼容的具体边界见 docs/pboot-template-compatibility.md。修改渲染器时,使用真实模板页验证首页、列表页、详情页和链接;不要只验证单个字符串替换。编辑已启用模板会影响在线页面,保存前应确认目标模板和文件。
13. 唯一系统 Agent
项目始终只有一个系统 Agent。SingleAgentResolver 负责解析它,数据库通过 Agents.SingletonKey 唯一索引保证最多一条。不要引入多 Agent 路由、Agent 切换或让客户端传入任意 Agent ID 绕过访问控制。
模型调用通过既有 IAgentFactory、Provider 服务和 SingleAgentService。Agent 可以使用 Skills、内置工具、MCP 和知识库;这些能力在 Orchestrator/Services/Agents/ 等位置组装。Controller 和 Razor 页面不要直接构造模型 SDK 客户端。
后台 AI 管理可以执行真实写入。新增 AI 工具前,先确认对应业务 Service 已具备权限、校验和事务能力;工具只负责把明确的参数交给该 Service,并通过既有捕获机制展示执行结果。
14. 会话、任务轮次和流式事件
AI 管理有三个层次:ConversationId 标识对话会话,TurnId 标识一次用户指令,流式事件描述该轮中的文本、工具进度和最终状态。浏览器导航或表单填写需要回执时,Agent 在同一轮等待结果后继续,不额外伪造一条用户消息。
前端必须持续显示进度,并处理完成、失败、停止、超时和流中断。收到浏览器填写请求不等于数据已经保存:填写可停在草稿,真正持久化仍按页面的保存流程执行。服务端核对待处理动作、用户、目标路径与表单 token。
当前活动任务在 Web 进程中协调;进程重启或连接断开不会自动恢复执行。已完成的写入不会因停止任务而回滚。详细事件契约与边界见 docs/ai-management-turns.md。
15. Skills、内置工具和 MCP
Skill 是教 Agent 完成一类任务的说明,根目录 skills/<技能名>/ 自动发现,目录可用 Skills:Directory 配置。后台可以查询与启停,不提供 ZIP 导入。新增或修改 Skill 时,在 SKILL.md 中写清结构化 JSON 返回格式:字段名、类型、必填项,以及成功、空结果、失败的合法示例,并与真实工具接口一致。
无复杂业务依赖的小工具放 AITools/AITools.SimpleTools/;依赖 CMS、备份或媒体服务的工具放对应的 Orchestrator/Services/ 目录。接入时沿用已有工具注册与 RenderableToolCapture,确认模型可见的参数、工具执行权限和前端展示一致。
MCP 用于连接外部工具,也提供本系统的 /mcp 端点。它是可选能力;连接失败不应阻断普通聊天、Skills 或 LightRAG。给外部工具开放写入能力时,继续执行身份、资源归属和授权检查。
16. 插件与知识库
插件接口在 Plugin.Abstractions/,服务端管理在 Orchestrator/Services/Plugins/。内置知识库插件由 Plugins/Knowledge/Knowledge.Server/、Knowledge.Client/ 和 LightRag/ 适配层组成。插件可以有后台页面、服务、配置与工具,但仍由 Web 宿主加载。
增加插件时要同时检查服务端注册、客户端路由、权限、配置、启停行为、升级和回退。插件服务查询授权状态时注入 ILicenseStatusProvider;后台任务应先创建 DI Scope。完整开发流程和在线插件打包要求见 docs/plugin-development.md。
文档上传、分析、LightRAG 摄取和状态回写是一条异步链路。修改其中一步时,检查失败状态、重试、取消和最终状态是否一致;不要把“上传成功”误认为“知识已可检索”。
17. 图片、视频、代码工作区与备份
图片与视频生成分别在 Orchestrator/Services/ImageGeneration/、VideoGeneration/,使用各自的配置、产物存储和服务。长任务要传递取消令牌,明确等待、失败和过期清理;不要在页面里直接发起模型服务请求。
代码编辑能力在 Orchestrator/Services/CodeEditing/。它只能操作授权工作区内的文件,列出、读取、搜索和修改都应经过现有路径规则,不能信任模型给出的任意磁盘路径。
数据库备份服务在 Orchestrator/Services/Backups/,依赖 MySQL 的 mysqldump。它只覆盖数据库;恢复网站还需上传文件、模板、配置、密钥与外部数据。敏感备份文件不能作为公开静态文件提供。
18. 缓存、日志与异常
CMS 公共页面使用输出缓存;内容写入后要通过已有失效服务清理相关缓存,否则访客可能看到旧页面。新增公开读取接口时先看现有缓存策略,避免缓存管理员或会员私有内容。
错误处理沿用 ASP.NET Core 与邻近 Service 的方式:可预期的业务失败返回清晰状态,取消令牌被取消时及时结束,意外异常写日志并让统一异常处理接管。日志里不要记录 API Key、密码、Cookie、完整上传正文或不必要的个人信息。
排查问题按请求链逐层看:浏览器请求与状态码 → Controller 参数和权限 → Service 日志 → 数据库或外部服务。开发环境还可用 IDE 断点和 Single.Tests/ 复现。不要用 .Result 或 .Wait() 阻塞异步调用。
19. 测试与构建
修改后先运行最贴近改动的测试,再按影响范围构建。常用命令:
dotnet test .\Single.Tests\Single.Tests.csproj dotnet build .\Web\Web.csproj
修改 Agent.Runtime/ 中影响构建或运行的文件后,先从项目根目录执行:
.\Agent.Runtime\build.ps1
脚本会编译并更新主项目引用的 DLL;随后重新构建 Web,新实现才会进入运行程序。交付 Release 时,先执行 Agent.Runtime/build.ps1 -Configuration Release,再按相同配置发布 Web;不要把未混淆 DLL 或混淆映射作为交付物。
测试要验证行为,例如匿名访问受限、写入后读取正确、模板渲染结果或异步失败状态。仅重复实现细节的测试不能发现真正的回归。
20. 发布、升级与运维
发布时准备相同版本的 Web 文件、数据库结构、模板、上传目录和配置。站点所在进程要能写入运行数据、密钥和上传目录;反向代理应正确传递外部地址与 HTTPS 信息。先在测试环境完成初始化或增量升级,再切换正式流量。
已有网站升级顺序建议为:备份数据库和文件 → 阅读对应版本增量 SQL → 在副本验证 SQL 和程序 → 部署 Web 与静态资源 → 检查首页、后台、会员、API 和 Agent。不要在旧库执行完整安装脚本。旧文件目录或默认模板名称变化时,数据库记录和实际文件都要迁移。
后台路径变更后重启 Web,并从配置的新地址访问。多实例部署前要确认共享 Data Protection 密钥、文件存储及 Agent 活动任务协调方式;当前任务事件不支持跨进程恢复。数据库备份不能替代全站备份。
21. 常见问题速查
| 现象 | 优先检查 |
|---|---|
| 构建找不到 Runtime DLL | 配套 DLL 是否存在,构建配置与引用路径是否一致 |
| MySQL 连接失败 | 服务是否启动、端口/账号/密码、连接串与数据库名 |
| 启动提示缺表或系统 Agent 无效 | 是否导入正确的完整安装 SQL,是否连接了目标库 |
| 后台地址 404 | Admin:Path 的当前值、是否重启、是否误用规范 /admin/ 链接 |
| API 返回 401 或 403 | 是否登录、角色/菜单权限、资源归属 |
| AI 没有回复 | Provider 地址、密钥、模型、启动日志与外部服务可用性 |
| 首页提示缺模板 | 数据库模板记录、Cms:Directory 文件及默认模板来源 |
| 修改内容后前台仍是旧页面 | 写入是否成功、CMS 缓存是否失效 |
| 知识库没有检索结果 | 插件启用状态、LightRAG 连接、文档摄取最终状态 |
| 图片或文件打不开 | 上传目录、公开 URL、文件权限与媒体存储设置 |
| 备份失败 | mysqldump 是否可用、数据库权限、备份目录与超时 |
22. 从需求到代码的实践顺序
以“后台增加一个 CMS 字段”为例,按以下顺序做最不容易遗漏:
在现有管理页面找到字段所在组件与 Client Service。
找到对应 API、业务 Service、实体和 EF 映射。
定义字段的含义、默认值、可空性、校验与权限。
同步更新共享 DTO、服务、页面和状态展示。
更新空库安装 SQL,并为已有网站编写增量 SQL。
检查公开站点、AI 工具、缓存和模板是否也使用这个字段。
运行相关测试,构建 Web,手工验证保存和读取。
如果需求只影响样式,将样式写在相应组件旁的 .razor.css;如果需求涉及外部服务,先从已有 Service 与配置模式接入。保持改动紧凑,不批量格式化旧文件,也不修改 bin/、obj/ 或第三方静态资源。
23. 进一步阅读
| 文档或位置 | 适合解决的问题 |
|---|---|
README.md | 安装、启动、初次使用与常见故障 |
AGENTS.md | 开发分层、数据库、权限和单 Agent 约束 |
PLAN.md | 当前项目目标、边界和待处理事项 |
docs/ai-management-turns.md | AI 任务轮次、流式事件和浏览器回执 |
docs/plugin-development.md | 插件设计、打包、启停与扩展 |
docs/pboot-template-compatibility.md | 模板标签兼容范围 |
docs/commercial-licensing.md | 免费授权查询与执行保护 |
docs/email-and-legacy-upgrade.md | 邮件配置与旧数据升级 |
manual-import/README.md | 本手册的 Markdown 导入要求 |
本文件本身符合开发手册导入格式。导入前先创建并启用“开发手册”栏目;后台导入后先检查目录、正文、封面和 SEO,确认无误再发布。
