Open-Assistant REST Backend 开发实战:从本地数据库搭建到数据导出的完整指南
2026/9/19 20:14:38 网站建设 项目流程

Open-Assistant REST Backend 开发实战:从本地数据库搭建到数据导出的完整指南

【免费下载链接】Open-AssistantOpenAssistant is a chat-based assistant that understands tasks, can interact with third-party systems, and retrieve information dynamically to do so.项目地址: https://gitcode.com/gh_mirrors/op/Open-Assistant

导读

本文以 Open-Assistant 仓库的 backend/README.md 为骨架,系统讲解其 REST 后端的完整开发流程:如何用 Docker Compose 拉起本地 PostgreSQL、安装 Python 依赖并以热重载模式启动 FastAPI 服务、通过.env配置数据库与 Redis、借助 Alembic 管理数据库迁移、启动 Celery Worker 处理毒性检测与特征提取等异步任务,以及用export.py把对话消息树导出为可用于模型训练的数据集。读完本文,你将能独立搭建一套可运行的 Open-Assistant 后端开发环境,并掌握其配置体系与数据导出管线的底层原理。

一、后端开发环境搭建

Open-Assistant 的 REST 后端(位于 backend/ 目录)是一个基于 FastAPI 的 Python 服务,负责任务分发、消息树管理、用户统计与数据导出。下面从零开始搭建本地开发环境。

1.1 启动本地数据库(Docker Compose)

在仓库根目录执行以下命令即可启动一套带backend-devprofile 的依赖服务:

docker compose --profile backend-dev up --build --attach-dependencies

该命令的核心逻辑定义在根目录 docker-compose.yaml 中。与后端开发相关的服务包括:

  • db:PostgreSQL 数据库,使用ghcr.io/laion-ai/open-assistant/oasst-postgres镜像,环境变量为POSTGRES_USER=postgresPOSTGRES_PASSWORD=postgresPOSTGRES_DB=postgres,映射宿主端口5432:5432,并通过pg_isready做健康检查(docker-compose.yaml)。
  • redis:用于缓存与限流,映射端口6379:6379,加载仓库根目录的 redis.conf(docker-compose.yaml)。
  • redis-insights:Redis 可视化监控面板,映射端口8001
  • adminer:轻量级数据库管理工具,映射端口8089:8080,可手动检查 web 与 backend 两套数据库。

注意(Apple Silicon / M1 芯片):若在 MacOS M1 上运行,需要显式指定平台架构:DB_PLATFORM=linux/x86_64 docker compose ...

后端的默认配置已经按localhost:5432连接数据库(见 config.py 中POSTGRES_HOST=localhostPOSTGRES_PORT=5432等默认值),因此数据库启动后无需额外改动即可连通。

1.2 Python 版本与虚拟环境

后端要求Python 3.10,仓库根目录的.python-version文件声明了版本,推荐使用pyenv管理,进入仓库目录后 pyenv 会自动识别并切换到对应版本。

1.3 安装 Python 依赖

按顺序执行以下三步安装全部依赖:

pip install -r backend/requirements.txt pip install -e ./oasst-shared/. pip install -e ./oasst-data/.
  • backend/requirements.txt是后端主依赖(FastAPI、SQLModel、Celery、Redis 等);
  • oasst-shared以可编辑模式安装,提供跨模块共享的协议 schema 与异常定义(oasst-shared/);
  • oasst-data以可编辑模式安装,提供导出数据格式(ExportMessageTreeLabelAvgValue等)与读写工具(oasst-data/)。

安装完成后,运行:

./scripts/backend-development/run-local.sh

后端服务即会在http://localhost:8080启动。该脚本实际执行的是(run-local.sh):

uvicorn main:app --reload --port 8080 --host 0.0.0.0

--reload开启热重载,任何代码改动都会自动重启服务,非常适合开发调试。

1.4 本地开发脚本族

scripts/backend-development/ 目录提供了一整套开发辅助脚本:

脚本作用
run-local.sh以热重载模式启动后端(默认跳过毒性/嵌入计算,传hf参数则启用真实 HuggingFace 调用)
run-local-no-limit.sh关闭限流后启动本地后端
start-docker.sh等价于docker compose --profile backend-dev up --build --attach-dependencies
start-worker.sh在 backend 目录下启动 Celery worker(含 Beat 调度器)
stop-worker.sh停止 Celery worker
start-mock-server.sh/stop-mock-server.sh启动/停止 mock 服务

二、REST 服务器配置:.env与核心环境变量

2.1 生成.env配置文件

复制 backend/.env.example 为.env并按要求修改:

# backend/.env.example 的内容 HUGGING_FACE_API_KEY=HF API KEY DATABASE_URI="postgresql://<username>:<password>@<host>/<database_name>" BACKEND_CORS_ORIGINS=["http://localhost", "http://localhost:4200", "http://localhost:3000", "http://localhost:8080", ...] REDIS_HOST=localhost REDIS_PORT=6379

其中DATABASE_URI必须设置为本地数据库地址,例如postgresql://postgres:postgres@localhost:5432/postgres

2.2 环境变量的底层解析逻辑

所有环境变量最终由 backend/oasst_backend/config.py 中的Settings(BaseSettings)统一解析(基于 pydantic 的BaseSettings,读取当前目录下的.env文件,大小写不敏感)。几个关键点:

  • 数据库连接:若未显式设置DATABASE_URI,pydantic validator 会根据POSTGRES_HOSTPOSTGRES_PORTPOSTGRES_USERPOSTGRES_PASSWORDPOSTGRES_DB自动拼接出postgresql://连接串(config.py)。
  • CORS:既支持BACKEND_CORS_ORIGINS列表,也支持用BACKEND_CORS_ORIGINS_CSV以逗号分隔字符串传入(config.py)。
  • Redis 与限流RATE_LIMIT(默认True)、REDIS_HOSTREDIS_PORT控制 FastAPI 限流器。服务启动时会连接 Redis 并初始化FastAPILimiter(main.py)。
  • DEBUG 系列开关DEBUG_SKIP_EMBEDDING_COMPUTATIONDEBUG_SKIP_TOXICITY_CALCULATION控制是否跳过 HuggingFace 的嵌入向量与毒性计算(本地无 API Key 时置True可加速);DEBUG_USE_SEED_DATA会在启动时把backend/test_data/realistic/realistic_seed_data.json的种子数据灌入数据库,方便本地联调(main.py)。
  • 认证相关AUTH_*系列字段用于解密前端 NextAuth.js 生成的 JWT,必须与website的认证配置保持一致;OFFICIAL_WEB_API_KEY用于启动时自动创建官方 Web API 客户端(main.py)。
  • Prometheus 指标ENABLE_PROM_METRICS(默认True)会在/metrics暴露监控指标(main.py)。

2.3 主服务启动入口

后端入口为 backend/main.py。除了uvicorn启动,它还提供了几个实用 CLI 参数(main.py):

python main.py --host 0.0.0.0 --port 8080 # 常规启动 python main.py --print-openapi-schema # 将 OpenAPI schema 打印到 stdout python main.py --retry-scoring # 重试打分失败的消息树后退出

服务启动时会执行一系列 startup 事件:自动升级 Alembic 到最新版本(UPDATE_ALEMBIC开启时)、创建官方 Web API 客户端、初始化 Prometheus 与限流器、检查/恢复消息树状态(TreeManager.ensure_tree_states())、按周期更新日/周/月/总排行榜缓存统计、每小时清理过期任务等(main.py)。

三、Alembic:数据库迁移管理

修改 SQL 模型(位于 backend/oasst_backend/models/)后,需要在backend目录下生成迁移脚本:

cd backend alembic revision --autogenerate -m "描述你做的改动"

生成后务必人工检查并编辑新创建的迁移文件,再执行alembic upgrade head应用到数据库。仓库中已有的迁移脚本全部位于 backend/alembic/versions/,例如add_message_revisions.pyadd_text_search.py等,可作为编写迁移的参考范本。后端启动时若UPDATE_ALEMBIC=True(默认开启),会自动把数据库升级到head,避免手工执行(main.py)。

四、API 文档:本地 docs 与 OpenAPI 导出

后端启动后,默认 API 文档地址为:

http://localhost:8080/docs

(Swagger UI,由 FastAPI 自动生成,openapi_url/api/v1/openapi.json,见 main.py)。

如果需要把 OpenAPI 规范同步到仓库docs/目录,以便其他人无需搭建环境即可查看 API 定义,可以执行:

wget localhost:8080/api/v1/openapi.json -O docs/docs/api/backend-openapi.json

导出的文件即 docs/docs/api/backend-openapi.json。该文件预期由test-api-contract.yamlCI 工作流自动更新(README 中标注为 TODO)。

五、Celery Worker:异步任务与周期调度

5.1 职责划分

Celery 在后端体系中承担两类工作:

  • 异步 HuggingFace 调用:如消息毒性检测(toxicity)与嵌入特征提取(feature extraction / embedding computation);
  • 周期任务(Celery Beat):如用户连续签到天数(user streak)重置。

Celery 应用定义在 backend/oasst_backend/celery_worker.py,broker 与 result backend 默认均为redis://localhost:6379/0,可用CELERY_BROKER_URL/CELERY_RESULT_BACKEND覆盖。内置的 beat 调度表(celery_worker.py):

任务名调度周期说明
periodic_user_streak_reset每 4 小时重置用户连续签到
update_search_vectors每 20 分钟批量更新全文搜索向量,batch_size=1000

周期任务的具体实现位于 backend/oasst_backend/scheduled_tasks.py(通过include=["oasst_backend.scheduled_tasks"]引入)。

5.2 本地运行 Worker

按 README 的指引:

  1. 在 backend/oasst_backend/config.py 中把HUGGING_FACE_API_KEY设置为正确的 API Key;
  2. 在 scripts/backend-development/run-local.sh 中确认:
export DEBUG_SKIP_TOXICITY_CALCULATION=False export DEBUG_SKIP_EMBEDDING_COMPUTATION=False
  1. backend目录运行 worker 启动脚本(start-worker.sh):
./scripts/backend-development/start-worker.sh # 等价于: celery -A oasst_backend.celery_worker worker -l INFO -B

其中-B表示把 Beat 调度器内嵌进 worker 进程。

  1. 查看日志:
tail -f celery.log tail -f celery.beat.log

5.3 CI / Docker 环境运行 Worker

在 CI(或 docker-compose 环境)中:

  • 在根目录 docker-compose.yaml 里设置DEBUG_SKIP_TOXICITY_CALCULATION=FalseDEBUG_SKIP_EMBEDDING_COMPUTATION=False(backend 服务已默认如此配置,见 docker-compose.yaml);
  • 会创建两个 Docker 实例:backend-workercelery -A oasst_backend.celery_worker worker -l info -E)与backend-worker-beatcelery -A oasst_backend.celery_worker beat -l INFO),两者均依赖 db 与 redis 健康检查(docker-compose.yaml);
  • 日志与普通 Docker 容器一样通过docker logs查看。

六、数据导出:export.py详解

6.1 基本用法

数据在数据库中积累后,可用 backend/export.py 导出。它直接连接数据库(复用后端的.env配置),因此需要与后端相同的 Python 环境。

导出所有通过评审的英文消息树:

python export.py --lang en --export-file output.jsonl

完整选项列表可用python export.py --help查看。

6.2 参数语义与源码级说明

结合 export.py 的 argparse 定义,各参数含义如下:

参数默认行为说明
--export-file输出到 STDOUT导出文件名;文件名含.gz时自动启用 gzip 压缩
--include-deleted排除包含已删除消息
--deleted-only仅导出已删除消息(隐含--include-deleted
--include-spam排除包含未评审或评审为负的消息(review_result不限定为 True)
--spam-only仅导出评审为负的消息(隐含--include-spam
--include-synthetic排除包含合成消息
--synthetic-only仅导出合成消息
--user <UUID>仅导出指定用户参与的消息(与--state互斥)
--state <state>ready_for_export消息树状态过滤:allprompt_lottery_waitinggrowingready_for_exportaborted_low_gradehalted_by_moderatorbacklog_ranking
--lang <code>全部按 BCP 47 语言码过滤(如en
--prompts-only仅导出初始 prompt 消息列表
--export-labels附带消息的平均文本标签值(含各标签的 count)
--export-events附带用户的 emoji、评分(rating)、排序(ranking)事件
--limit <N>全部最多导出的消息树数量
--anonymizer-seed <int>不匿名匿名化随机种子;不指定则不做匿名化

几个值得注意的实现细节:

  • 默认过滤链:若不传--state,默认只导出READY_FOR_EXPORT状态的树;review_result默认限定为True(即必须通过评审),--include-spam会放宽该限制(export.py)。
  • 匿名化:传入--anonymizer-seed时使用oasst_shared.utils.Anonymizer对用户 ID 等敏感信息做确定性匿名化;不传则打印警告并原样导出(export.py)。
  • 导出格式:正常树导出时使用tree_export.build_export_tree组装成ExportMessageTree结构(消息树 + 标签均值 + 事件),并使用oasst_data的 writer 写入文件(export.py);按用户过滤或过滤不完整树时则扁平化为消息列表导出。
  • 数据来源:导出时对MessageMessageTreeStateMessageEmojiMessageReactionTextLabels等表进行聚合查询,按TextLabel枚举逐一计算avg(labels[l])count(labels[l])(export.py)。

6.3 常见问题:"Why isn't my export working?"

README 指出最常见的原因是消息尚未通过评审流程,导致消息树未达到可导出状态。此时可加上--include-spam参数,将review_result限制放宽为不限,从而导出尚未通过评审的树(export.py)。

七、总结

Open-Assistant 的 REST 后端是一个典型的"FastAPI + SQLModel + PostgreSQL + Redis + Celery"技术栈:

  1. 环境就绪docker compose --profile backend-dev up --build --attach-dependencies一条命令拉起数据库与 Redis;
  2. 服务启动pip install三个依赖后运行 run-local.sh,uvicorn热重载模式监听8080
  3. 配置驱动:所有行为(数据库、Redis、限流、DEBUG 开关、种子数据、Prometheus)均由.env环境变量经 config.py 统一驱动;
  4. 迁移与文档:Alembic 管理 schema 演进(启动时自动升级),/docs提供交互式 API 文档,wget可同步 OpenAPI 规范到 docs/docs/api/backend-openapi.json;
  5. 异步任务:Celery Worker + Beat 处理毒性检测、嵌入计算与周期任务,本地与 CI/Docker 两种运行模式均有配套脚本;
  6. 数据出口:export.py 提供高度可配置的消息树导出能力(语言、状态、评审结果、匿名化、压缩等),是 Open-Assistant 数据飞轮的关键一环。

按照上述步骤,你即可获得一套完整的本地开发环境,并深入理解该后端从数据采集到数据集导出的全链路设计。

【免费下载链接】Open-AssistantOpenAssistant is a chat-based assistant that understands tasks, can interact with third-party systems, and retrieve information dynamically to do so.项目地址: https://gitcode.com/gh_mirrors/op/Open-Assistant

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询