内容
<h1 align="center">censurado-web-brain</h1>
<p align="center">
<strong> Censurado新闻编辑室:一个由主持人运行的代理CLI和磁盘上的提示配方,驱动系统的其余部分,以及一个将Go数据/API后端(拥有所有内容数据并提供操作员管理面板)、静态网站生成器、公共网站和ComfyUI连接起来的Docker Compose。它不存储任何数据,也不运行服务器或模型:作者、来源和文章都存储在后端,CLI通过HTTP与其通信。</strong>
</p>
<p align="center">
<img src="https://img.shields.io/badge/compose-one_stack-2496ED?logo=docker&logoColor=white" alt="Docker Compose" />
<img src="https://img.shields.io/badge/AMD-Strix_Halo-ED1C24?logo=amd&logoColor=white" alt="AMD Strix Halo" />
<img src="https://img.shields.io/badge/License-MIT-blue" alt="License" />
</p>
<h2 align="center">
<a href="https://hec-ovi.github.io/censurado-web-brain/">📖 阅读交互式文档 →</a>
</h2>
<p align="center">
<a href="https://hec-ovi.github.io/censurado-web-brain/"><img src="https://img.shields.io/badge/docs-live-e01842?style=for-the-badge&logo=github&logoColor=white" alt="阅读交互式文档" /></a>
</p>
<h2 align="center">
<a href="https://elcensuradoweb.com">🌐 查看实时演示: elcensuradoweb.com →</a>
</h2>
<p align="center">
<a href="https://elcensuradoweb.com"><img src="assets/censurado-portal.gif" width="820" alt="Censurado 文章在桌面门户中:嵌入的 X 帖子位于文章上方,直接位于价格比较表上方" /></a>
</p>
<p align="center">
<a href="https://elcensuradoweb.com"><img src="assets/censurado-mobile.gif" width="240" alt="同一门户在手机上:文章提要滚动在一个狭窄的移动视口中" /></a>
</p>
<p align="center"><sub>新闻编辑室发布到公共网站,一个CDN上的完全静态门户。帖子嵌入在文章中(这里是一个 X 帖子位于一个价格表上方),整个网站响应式地适应手机。</sub></p>
---
## 这是什么
本仓库是新闻编辑室:驱动器行走的代理CLI,用于撰写和发布文章(`cli/`)、编辑提示配方(`prompts/`),维护扫描以保持语料库整洁(`newsroom/`,`censurado-brain`命令),以及一个将整个管道连接起来的`docker-compose.yml`。它不重新实现其他仓库:每个服务都从一个兄弟仓库的自己的Dockerfile(或拉取镜像)构建,本仓库拥有它们之间的连接、耦合它们的单个秘密以及代理遵循的配方。
这里没有数据库和服务器。内容(作者、来源、文章、布局、主题)仅存在于后端,CLI通过后端的HTTP API读取和写入内容。删除此仓库,后端仍然提供整个网站及其管理面板;您失去的是创作新作品的方式。
本仓库是系统运行的真实来源。如果关于端口、流程或契约的声明与此处代码和docker-compose冲突,则代码为准。请先阅读此README、 `AGENTS.md`和`docker-compose.yml`。
它期望代码仓库在旁边检查:
```
workspace/
censurado-web-brain/ <- 您在这里(新闻编辑室:CLI + 提示 + 扫描 + docker-compose)
censurado-web-backend/ <- 数据 + API:sqlite存储、发布/读取API、媒体、管理员面板
censurado-web/ <- 静态网站生成器 + 公共前端(模板/CSS/JS)
comfyui-strix-docker/ <- ComfyUI on ROCm(图像生成)
telegram-bot-skill/ <- Telegram 桥(需要 Telegram 通道)
```
代码仓库,均在 [github.com/hec-ovi](https://github.com/hec-ovi):
- [censurado-web-backend](https://github.com/hec-ovi/censurado-web-backend) - 数据 + API(sqlite存储、发布/读取API、媒体)和操作员管理面板。
- [censurado-web](https://github.com/hec-ovi/censurado-web) - 静态网站生成器 + 公共前端。
- [comfyui-strix-docker](https://github.com/hec-ovi/comfyui-strix-docker) - ComfyUI on ROCm,艺术导演的渲染后端。
- [telegram-bot-skill](https://github.com/hec-ovi/telegram-bot-skill) - Telegram 桥,将CLI代理放入您的口袋中。需要时,请使用 Telegram 通道;其设置位于自己的仓库中。
## 组件
| 服务 | 构建自 | 角色 | 主机绑定 |
|-------------|-----------------------------|-----------------------------------------------------|-----------|
| `publish` | [censurado-web-backend](https://github.com/hec-ovi/censurado-web-backend) | 编写 + 读取 API、媒体存储、唯一的 sqlite 编写者,拥有所有内容数据(作者、来源、文章、布局),并提供操作员管理面板(受保护的 SPA,涵盖文章、门户、作者、主题、来源、状态) | 127.0.0.1:8082 |
| `generate` | [censurado-web](https://github.com/hec-ovi/censurado-web) | 静态网站构建器,监视数据库并重建 | 无 |
| `site` | nginx | 提供生成的静态门户 | **8080** (`SITE_PORT`) |
| `comfyui` | [comfyui-strix-docker](https://github.com/hec-ovi/comfyui-strix-docker) | 图像生成,艺术导演的渲染后端 | 127.0.0.1:8188 |
只有 `site` 在 `0.0.0.0` 上公开。所有操作都绑定到 `127.0.0.1`;在主机或通过 SSH 隧道访问它。`publish` 镜像从 `censurado-web-backend` 构建;`generate` 运行固定的 `golang` 镜像,覆盖 `censurado-web`(生成器)和 `censurado-web-backend`(共享的 `domain`/`store` 库),并挂载只读。
## 工作流程
```
cli 代理 ──POST /articles──► publish ──► sqlite ──► generate ──► site-data ──► site
(操作员令牌, (唯一 (监视数据库, (公共)
3 个范围) 编写者) 重建)
```
<p align="center">
<a href="https://hec-ovi.github.io/censurado-web-brain/"><img src="assets/censurado-workflows.gif" width="900" alt="交互式新闻编辑室文档:概览图、编辑工作流管道、运行模式、多代理作者和完整架构" /></a>
</p>
<p align="center"><sub>交互式工作流图(<a href="https://hec-ovi.github.io/censurado-web-brain/">实时文档</a>):概览图、编辑管道(研究 → 大纲 → 草稿 → 评估 → 事实核查 → 最终确定 → 图像 → 预览)、运行模式、多代理作者和完整架构(主机 Telegram 通道、24/7 服务循环、CDN)。</sub></p>
CLI 代理为每个作品撰写并发布,通过发布 API,免配额。指向一个 CLI 代理(Claude、Codex、Hermes、OpenClaw 或任何等效代理)到 **[cli/SKILL.md](cli/SKILL.md)**,它一步一步地遍历新闻编辑室工作流(`python3 cli/censurado.py step`):选择模式,从后端加载作者的声音,研究和交叉来源,草拟,通过编辑门控,然后在发布前显示草稿并询问。一步门控一次服务一个节点,因此代理无法跳过门控或一键式制作作品;节点文本和步骤顺序位于此仓库的 git 跟踪的 `prompts/workflow/` 文件中。它在批准后发布。无需模型预算,过程中无需推理。一个作品也可以在上线后进行编辑(操作员令牌带有 `admin:write`),并且可以通过同一代理首先填充空作者数据库。
## 使用步骤
先决条件:Docker + Compose v2,代码仓库作为兄弟检查(见上),磁盘上的 ComfyUI 模型,以及对于 `comfyui`,AMD Strix Halo 盒(gfx1151)上的最新 amdgpu 内核。堆栈的其余部分是纯 HTTP,无需 GPU。 使用 `./run.sh <cmd>` 运行堆栈(仅需 bash + docker,无需 `make`);`Makefile` 镜像相同的目标,适用于有 `make` 的人,原始 `docker compose` 形式也适用。
**1. 配置。** 复制模板并编辑非机密的机器值(GPU 组 ID):
```bash
cp .env.example .env # 编辑 RENDER_GID, VIDEO_GID, COMFYUI_MODELS_PATH
```
**2. 引导秘密。** 这会生成操作员发布密钥(范围 `articles:write`、`articles:publish-any` 和 `admin:write`),将其写入 `.env`,将令牌哈希种子到 `keys.json`,并修复卷权限。它还会配置仅限本地访问的操作员面板登录(默认令牌:`admin`)并写入匹配的哈希:
```bash
./bootstrap.sh
```
**3. 启动堆栈。** 快速通道(后端 API + 生成器 + 公共网站,无 GPU)是默认的。第一次运行会构建镜像并下载 Go 模块图,因此速度较慢;后续运行速度较快:
```bash
./run.sh up # 快速通道:发布 + 生成 + 站点(无 comfyui),分离
docker compose ps # 所有服务均已启动;`generate` 可能需要一分钟
```
`./run.sh up` 在后台运行;添加 `--console` 即可查看日志: `./run.sh up --console`。在全新检出时,步骤 1 至 3 合并为一个命令: `./run.sh start` 会写入 `.env`,如果缺少密钥则生成密钥,然后启动快速通道。(使用 `make`:`make up`、`make start`。)
**想要英雄图片?** `comfyui` 很重,仅支持 GPU,因此它是可选的,永远不会阻塞快速通道。在 AMD Strix Halo 盒上,添加它:
```bash
./run.sh up-gpu # 整个堆栈,包括 comfyui(或 `./run.sh comfyui` 以便稍后添加)
```
因此,默认情况下,您将获得完整的 CLI 发布通道(编写、审查、编辑、服务),无需 GPU;`comfyui` 只添加每个文章的图像生成。
**4. 检查它是否存活。**
```bash
curl -s http://localhost:8082/healthz # 发布 API -> ok
```
在 http://localhost:8082 打开操作员面板(使用步骤 2 中的面板令牌登录)。后端提供它,它直接管理后端的内容,因此它在只有后端运行时也能工作。公共门户(默认情况下为 http://localhost:8080,`.env` 中的 `SITE_PORT`)在第一个文章存在之前是空的。
**5. 获取文章。** CLI 代理通过发布 API 免配额编写并发布文章。将 CLI 代理(Claude、Codex、Hermes、OpenClaw 或任何等效代理)指向 **[cli/SKILL.md](cli/SKILL.md)**,它将一步一步地遍历新闻编辑室工作流(`python3 cli/censurado.py step`):选择模式,从后端加载作者的声音,研究和交叉来源,草拟,通过编辑门控,然后在发布前显示草稿并询问。一步门控一次服务一个节点,因此代理无法跳过门控或一键式制作作品;节点文本和步骤顺序位于此仓库的 git 跟踪的 `prompts/workflow/` 文件中。它在批准后发布。无需模型预算,过程中无需推理。一个作品也可以在上线后进行编辑(操作员令牌带有 `admin:write`),并且可以通过同一代理首先填充空作者数据库。
**6. 在门户上查看。** `generate` 服务监视数据库,并在发布后约 2 秒内重建静态网站,因此只需刷新门户即可。要强制一次性重建:`make generate`。
**7. 操作。** 面板(由后端在 8082 上提供)是单个操作员界面:它列出和编辑文章,策划门户,创建和编辑作者(姓名、声音/样式、性别、主题、附加来源),派生主题,并管理来源,所有这些都针对后端。 它直接与后端通信,并绑定到 `127.0.0.1`。
**8. 关闭。** `docker compose down` 停止所有服务,但保留数据(数据库和媒体是主机绑定挂载在 `${CENSURADO_DATA_DIR:-./data}` 下,在此仓库中为 `./data/db` 和 `./data/media`,被 gitignore)。要删除命名卷:`docker compose down -v`,然后 `docker compose run --rm init-perms` 即可在下一次 `up` 之前使站点卷可写。
`bootstrap.sh` 可以安全地重新运行:它会轮换操作员密钥(旧操作员条目从 `keys.json` 中删除,因此旧令牌停止工作),并保留现有的面板登录(使用 `./mint-panel-login.sh` 轮换该登录)。
## 通过 MCP 驱动
步骤 5 假设一个可以运行 `python3 cli/censurado.py ...` 的代理。如果您的代理无法运行 shell 命令,或者您希望它拥有门户而无需其他功能,请将其连接到 `mcp/` 中的 MCP 服务器:
```bash
claude mcp add censurado -- python3 /path/to/censurado-web-brain/mcp/src/server.py
```
任何 stdio MCP 客户端都有效。它通过相同的 CLI 动词公开 32 个工具(文章、首页布局、推荐的轨道、作者及其语音提示和肖像、媒体和英雄渲染、编辑配方和门控行走,以及公共部署),因此无需分叉:MCP 代理和终端操作员通过相同的代码写入。
服务器必须在具有此仓库及其 `.env` 的主机上运行,因为操作员令牌位于此处;令牌永远不会跨越网络。代理正常运行所需的一切(本地与公共规则、布局模型、合规线)都随连接的指令一起传输,因此它不需要仓库访问权限,也不需要技能文件。
以 `doctor` 工具开始任何会话。它检查配置和操作员令牌、每个服务、身份验证的内容读取、图像通道、媒体存储、部署通道和编辑配方,然后打印判决和下一步。`deep: true` 更进一步,实际渲染图像,通过媒体存储往返探测文件,并检查部署登录。详细信息见 [mcp/README.md](mcp/README.md) 和 [mcp/CONTRACT.md](mcp/CONTRACT.md) 中的契约。
## 部署到实时站点
`localhost:8080` 上的门户是本地数据库的静态快照。要将其推送到实时站点(elcensuradoweb.com,在 Cloudflare Pages 上):
```bash
wrangler login # 一次(OAuth)
# 在 .env 中设置 CLOUDFLARE_ACCOUNT_ID(您的账户 ID;参见 .env.example)
make deploy # 或 ./deploy/deploy-cdn.sh
```
`deploy/deploy-cdn.sh` 构建一个新鲜的快照,大小为生产页面,复制媒体,写入根重定向和缓存头,并推送到 Pages。缓存策略(资产被重新获取(无存储),媒体是不可变的)记录在 [deploy/CACHING.md](deploy/CACHING.md) 中。
## 从实时网站重建语料库
数据库中存储了所有内容,并且数据库被git忽略,因此一旦`data/`目录被清空,语料库就会丢失。公共网站是一个静态快照,因此`elcensuradoweb.com`(Cloudflare Pages)是文章、作者和图片的最后一个幸存副本。样式(模板、CSS、视频)存在于`censurado-web`中,而不是数据库中,因此它总是在代码中恢复。重建过程中没有提交的工具;这是一个手动过程。总体流程:
1. **启动服务栈。** `./run.sh up`(快速通道;`comfyui` 除非您添加 `up-gpu` 否则保持关闭)。数据库启动时为空,门户返回404,直到第一篇文章存在。
2. **拉取已发布的內容。** 直播页面上的所有内容都是可用的:
- 从子站点地图(`/sitemaps/articles-YYYY-MM.xml`)枚举每个文章的URL。
- 读取每个文章页面:标题、日期、作者句柄和章节来自`NewsArticle` JSON-LD;摘要是`.article-standfirst`段落(摘要仅在列表卡片上渲染为`.card-subtitle`,不在文章页面上);主题是`topic-link`芯片;英雄图片是JSON-LD `image`。将正文HTML转换为markdown。
- 反转嵌入。生成器将它们作为正文标记(`{{video:<id>}}`、`{{tweet:<id>}}`、`{{relacionado:<slug>}}`)进行标记,而HTML到markdown的转换会删除渲染的iframe或卡片,因此从渲染的HTML中提取YouTube ID、推文快照(姓名、句柄、头像、文本、URL)和相关链接,然后重写标记。推文还需要将其快照存储在文章的`metadata.tweets[]`中;相关标记存储目标的本地slug,它与实时slug不同。
- 作者来自`/author/<handle>/`和`/about/`页面:姓名、简介、头像、性别和领域。
- 图片:通过字节重新上传每个`/media/<sha>`。存储密钥按sha256,因此URL稳定,每个正文、英雄和头像引用都保持解析。
3. **重新发布。** 通过操作员API(先是`/media`,然后是`/authors`,然后是`/articles`)或在`:8082`的管理面板中粘贴。重新发布相同的标题+正文会重现相同的內容哈希,因此永久链接匹配。现有文章通过`PUT /articles/{slug}`更新;纯粹的重发布是一个幂等重试,跳过更新。
4. **修复日期。** 文章页面显示`created_at`,后端在插入时(导入时间)进行标记,而不是`published_at`。在sqlite中设置它们相等,写入器停止以释放WAL:
```bash
docker compose stop publish generate
docker run --rm --user 65532:65532 -v "$PWD/data/db:/db" python:3-slim \
python3 -c "import sqlite3; c=sqlite3.connect('/db/censurado.db'); \
c.execute('UPDATE articles SET created_at = published_at'); c.commit(); \
c.execute('PRAGMA wal_checkpoint(TRUNCATE)'); c.commit()"
docker compose start publish generate
```
5. **重建合成部分。** 有三件事从未出现在公共页面上,因此无法抓取,需要手动编写每个作者(通过面板的作者+来源,或`POST /authors`和`POST /sources`):
- **样式卡片**(`style`):作者的私人声音指南,精简和注册他们写作的风格(左派、自由主义者、阴谋论者、AI研究人员等)。这使得每个角色听起来像他们自己。
- **`who_i_am`**(`metadata.who_i_am`):工作流在草稿时嵌入的私人第一人称简介。
- **来源注册表**:每个作者阅读的媒体 outlet,每个媒体 outlet都有一个`lean`(左派、中立、右派)和一个 feed,附加到作者身上(左派媒体 outlet对应左派作者等)。
这些是作者资料:公共简介、头像、性别和领域从站点恢复;样式卡片、`who_i_am`和附加来源由您定义。
## 无GPU盒或无Docker运行
服务栈沿GPU线路干净地分开:
- **无GPU(无Strix Halo)。** 除`comfyui`外,所有内容都在任何带有Docker的机器上运行,这是默认设置:`./run.sh up`(或`./run.sh start`)启动快速写入/审查/发布/服务通道,从不触及GPU。您只会丢失每篇文章的图像生成。发布纯文本内容,或通过`POST /media`附加其他地方生成的图像。
- **无ComfyUI。** 跳过`comfyui`并发布没有英雄图像的内容(或上传一个);当ComfyUI不存在时,将跳过每篇文章的图像步骤。
- **完全无Docker。** 您无法在本地运行服务栈。在一台有Docker的机器上运行它,并通过隧道访问API,或在云中托管后端并将您的本地CLI指向它。
## 配置
所有配置都存放在`.env`中(参见`.env.example`)。非机密的默认值针对参考Strix Halo盒(渲染GID 990,视频GID 44);将`COMFYUI_MODELS_PATH`指向您的ComfyUI模型目录,并为您的机器调整其余部分。机密字段由`bootstrap.sh`填充,不应手动编辑。`.env`和`keys.json`被git忽略。维护扫描读取几个可选的`NEWSROOM_*`变量(后端基本URL和编辑密钥),两者都有默认的工作值;参见`.env.example`。
## 故意省略的内容
- `censurado-web-backend`附带的用于生产的litestream备份边车。如果您想要离站备份,请从其自己的compose中添加;此compose保留运行系统。
- 操作端口前面的TLS和身份验证。它们绑定到`127.0.0.1`。在公开它们之前,请在前面放置身份验证层。
## 待办功能(路线图)
尚未构建,捕获在这里,以便我们可以选择它们。下面没有一个阻止当前流水线。
- **分析/BI仪表盘**(后端面板)。一个表面用于增长:一个最受欢迎的主题图表(过滤总数,构建以扩展到数千个主题),作者按点赞排名,文章最少的作者,以及统计/增长建模。注意:作者点赞需要一个后端不持有的反应数据源(反应存在于下游Cloudflare Pages反应函数中)。
- **Rebel Forge集成。** 集成Rebel Forge功能(一个单独的GitHub仓库)。待处理,范围在选择时定义。
- **服务循环后续。** 24/7循环本身已经发货(`./run.sh serve`,见下文)。仍然开放:上游贡献的其余CLI适配器(直到它们落地,桥梁通道在`claude-code`上结算,而链逻辑已经遍历配置中列出的内容),通过相同的备用链路由`automation/auto-batch.sh`,在调用24/7之前进行多天的诱导故障浸泡,然后是一个轻量级的电子邮件触发器(Cloudflare Email Worker发布到一个小型监听器)用于按需运行。 n8n和类似的节点图编排器被丢弃:太重,并且容器化后无法访问主机CLI。
## 测试
```bash
make install # 一次:创建venv,安装软件包 + 开发工具(uv)
make test # 整个套件(或:.venv/bin/pytest tests -q)
```
JS通道运行一次`npm install`,然后`npm test`:服务循环端到端对抗假二进制(脚本桥和脚本代理金丝雀:认证/配额降级,无责重启,当仅桥梁死亡时,无知适配器,链条下降警报和复兴,瞬态阈值)以及Pages反应函数。
Python套件在本地运行,无CI。它涵盖了作者CLI(推文/真相快照映射,软故障错误处理,本地步骤门控及其工件强制执行),维护扫描(状态探测,规范合同传递,主题清理,嵌入重新检查),编辑提示漂移防护(参数保持客户端填充占位符,防滑规则存活,每个节点在磁盘上存在),文章合同镜像(哈希,slug,章节,模式漂移),技能包(解析器路由仅到存在子技能),以及通过`docker compose config`的compose布线(真正的解析器:服务集无配置平面服务,`site`仅公共端口,`generate`驻留观察器,db和媒体在持久绑定挂载上)。不构建镜像,不需要GPU。
## 布局
```
cli/censurado.py 代理CLI(发布/编辑,媒体,图像,推文,作者,来源,步骤)
cli/SKILL.md 控制技能(解析器):将CLI代理路由到正确的子技能
cli/skills/ 胖子技能(写文章,每日批次,作者,来源等)
cli/workflow/ 强制数字地板/上限(parameters.json)节点填充的流程
cli/templates/ ComfyUI渲染图(flux2_klein)
prompts/ 编辑配方:流程步骤门控节点 + 清单,角色 + 编辑
newsroom/ 维护CLI(censurado-brain):状态探测 + 规范合同传递 + 主题清理 + 嵌入重新检查
docker-compose.yml 整个栈(服务,网络,卷,端口)
AGENTS.md 代理导向地图:跨服务合同和指针
deploy/ deploy-cdn.sh(推送到Cloudflare Pages)+ CACHING.md(缓存策略)
.env.example 配置模板(复制到.env)
bootstrap.sh 铸造机密,播种keys.json,填充.env,修复卷权限
mint-panel-login.sh 旋转或设置操作员面板登录令牌
run.sh 无依赖栈运行器(bash + docker):启动/升级/降级/部署
Makefile 可选`make`镜像运行.sh,加上python通道(安装/测试/ lint)
nginx/site.conf 公共静态站点服务器(根重定向到/latest/)
functions/ Cloudflare Pages文章反应函数(点赞/踩 + D1)
automation/ auto-batch.sh(一个无人值守的批次)+ supervisor/(24/7服务循环 + 需求.md)
+ scheduler/(独立定时提示运行器,合同隔离,尚未连接)
tests/ 本地套件(CLI,扫描,提示漂移,合同,组合布线)
```
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器