# https://github.com/apache/answer 项目说明书

生成时间：2026-06-23 22:10:02 UTC

## 目录

- [项目概览与系统架构 (Project Overview & System Architecture)](#page-1)
- [核心问答与用户体系 (Core Q&A and User System)](#page-2)
- [AI 能力、搜索与插件扩展 (AI, Search & Plugin Extensibility)](#page-3)
- [部署、国际化与运维 (Deployment, Internationalization & Operations)](#page-4)

<a id='page-1'></a>

## 项目概览与系统架构 (Project Overview & System Architecture)

### 相关页面

相关主题：[核心问答与用户体系 (Core Q&A and User System)](#page-2), [AI 能力、搜索与插件扩展 (AI, Search & Plugin Extensibility)](#page-3), [部署、国际化与运维 (Deployment, Internationalization & Operations)](#page-4)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/apache/answer/blob/main/README.md)
- [charts/README.md](https://github.com/apache/answer/blob/main/charts/README.md)
- [internal/base/server/http.go](https://github.com/apache/answer/blob/main/internal/base/server/http.go)
- [internal/cli/build.go](https://github.com/apache/answer/blob/main/internal/cli/build.go)
- [ui/package.json](https://github.com/apache/answer/blob/main/ui/package.json)
- [ui/src/utils/pluginKit/interface.ts](https://github.com/apache/answer/blob/main/ui/src/utils/pluginKit/interface.ts)
- [ui/src/utils/pluginKit/index.ts](https://github.com/apache/answer/blob/main/ui/src/utils/pluginKit/index.ts)
- [ui/src/utils/pluginKit/utils.ts](https://github.com/apache/answer/blob/main/ui/src/utils/pluginKit/utils.ts)
- [ui/src/utils/request.ts](https://github.com/apache/answer/blob/main/ui/src/utils/request.ts)
- [ui/src/utils/requestAi.ts](https://github.com/apache/answer/blob/main/ui/src/utils/requestAi.ts)
- [ui/src/components/SchemaForm/README.md](https://github.com/apache/answer/blob/main/ui/src/components/SchemaForm/README.md)
- [ui/src/components/Editor/utils/index.ts](https://github.com/apache/answer/blob/main/ui/src/components/Editor/utils/index.ts)
- [ui/src/utils/index.ts](https://github.com/apache/answer/blob/main/ui/src/utils/index.ts)
- [ui/src/utils/floppyNavigation.ts](https://github.com/apache/answer/blob/main/ui/src/utils/floppyNavigation.ts)
</details>

# 项目概览与系统架构 (Project Overview & System Architecture)

## 1. 项目定位与目标

Apache Answer 是一个面向任何规模团队构建的问答（Q&A）平台软件，可以作为社区论坛、帮助中心或知识管理平台来使用 资料来源：[README.md:1-13]()。项目由 Apache 软件基金会托管，采用 Go 与 React 双语言开发，遵循 Apache License 2.0 协议 资料来源：[README.md:9-15]()。

在社区中，Answer 常被用于：
- 内部团队的 Q&A 平台：当用户提出问题并打上对应团队的标签时，团队成员会收到通知（参见社区 Issue #419 关于新问题邮件通知的诉求）。
- 开源社区运营：社区讨论过使用数字化看板量化贡献并激励参与者（参见社区 Issue #15）。
- 通用知识共享：投票、评论、表情互动（参见社区 Issue #883 关于给问题/答案增加 reaction 表情的讨论）。

## 2. 技术栈与代码组织

项目后端使用 Go（`badge/language-go-blue.svg`），前端使用 React（`badge/language-react-blue.svg`），整体打包为单一可执行文件并通过 Docker 镜像分发 资料来源：[README.md:9-15, 27-28]()。前端部分使用 `pnpm@9.7.0` 作为包管理器，要求 Node.js >= 20 资料来源：[ui/package.json:42-46]()。

部署上 Answer 提供三种主要形态：

| 形态 | 命令 / 入口 | 说明 |
| ---- | ---- | ---- |
| Docker 容器 | `docker run -d -p 9080:80 -v answer-data:/data --name answer apache/answer:2.0.1` | 默认端口 80 映射到主机 9080，数据卷为 `/data` 资料来源：[README.md:27-28]() |
| Kubernetes Helm Chart | `apache/answer` chart | 默认 `replicaCount=1`、镜像 tag 为 `latest`、默认 `LOG_LEVEL=INFO` 资料来源：[charts/README.md:5-20]() |
| 自定义构建 | `internal/cli/build.go` 中的 `formatPlugins` 解析插件描述 | 支持 `name@version=/local/path` 形式的插件本地覆盖 资料来源：[internal/cli/build.go]() |

## 3. 服务端架构

后端使用 Gin 作为 HTTP 框架，提供健康检查、静态文件、API、Swagger、UI 视图与插件 API 多个分组路由 资料来源：[internal/base/server/http.go:46-71]()。`/healthz` 用于存活探针；`/chat/completions` 路径在 Brotli 压缩之前被显式放行，以支持流式 AI 响应 资料来源：[internal/base/server/http.go:33-39]()。

模板系统既支持通过 `ANSWER_TEMPLATE_PATH` 环境变量加载外部模板，也支持使用编译期嵌入的 `ui.Template` 资源 资料来源：[internal/base/server/http.go:40-49]()。整体请求处理流如下：

```mermaid
flowchart LR
  Client[浏览器 / 客户端] -->|HTTP| Gin[Gin Engine]
  Gin -->|Accept-Language| Lang[ExtractAndSetAcceptLanguage]
  Gin -->|条件压缩| Brotli[Brotli 压缩]
  Gin -->|路由分发| API[AnswerAPIRouter / SwaggerRouter / StaticRouter]
  Gin -->|页面渲染| View[ViewRouter + 模板]
  API -->|业务调用| Service[internal/service 业务服务]
  Service -->|ORM| DB[(数据库)]
  API -->|插件调用| Plugin[PluginAPIRouter]
```

国际化（i18n）由 `ExtractAndSetAcceptLanguage` 中间件处理；头像缩略图与访问鉴权作为静态路由的中间件链 资料来源：[internal/base/server/http.go:52-58]()。

## 4. 前端架构与插件系统

前端以 React + TypeScript 构建，核心工具模块集中在 `ui/src/utils` 下，导出 `request`、`Storage`、`floppyNavigation`、`storageExpires`、`SaveDraft` 等通用能力 资料来源：[ui/src/utils/index.ts:24-29]()。HTTP 请求基于 `axios` 实现，包含超时（默认 10s）、凭据携带、错误码拦截等机制 资料来源：[ui/src/utils/request.ts:39-44]()。针对 AI 流式响应，独立提供 `requestAi.ts`，支持 `onMessage`、`onError`、`onComplete` 回调以及可中断的 `AbortController` 资料来源：[ui/src/utils/requestAi.ts:1-22]()。

插件是 Answer 的核心扩展机制。`PluginType` 枚举定义了八种插件类型：`connector`、`search`、`editor`、`editor_replacement`、`route`、`captcha`、`render`、`sidebar` 资料来源：[ui/src/utils/pluginKit/interface.ts:25-36]()。每个插件由 `PluginInfo`（`slug_name`、`type` 等元数据）与 `Plugin` 组件组成 资料来源：[ui/src/utils/pluginKit/interface.ts:38-44]()。`Plugins` 类的初始化流程会先注册内置插件，再通过 `getPluginsStatus` 拉取已启用插件，并构建 `replacementPlugins` 映射以支持同类替换 资料来源：[ui/src/utils/pluginKit/index.ts:54-69]()。i18n 资源以命名空间 `plugin` 注册，并在 i18next 重新初始化后自动重新注入 资料来源：[ui/src/utils/pluginKit/utils.ts:36-50]()。

## 5. 关键子系统一览

- **SchemaForm 组件**：基于 JSON Schema 与 UI Schema 动态构建表单，提供 `initFormData`、`validator`、`refreshConfig` 等能力，可用于插件配置面板等场景 资料来源：[ui/src/components/SchemaForm/README.md:5-72]()。
- **编辑器渲染工具**：`htmlRender` 在客户端将原始 HTML 中的 `p`、表格、`a` 标签做规范化处理（如为外链添加 `rel="nofollow"`、为表格套上响应式容器） 资料来源：[ui/src/components/Editor/utils/index.ts:30-50]()。
- **导航与草稿**：`floppyNavigation` 用于在路由跳转时暂存来源路径以便登录后回跳 资料来源：[ui/src/utils/floppyNavigation.ts:24-30]()；`storageWithExpires` 提供带过期时间的本地草稿存储，默认 7 天 资料来源：[ui/src/utils/storageWithExpires.ts:27-33]()。
- **构建管线**：`internal/cli/build.go` 中的 `formatPlugins` 将 `plugin@version=path` 描述解析为 `pluginInfo`，并对本地路径取绝对值，确保在临时构建目录中正确解析 资料来源：[internal/cli/build.go:13-32]()。

## 6. 部署与扩展建议

- **快速试用**：使用 Docker 命令一键启动，访问 `http://localhost:9080` 资料来源：[README.md:27-28]()。
- **生产部署**：通过 Helm Chart 部署到 Kubernetes，注意默认 `replicaCount=1`，如需水平扩容需结合外部数据库实现 资料来源：[charts/README.md:7-12]()。
- **插件开发**：参考 `PluginType` 枚举选择目标插槽，使用 `SchemaForm` 暴露配置 UI，通过 `info.yaml` 注册 `slug_name` 与 `type` 资料来源：[ui/src/utils/pluginKit/interface.ts:25-44]()。
- **AI 能力**：v2.0.1 起原生支持语义搜索与向量同步，AI 接口路径 `/chat/completions` 已从 Brotli 压缩中排除以保留流式输出 资料来源：[internal/base/server/http.go:33-39]()，配合 `requestAi.ts` 消费 SSE 响应 资料来源：[ui/src/utils/requestAi.ts:1-22]()。

## See Also

- [SchemaForm 使用文档](ui/src/components/SchemaForm/README.md)
- [插件接口定义](ui/src/utils/pluginKit/interface.ts)
- [HTTP 服务装配入口](internal/base/server/http.go)
- [Helm Chart 配置](charts/README.md)

---

<a id='page-2'></a>

## 核心问答与用户体系 (Core Q&A and User System)

### 相关页面

相关主题：[项目概览与系统架构 (Project Overview & System Architecture)](#page-1), [AI 能力、搜索与插件扩展 (AI, Search & Plugin Extensibility)](#page-3), [部署、国际化与运维 (Deployment, Internationalization & Operations)](#page-4)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/apache/answer/blob/main/README.md)
- [internal/base/server/http.go](https://github.com/apache/answer/blob/main/internal/base/server/http.go)
- [ui/src/services/client/question.ts](https://github.com/apache/answer/blob/main/ui/src/services/client/question.ts)
- [ui/src/utils/pluginKit/index.ts](https://github.com/apache/answer/blob/main/ui/src/utils/pluginKit/index.ts)
- [ui/src/utils/pluginKit/interface.ts](https://github.com/apache/answer/blob/main/ui/src/utils/pluginKit/interface.ts)
- [ui/src/utils/pluginKit/utils.ts](https://github.com/apache/answer/blob/main/ui/src/utils/pluginKit/utils.ts)
- [ui/src/utils/request.ts](https://github.com/apache/answer/blob/main/ui/src/utils/request.ts)
- [ui/src/components/SchemaForm/README.md](https://github.com/apache/answer/blob/main/ui/src/components/SchemaForm/README.md)
- [ui/src/components/Editor/utils/index.ts](https://github.com/apache/answer/blob/main/ui/src/components/Editor/utils/index.ts)
- [internal/cli/build.go](https://github.com/apache/answer/blob/main/internal/cli/build.go)
- [ui/package.json](https://github.com/apache/answer/blob/main/ui/package.json)
- [charts/README.md](https://github.com/apache/answer/blob/main/charts/README.md)
</details>

# 核心问答与用户体系 (Core Q&A and User System)

## 1. 概述与定位

Apache Answer 是一款面向任意规模团队的问答平台软件，可用于社区论坛、帮助中心或知识管理等多种场景。`README.md` 中明确说明其设计目标是 "A Q&A platform software for teams at any scales"，后端采用 Go 语言，前端采用 React 技术栈。平台通过插件机制提供扩展能力，使社区运营方和开发者能够灵活定制功能。

资料来源：[README.md:1-25]()

核心问答体系包括问题（Question）、回答（Answer）、评论（Comment）、标签（Tag）和用户（User）等基础实体。这些实体在 UI 层通过标准化的服务模块与后端 REST API 交互，并借助插件系统在生命周期内进行能力增强。

## 2. HTTP 服务与请求流转

后端 HTTP 服务通过 Gin 引擎构建，路由注册在 `internal/base/server/http.go` 中完成。该文件定义了多个路由器：`StaticRouter`、`AnswerAPIRouter`、`SwaggerRouter`、`UIRouter`、`PluginAPIRouter` 和 `TemplateRouter`，并通过中间件链处理压缩、语言提取和短 ID 标识等横切关注点。

```mermaid
flowchart LR
  A[浏览器/客户端] --> B[Gin Engine]
  B --> C[Brotli 压缩 + 语言中间件]
  C --> D{路由分发}
  D --> E[UIRouter<br/>视图渲染]
  D --> F[AnswerAPIRouter<br/>业务 API]
  D --> G[PluginAPIRouter<br/>插件 API]
  D --> H[SwaggerRouter<br/>文档]
  D --> I[StaticRouter<br/>静态资源]
  E --> J[用户问答页面]
  F --> K[问题/回答/用户控制器]
```

资料来源：[internal/base/server/http.go:1-50]()

值得注意的细节是，`/chat/completions` 路径被显式跳过 Brotli 压缩，因为该接口通常用于 AI 流式响应（Server-Sent Events），压缩会破坏流式传输。健康检查端点 `/healthz` 直接返回 "OK"，便于容器编排系统探活。

## 3. 前端问答服务层

前端通过统一的请求封装与后端 API 通信。`ui/src/utils/request.ts` 基于 Axios 封装了 `baseConfig`，在开发模式下使用相对路径，在生产模式下使用 `process.env.REACT_APP_API_URL`，并启用了 `withCredentials` 以支持跨域 Cookie 认证。

问题相关的服务调用集中在 `ui/src/services/client/question.ts` 中，包括相似问题推荐、邀请用户回答、问题恢复等操作：

| 操作 | HTTP 方法 | 接口路径 | 用途 |
|------|----------|----------|------|
| 获取相似问题 | GET | `/answer/api/v1/question/similar/tag` | 提问时推荐相似问题 |
| 邀请回答 | PUT | `/answer/api/v1/question/invite` | 邀请指定用户回答 |
| 恢复已删问题 | POST | `/answer/api/v1/question/recover` | 误删恢复 |
| 恢复已删回答 | POST | `/answer/api/v1/answer/recover` | 误删恢复 |

资料来源：[ui/src/services/client/question.ts:1-30]()，[ui/src/utils/request.ts:30-55]()

社区讨论中提到的「对问题和回答添加反应（Reactions）」功能（参考 Issue #883）正是基于此类服务层进行扩展，避免影响声誉系统。

## 4. 用户体系与插件扩展

### 4.1 用户认证与会话

前端通过 `LOGGED_TOKEN_STORAGE_KEY` 在本地存储登录凭证，并在每次请求时携带。请求模块还实现了对特定状态码（如 401、403）的全局处理，结合 `floppyNavigation` 在认证失效时引导用户跳转登录页。

资料来源：[ui/src/utils/request.ts:40-60]()

### 4.2 插件系统支撑的用户能力

插件系统是用户体系扩展的核心。`ui/src/utils/pluginKit/interface.ts` 定义了 `PluginType` 枚举，包含 `Connector`（登录连接器）、`Search`（搜索引擎）、`Editor`（编辑器）、`Captcha`（验证码）等类型：

| 插件类型 | 用途 | 用户体系关联 |
|---------|------|--------------|
| Connector | 第三方登录（如 GitHub、Google） | 用户注册与登录 |
| Search | 搜索后端实现 | 知识检索 |
| Editor | 编辑器扩展 | 提问/回答编辑 |
| Captcha | 人机验证 | 防灌水 |
| Render | 自定义渲染 | 内容展示 |

资料来源：[ui/src/utils/pluginKit/interface.ts:30-60]()

插件初始化流程由 `ui/src/utils/pluginKit/index.ts` 中的 `Plugins` 类管理：先注册内置插件，再调用 `getPluginsStatus` 获取已启用插件列表，最后动态加载。i18n 资源通过 `initI18nResource` 注入到 `i18next` 的 `plugin` 命名空间下，并监听 `initialized` 事件以兼容开发模式热更新。

资料来源：[ui/src/utils/pluginKit/index.ts:30-70]()，[ui/src/utils/pluginKit/utils.ts:30-50]()

### 4.3 本地化与多语言

针对社区对中文支持的关注（参考 Issue #363、#367），插件层提供 `addResourceBundle` 机制，按语言动态注入翻译资源。核心语言解析在 `internal/base/server/http.go` 的 `ExtractAndSetAcceptLanguage` 中间件中完成。

资料来源：[internal/base/server/http.go:25-35]()，[ui/src/utils/pluginKit/utils.ts:20-35]()

## 5. 表单与编辑器：用户内容生产

### 5.1 SchemaForm

`SchemaForm` 组件可根据 JSON Schema 与 UI Schema 自动构建表单，典型应用场景包括插件配置页、用户偏好设置等。其 `refreshConfig` 方法允许动态刷新配置项，便于在不刷页的前提下更新表单定义。

资料来源：[ui/src/components/SchemaForm/README.md:1-30]()

### 5.2 富文本编辑器

`ui/src/components/Editor/utils/index.ts` 实现了 HTML 渲染逻辑，包括 BR 标签换行修复、表格 Bootstrap 样式注入、外链 `rel="nofollow"` 自动追加等。这些处理保证用户提交的内容在不同主题与样式下均能安全、正确地呈现，是问答内容质量的基础保障。

资料来源：[ui/src/components/Editor/utils/index.ts:1-30]()

## 6. 构建与部署

后端通过 `internal/cli/build.go` 实现自定义构建流程，支持在编译期注入外部插件（格式：`module@version=local_path`）。前端构建依赖由 `ui/package.json` 管理，要求 Node.js ≥ 20、pnpm ≥ 9。Helm Chart（`charts/README.md`）提供了 Kubernetes 部署模板，默认开启 `/data` 持久化卷，存储大小 5Gi。

资料来源：[internal/cli/build.go:1-40]()，[ui/package.json:1-30]()，[charts/README.md:1-30]()

## 7. 常见问题与最佳实践

- **本地化缺失**：若界面未显示中文，需确认插件 i18n 资源已被正确注入，可通过 `getTransNs()` 返回的命名空间排查。
- **插件加载失败**：`Plugins.init()` 会捕获 `getPluginsStatus` 异常并降级为空列表，确保安装阶段不会因 API 不可用而崩溃。
- **认证失效**：拦截器依赖 `LOGGED_TOKEN_STORAGE_KEY`，清理浏览器存储会导致会话丢失。
- **流式响应**：调用 `/chat/completions` 的前端代码必须使用支持 SSE 的客户端（如 `requestAi.ts` 中的 `ReadableStreamDefaultReader`），不要使用普通的 Axios 封装。

资料来源：[ui/src/utils/pluginKit/index.ts:35-55]()，[ui/src/utils/requestAi.ts:15-40]()

## See Also

- [插件系统与扩展开发 (Plugin System)](./plugin-system.md)
- [AI 与向量搜索能力 (AI & Vector Search)](./ai-vector-search.md)
- [Helm Chart 部署指南 (Kubernetes Deployment)](./helm-deployment.md)

---

<a id='page-3'></a>

## AI 能力、搜索与插件扩展 (AI, Search & Plugin Extensibility)

### 相关页面

相关主题：[项目概览与系统架构 (Project Overview & System Architecture)](#page-1), [核心问答与用户体系 (Core Q&A and User System)](#page-2), [部署、国际化与运维 (Deployment, Internationalization & Operations)](#page-4)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/apache/answer/blob/main/README.md)
- [charts/README.md](https://github.com/apache/answer/blob/main/charts/README.md)
- [internal/cli/build.go](https://github.com/apache/answer/blob/main/internal/cli/build.go)
- [internal/base/server/http.go](https://github.com/apache/answer/blob/main/internal/base/server/http.go)
- [ui/src/utils/pluginKit/index.ts](https://github.com/apache/answer/blob/main/ui/src/utils/pluginKit/index.ts)
- [ui/src/utils/pluginKit/utils.ts](https://github.com/apache/answer/blob/main/ui/src/utils/pluginKit/utils.ts)
- [ui/src/utils/requestAi.ts](https://github.com/apache/answer/blob/main/ui/src/utils/requestAi.ts)
- [ui/src/services/client/question.ts](https://github.com/apache/answer/blob/main/ui/src/services/client/question.ts)
- [ui/src/components/SchemaForm/README.md](https://github.com/apache/answer/blob/main/ui/src/components/SchemaForm/README.md)
- [ui/package.json](https://github.com/apache/answer/blob/main/ui/package.json)
</details>

# AI 能力、搜索与插件扩展 (AI, Search & Plugin Extensibility)

## 概述

Apache Answer 是一个开源的问答社区平台，支持构建团队帮助中心、社区论坛与知识库。从 v2.0.1 发布说明可以看出，平台已原生支持 **语义搜索、AI 对话、向量嵌入同步** 等能力，并提供了完善的 **插件系统**，允许开发者在不修改核心代码的前提下扩展登录连接器、搜索后端、向量存储等模块 资料来源：[README.md:11-25]() 资料来源：[ui/src/utils/pluginKit/index.ts:19-31]()。

本页重点介绍 AI 能力、搜索机制与插件扩展三大主题，帮助开发者快速理解其架构、接口与扩展方式。

## AI 能力与流式请求

### AI 请求处理

前端通过 `requestAi.ts` 实现了对 AI 流式接口的统一封装。它在 `RequestAiOptions` 之上扩展了 `onMessage`、`onError`、`onComplete` 等回调，并维护了一个全局 `requestState`（包含 `currentReader` 与 `abortController`）以支持取消当前正在进行的请求 资料来源：[ui/src/utils/requestAi.ts:9-32]()。

在错误处理上，模块解析 HTTP 状态码并对后端返回的 `err_type` 做差异化处理：`toast` 类型通过 `toastStore` 弹窗提示用户，`alert` 类型则将错误对象 reject 出去供调用方展示 资料来源：[ui/src/utils/requestAi.ts:42-77]()。后端 Gin 引擎特别放行了 `/chat/completions` 路径的 Brotli 压缩，避免对流式响应造成干扰 资料来源：[internal/base/server/http.go:43-50]()。

### 与问答业务的集成

AI 能力并非独立存在，而是嵌入到问答工作流中。例如，问题详情页的相似问题推荐 (`/answer/api/v1/question/similar/tag`)、邀请用户回答 (`/answer/api/v1/question/invite`)、以及删除后的恢复接口 (`/answer/api/v1/answer/recover`、`/answer/api/v1/question/recover`) 都通过 SWR 缓存统一调度 资料来源：[ui/src/services/client/question.ts:1-78]()。开发者可在这些已有业务流中注入 AI 提示或自动化操作。

## 搜索与 Schema 表单

### 搜索入口

Answer 在前端通过 `question` 客户端封装了多个搜索类接口，并通过 SWR 提供响应式缓存与加载状态。这种设计使得"相似问题"、"标签搜索"、"全文检索"等入口可以共享一套请求/缓存/错误处理范式 资料来源：[ui/src/services/client/question.ts:1-18]()。

### 后台配置：SchemaForm

AI 与搜索插件通常需要让管理员在界面里配置参数（如 Embedding 模型、API Key、向量维度等）。`SchemaForm` 组件基于 JSON Schema 与 UI Schema 动态渲染表单，支持 `input`、`select`、`upload`、`switch`、`timezone`、`checkbox`、`radio`、`textarea`、`button` 等多种 widget 资料来源：[ui/src/components/SchemaForm/README.md:1-90]()。通过 `UIOptions.validator` 字段还能编写异步校验逻辑，使得插件配置 UI 可以无缝集成进现有管理后台 资料来源：[ui/src/components/SchemaForm/README.md:99-120]()。

## 插件扩展体系

### 插件分类与注册

插件在前端以 `Plugin` 对象描述，核心字段包括 `slug_name`（唯一标识）、`type`（如 `connector`、`search`、`vector` 等，可在 `PluginType` 中枚举）、`name`、`description` 等 资料来源：[ui/src/utils/pluginKit/index.ts:11-31]()。`Plugins` 初始化时会先注册内置插件 (`registerBuiltin`)，再通过 `getPluginsStatus` 拉取后端启用的插件列表并按需激活 资料来源：[ui/src/utils/pluginKit/index.ts:35-50]()。

### 国际化与渲染

插件可以携带自带的 i18n 资源包，由 `addResourceBundle` 注入到 `i18next` 的 `plugin` 命名空间下；同时为了兼容开发模式下的热更新，工具还监听了 `initialized` 事件以重新注入 资料来源：[ui/src/utils/pluginKit/utils.ts:25-42]()。`PluginRender` 会根据 `PluginType` 自动选择对应的渲染器，从而将插件 UI 嵌入到登录页、搜索框、答案区等位置 资料来源：[ui/src/utils/pluginKit/index.ts:14-18]()。

## 构建与部署

### CLI 构建插件化二进制

`internal/cli/build.go` 提供了 `answer build` 命令。其插件描述格式为 `module/path@version=/local/path`，其中 `=` 后可选本地目录用于开发期联调 资料来源：[internal/cli/build.go:13-26]()。在生成最终 main.go 时，远程插件通过 `versionedModulePath` 加入 import 列表，本地插件则被复制到 `vendor/github.com/apache/answer-plugins/` 目录下以 `replace` 指令重定向 资料来源：[internal/cli/build.go:55-85]()。

### Helm 部署

生产环境推荐使用官方 Helm Chart。下表列出了常用配置项 资料来源：[charts/README.md:9-32]()：

| 参数 | 描述 | 默认值 |
| --- | --- | --- |
| `replicaCount` | Answer 副本数 | `1` |
| `image.repository` | 镜像仓库 | `apache/answer` |
| `image.tag` | 镜像标签 | `latest` |
| `persistence.enabled` | 是否持久化 `/data` 卷 | `true` |
| `persistence.size` | 持久卷大小 | `5Gi` |
| `env` | 可选环境变量 | `LOG_LEVEL: INFO` |
| `extraContainers` | 边车容器列表 | `[]` |

```mermaid
flowchart LR
    A[前端 UI<br/>React] -->|SWR 请求| B[API 路由<br/>Gin]
    B --> C[业务 Controller]
    B --> D[AI Controller]
    B --> E[插件 API Router]
    C --> F[(DB)]
    D --> G[(向量库<br/>Plugin)]
    E --> H[Connector<br/>Plugin]
    E --> I[Search<br/>Plugin]
    style D fill:#fef3c7,stroke:#d97706
    style E fill:#dbeafe,stroke:#1d4ed8
```

## 常见问题与扩展建议

- **AI 流式响应被 Brotli 压缩破坏**：后端已对 `/chat/completions` 跳过压缩，开发者新增 AI 路径时需注意保持该白名单 资料来源：[internal/base/server/http.go:44-50]()。
- **插件本地开发**：`answer build` 支持 `module@version=/local/path` 语法；如遇到 v2+ 模块无法直接拉取，可设置 `ANSWER_MODULE` 指向本地 checkout 资料来源：[internal/cli/build.go:70-85]()。
- **配置表单扩展**：插件后台配置建议基于 `SchemaForm` 实现，可复用校验、`readOnly`、`simplify` 等统一行为 资料来源：[ui/src/components/SchemaForm/README.md:99-130]()。
- **社区诉求**：社区曾反馈希望增加"表情反应 (Reactions)"以丰富互动，插件机制为该类新功能提供了天然挂载点 资料来源：[ui/src/utils/pluginKit/index.ts:11-31]()。

## See Also

- [插件与构建系统详解 (Plugins & Build System)](./plugins-and-build.md)
- [问答业务流 (Question & Answer Workflow)](./question-answer-workflow.md)
- [部署与运维 (Deployment & Operations)](./deployment.md)

---

<a id='page-4'></a>

## 部署、国际化与运维 (Deployment, Internationalization & Operations)

### 相关页面

相关主题：[项目概览与系统架构 (Project Overview & System Architecture)](#page-1), [核心问答与用户体系 (Core Q&A and User System)](#page-2), [AI 能力、搜索与插件扩展 (AI, Search & Plugin Extensibility)](#page-3)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/apache/answer/blob/main/README.md)
- [charts/README.md](https://github.com/apache/answer/blob/main/charts/README.md)
- [internal/cli/build.go](https://github.com/apache/answer/blob/main/internal/cli/build.go)
- [internal/base/server/http.go](https://github.com/apache/answer/blob/main/internal/base/server/http.go)
- [internal/base/server/http_funcmap.go](https://github.com/apache/answer/blob/main/internal/base/server/http_funcmap.go)
- [ui/src/utils/localize.ts](https://github.com/apache/answer/blob/main/ui/src/utils/localize.ts)
- [ui/src/utils/pluginKit/utils.ts](https://github.com/apache/answer/blob/main/ui/src/utils/pluginKit/utils.ts)
- [ui/src/utils/pluginKit/interface.ts](https://github.com/apache/answer/blob/main/ui/src/utils/pluginKit/interface.ts)
- [ui/src/utils/pluginKit/index.ts](https://github.com/apache/answer/blob/main/ui/src/utils/pluginKit/index.ts)
- [ui/package.json](https://github.com/apache/answer/blob/main/ui/package.json)
- [ui/src/components/SchemaForm/README.md](https://github.com/apache/answer/blob/main/ui/src/components/SchemaForm/README.md)
</details>

# 部署、国际化与运维 (Deployment, Internationalization & Operations)

## 概述

Apache Answer 是一个面向团队、社区与企业的开源问答平台软件。本页聚焦于其部署形态、本地化能力以及日常运维相关的实现细节，覆盖 Docker 容器化部署、Kubernetes Helm Chart、二进制构建、i18n 资源加载、插件国际化以及 HTTP 服务初始化与中间件链等内容。

## 部署方式

### Docker 快速启动

最简部署方式为通过 Docker 直接拉取官方镜像运行：

```bash
docker run -d -p 9080:80 -v answer-data:/data --name answer apache/answer:2.0.1
```

上述命令将容器 80 端口映射至宿主机的 9080 端口，并把 `/data` 目录挂载到名为 `answer-data` 的数据卷中，以便持久化应用数据。资料来源：[README.md]()

### Kubernetes Helm Chart

仓库 `charts/` 目录提供了官方 Helm Chart，要求 Kubernetes 1.20+。默认配置覆盖副本数、镜像来源与拉取策略、持久化卷与服务账户等。下表列出关键可配置参数（资料来源：[charts/README.md]()）：

| 参数 | 说明 | 默认值 |
|------|------|--------|
| `replicaCount` | Answer 副本数 | `1` |
| `image.repository` | 镜像仓库 | `apache/answer` |
| `image.tag` | 镜像标签 | `latest` |
| `env` | 容器环境变量 | `LOG_LEVEL: INFO` |
| `persistence.enabled` | 是否启用 `/data` 持久卷 | `true` |
| `persistence.size` | 持久卷容量 | `5Gi` |
| `serviceAccount.create` | 是否创建 ServiceAccount | `true` |

### 含插件的自定义构建

当需要将自有或本地插件打包进二进制时，`internal/cli/build.go` 的 `formatPlugins` 函数会解析形如 `github.com/apache/answer-plugins/github-connector@latest=/local/path` 的描述串，并将本地相对路径解析为绝对路径后传递给后续构建步骤。构建流程会生成临时 `main.go`、复制 UI 与插件源码，并按需执行 `pnpm install`。对 v2+ 模块若未本地缓存则会通过 `git clone --depth=1` 拉取，并提示用户可通过设置 `ANSWER_MODULE` 环境变量改用本地检出目录。资料来源：[internal/cli/build.go]()

## 国际化与本地化

### 语言资源加载

前端通过 `ui/src/utils/localize.ts` 中的 `pullLanguageConf` 与 `addI18nResource`，在用户切换语言或进入 `/install` 阶段时按需调用后端接口获取对应语言资源，并写入 `LANG_RESOURCE_STORAGE_KEY` 缓存键。开发模式下还会动态合并 `i18n/i18n.yaml` 中的语言选项，以便即时预览新增翻译——这也是社区多次呼吁加强中文等小语种支持的入口点（参考 Issue #363、#367）。资料来源：[ui/src/utils/localize.ts]()

### 插件国际化

插件体系通过统一命名空间 `plugin` 注册 i18n 资源。`ui/src/utils/pluginKit/utils.ts` 的 `addResourceBundle` 遍历多语言对象后调用 `i18next.addResourceBundle` 注入运行时；同时通过监听 `initialized` 事件，在热重载场景下重新注入，避免插件翻译被基础资源重置时丢失。每个插件通过 `PluginInfo` 声明 `slug_name`、`type` 等元信息，由 `PluginType` 枚举（`connector`、`search`、`editor`、`captcha` 等）归类，使 `PluginRender` 可按类型自动渲染。资料来源：[ui/src/utils/pluginKit/utils.ts]()、[ui/src/utils/pluginKit/interface.ts]()、[ui/src/utils/pluginKit/index.ts]()

### 插件配置表单

`SchemaForm` 组件允许后端返回 JSON Schema 直接生成插件配置表单。其后端协议要求每个字段返回 `name`、`type`、`title`、`required`、`value`、`ui_options` 等字段，支持的控件类型覆盖 `textarea`、`select`、`upload`、`switch` 等，并通过 `UIAction` 描述提交后行为（如刷新配置、Toast 提示）。资料来源：[ui/src/components/SchemaForm/README.md]()

## HTTP 服务与运维

### 服务初始化

Go 后端使用 Gin 作为 HTTP 框架。`internal/base/server/http.go` 在启动时根据 `ANSWER_TEMPLATE_PATH` 环境变量或嵌入的 `ui.Template` 加载 HTML 模板，并注册 `/healthz` 健康检查端点返回 `OK`。Brotli 压缩默认开启，但 `/chat/completions` 路径会被显式跳过，以兼容 AI 聊天的流式响应（v2.0.1 起引入的语义搜索与向量化能力依赖此路径）。资料来源：[internal/base/server/http.go]()

中间件链按顺序生效：`brotli.Brotli` → `ExtractAndSetAcceptLanguage`（提取并设置语言）→ `ShortIDMiddleware.SetShortIDFlag`（短 ID 标识），随后通过 `HeadersByRequestURI` 调整响应头，最后分发到视图路由与静态资源路由。资料来源：[internal/base/server/http.go]()

### 外链 Nofollow 处理

`internal/base/server/http_funcmap.go` 中的 `FormatLinkNofollow` 通过正则匹配正文 `<a>` 标签，对指向非本站 URL 的链接追加 `rel="nofollow"`，而指向自身 `SiteUrl` 的链接保持原状，从而保留 SEO 友好性、避免外部链接权重流失。资料来源：[internal/base/server/http_funcmap.go]()

### 前端依赖与构建

前端基于 React + TypeScript 构建，`package.json` 中声明 `packageManager` 为 `pnpm@9.7.0`，并要求 Node ≥ 20、pnpm ≥ 9。主要库包括 `react-i18next@11`、`react-router-dom@7`、`zustand@5`、`SWR@1.3` 等；测试栈使用 Jest + Testing Library，构建工具为 `react-scripts` 5 配合 `react-app-rewired` 自定义配置。资料来源：[ui/package.json]()

## 常见问题与建议

- **语言显示异常**：若切换语言后部分文案未更新，需检查 `LANG_RESOURCE_STORAGE_KEY` 缓存及后端语言资源接口。社区中也有用户多次反馈希望原生支持更多中文界面（参见 Issue #363、#367）。
- **插件路径问题**：自定义构建若出现 "failed to clone ..." 错误，建议设置 `ANSWER_MODULE` 或使用 `=/local/path` 形式指定本地插件路径（v2.0.1 改进）。
- **运维扩缩容**：可通过 Helm Chart 的 `replicaCount` 与持久卷配置实现水平扩展，并通过 `env.LOG_LEVEL` 控制日志级别；`/healthz` 可作为 Kubernetes 存活探针的目标端点。
- **互动增强**：社区已讨论加入 "Reactions" 以替代部分低质量评论（Issue #883），以及邮件订阅新问题（Issue #419），未来运维侧可能需要配置 SMTP 与通知路由。

## See Also

- 项目主页与文档：[answer.apache.org](https://answer.apache.org)
- 安装指南：[Installation](https://answer.apache.org/docs/installation)
- 插件体系：[ui/src/utils/pluginKit](https://github.com/apache/answer/blob/main/ui/src/utils/pluginKit)
- SchemaForm 用法：[ui/src/components/SchemaForm/README.md](https://github.com/apache/answer/blob/main/ui/src/components/SchemaForm/README.md)
- Helm Chart 配置：[charts/README.md](https://github.com/apache/answer/blob/main/charts/README.md)

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：apache/answer

摘要：发现 14 个潜在踩坑项，其中 2 个为 high/blocking；最高优先级：配置坑 - 来源证据：[Feature] Add option to disable email verification on registration。

## 1. 配置坑 · 来源证据：[Feature] Add option to disable email verification on registration

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[Feature] Add option to disable email verification on registration
- 对用户的影响：可能影响升级、迁移或版本选择。
- 证据：community_evidence:github | https://github.com/apache/answer/issues/1517 | 来源类型 github_issue 暴露的待验证使用条件。

## 2. 维护坑 · 来源证据：Can't accept answers

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：Can't accept answers
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/apache/answer/issues/1541 | 来源讨论提到 macos 相关条件，需在安装/试用前复核。

## 3. 安装坑 · 依赖 Docker 环境

- 严重度：medium
- 证据强度：runtime_trace
- 发现：安装/运行入口包含 Docker 命令：docker run -d -p 9080:80 -v answer-data:/data --name answer apache/answer:2.0.1
- 对用户的影响：非工程用户可能没有 Docker，启动成本明显增加。
- 复现命令：`docker run -d -p 9080:80 -v answer-data:/data --name answer apache/answer:2.0.1`
- 证据：identity.distribution | https://github.com/apache/answer | docker run -d -p 9080:80 -v answer-data:/data --name answer apache/answer:2.0.1

## 4. 安装坑 · 来源证据：Answer process jumps after few days to ~ 99% CPU usage

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Answer process jumps after few days to ~ 99% CPU usage
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/apache/answer/issues/1493 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 5. 安装坑 · 来源证据：Fix issue to support building with local plugins

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：Fix issue to support building with local plugins
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/apache/answer/issues/1519 | 来源讨论提到 macos 相关条件，需在安装/试用前复核。

## 6. 安装坑 · 来源证据：avatar column in user table is too small

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安装相关的待验证问题：avatar column in user table is too small
- 对用户的影响：可能增加新用户试用和生产接入成本。
- 证据：community_evidence:github | https://github.com/apache/answer/issues/1498 | 来源讨论提到 linux 相关条件，需在安装/试用前复核。

## 7. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 证据：capability.assumptions | https://github.com/apache/answer | README/documentation is current enough for a first validation pass.

## 8. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 证据：evidence.maintainer_signals | https://github.com/apache/answer | last_activity_observed missing

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 证据：downstream_validation.risk_items | https://github.com/apache/answer | no_demo; severity=medium

## 10. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 证据：risks.scoring_risks | https://github.com/apache/answer | no_demo; severity=medium

## 11. 安全/权限坑 · 来源证据：API Key authentication not supported in private mode (LoginRequired=true)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：API Key authentication not supported in private mode (LoginRequired=true)
- 对用户的影响：可能影响授权、密钥配置或安全边界。
- 证据：community_evidence:github | https://github.com/apache/answer/issues/1508 | 来源讨论提到 api key 相关条件，需在安装/试用前复核。

## 12. 安全/权限坑 · 来源证据：Image upload fails with "Cannot read properties of null" after upgrading to v2.0.0

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Image upload fails with "Cannot read properties of null" after upgrading to v2.0.0
- 对用户的影响：可能影响升级、迁移或版本选择。
- 证据：community_evidence:github | https://github.com/apache/answer/issues/1516 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。

## 13. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 证据：evidence.maintainer_signals | https://github.com/apache/answer | issue_or_pr_quality=unknown

## 14. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 证据：evidence.maintainer_signals | https://github.com/apache/answer | release_recency=unknown

<!-- canonical_name: apache/answer; human_manual_source: deepwiki_human_wiki -->
