01laky/many_faces_ai

GitHub: 01laky/many_faces_ai

一个基于 Python gRPC 的无状态 AI 微服务,连接本地 Ollama(qwen2.5)为后台管理系统提供 RAG 智能问答和咨询性内容审核能力。

Stars: 0 | Forks: 0

# Many Faces AI 服务 [![version](https://img.shields.io/badge/version-0.11.0-blue)](./VERSION) ![Python](https://img.shields.io/badge/Python-3.11-3776AB) ![gRPC](https://img.shields.io/badge/gRPC-1.80-244c5a) ![Ollama](https://img.shields.io/badge/Ollama-host-black) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/2218701455052712.svg)](https://github.com/01laky/many_faces_main/actions/workflows/ci.yml) ![tests](https://img.shields.io/badge/tests-CI%20gated-brightgreen) ![platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey) **版本:** [`0.11.0`](./VERSION) · [更新日志](./CHANGELOG.md) · [功能路线图](./docs/capability-roadmap-v0.9.0.md) **作者:** Ladislav Kostolny · [01laky@gmail.com](mailto:01laky@gmail.com) ## 快速开始 ``` # Full stack(推荐) cd many_faces_main ./scripts/start-all-dev.sh # Standalone cd many_faces_ai ./scripts/start-dev.sh ``` **gRPC 端口:** `localhost:50051` · **Ollama** 必须在宿主机的 `OLLAMA_HOST` 上运行 ## 架构 ``` flowchart LR be["many_faces_backend
IAiGrpcService (orchestrator)"] --> grpc["many_faces_ai
thin Python gRPC adapter"] grpc --> ollama["Ollama on host
qwen2.5:7b · nomic-embed-text"] be -->|"RAG: embed question"| embed["EmbedText → nomic-embed-text"] be -->|"RAG: answer one bundle"| gen["Generate → qwen2.5:7b"] be -->|"stream operator answer"| stream["GenerateStream → qwen2.5:7b"] be -->|"content moderation"| review["ReviewContent"] be -->|"infra"| profile["GetHostProfile / HealthCheck"] embed --> grpc gen --> grpc stream --> grpc review --> grpc profile --> grpc ``` **此服务是无状态的。** 它从不读取数据库,从不调用 Elasticsearch,也从不发布内容。**后端负责编排**一切 —— 此 worker 仅负责**生成**和**嵌入**。 ## 三大支柱 | 支柱 | 亮点 | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **安全性 (AIH1)** | 仅限内部 **gRPC** —— 无公开 HTTP;可选的 **`x-ai-worker-token`** metadata 认证;通过 `GRPC_TLS_CERT_FILE` 启用 **TLS**;对公开统计数据获取进行 SSRF 防护;内容审核输入进行净化处理。CI: `node ../scripts/verify-ai-security-tests.mjs`。 | | **AI 功能** | **线上:** `EmbedText` (RAG 向量) · `Generate` (批量 map+stitch) · `GenerateStream` (token 流式传输) · `ReviewContent` (咨询性审核) · `GetHostProfile` / `HealthCheck`。**可用,尚未接入:** `ChatRiskScore`, `GenerateReport`, `BuildFaceContextSnapshot`, `ExplainDecision`。 | | **配置** | 通过环境变量配置 `OLLAMA_HOST`、模型名称、超时时间、最大 token 数;**低 VRAM 调优** (`OLLAMA_KEEP_ALIVE=-1`, `OLLAMA_NUM_GPU`, `OLLAMA_FLASH_ATTENTION`, `OLLAMA_KV_CACHE_TYPE`)。 | ## 为什么采用这种 AI 设计 | 优势 | 意味着什么 | | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **完全本地化** | Ollama 运行在宿主机上 —— 保护隐私、无每 token 成本、支持离线工作 | | **RAG,而非 prompt-stuffing** | 操作员聊天会**嵌入问题**并仅检索相关数据 (ES kNN+BM25, RRF) —— 不会将全量数据倾倒至 context | | **精确数字,绝不产生幻觉** | Embeddings 仅用于**路由**到正确的数据;**数值由后端全新且确定性地加载** —— 模型只负责叙述,绝不凭空捏造数量 | | **针对小型本地模型调优** | **批量 map+stitch** 每次只向 7B 模型输入一个专注的数据块;**快速路径**只需 0–1 次生成即可回答计数/单 bundle 问题;答案按 token **流式传输** | | **仅作建议** | Worker 仅提供建议;由 `SUPER_ADMIN` 完成最终审核;AI 绝不自行发布;两种信任模型(不受信任的用户内容 vs 受信任的操作员请求)绝不混淆 | | **仅限 SUPER_ADMIN** | 所有 AI 功能均位于管理员界面;不对用户暴露 AI | ## AI 路径 —— 两条独立的 Pipeline | 路径 | RPCs | 目的 | | --------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | **操作员 RAG 聊天** | `EmbedText` + `Generate` + `GenerateStream` | 多线程操作员聊天:嵌入问题 → 从 ES 检索统计 bundle → 加载最新数值 → 批量 map+stitch → 流式传输答案 | | **用户内容审核** | `ReviewContent` | 相册/博客/短视频审批队列 —— 咨询性;不受信任的内容,**绝不**与操作员路径混淆 | ## 本地 7B 模型上的性能 在专用的 **RTX 3050 4 GB + Ryzen 7** 机器上:生成完整答案约需 ~90–120 秒。包含三项优化: | 优化项 | 方式 | | --------------------------- | ------------------------------------------------------------------------------------------------------- | | **减少生成次数** | 计数快速路径 = **0** 次生成;单 bundle 快速路径 = **1** 次生成 | | **加快生成速度** | `OLLAMA_KEEP_ALIVE=-1` 使模型常驻内存;96-token 的 map 上限;在 4 GB GPU 上设置 `MaxParallelBundleAiCalls=1` | | **降低感知延迟** | `GenerateStream` → 生成时在管理员 UI 中逐 token 显示 | **GPU 调优 (4 GB VRAM):** `OLLAMA_NUM_GPU=20` (部分卸载), `OLLAMA_FLASH_ATTENTION=1`, `OLLAMA_KV_CACHE_TYPE=q8_0`, `OLLAMA_NUM_CTX=4096`。 **可选的 3B 辅助模型:** `num_gpu=0` + `OLLAMA_MAX_LOADED_MODELS=2` —— 常驻 CPU 用于网关决策,不产生 GPU 资源争用。 **完整指南:** [`../docs/guides/operator-ai-performance.md`](../docs/guides/operator-ai-performance.md) ## 内容审核角色 `ReviewContent` RPC 是一个用于用户创建的相册、博客和短视频的**咨询性**分类器。此服务会: - 接收来自后端 worker 的有限审查请求(内容类型、标题、描述、媒体 URL、审核版本) - 在分类前通过 `moderation_input_sanitize.py` 规范化不受信任的输入(控制字符 + bidi 字符剥离、长度限制) - 返回结构化决策:`approve` / `reject` / `needs_human_review`,包含置信度、风险等级、标记、安全的用户端提示消息、模型版本、trace id - **绝不**写入 PostgreSQL,绝不发布内容,绝不自动批准 **安全规则:** AI 建议 → 后端策略验证 → `SUPER_ADMIN` 最终决定。 **指南:** [`../docs/guides/ai-assisted-content-approval.md`](../docs/guides/ai-assisted-content-approval.md) ## 安全 (AIH1) - 仅限内部 **gRPC** —— 无公开 HTTP API;后端是唯一预期的调用者。 - 可选的 **`x-ai-worker-token`** metadata 认证;安全强化配置要求在启动时提供。 - 通过 `GRPC_TLS_CERT_FILE` / `GRPC_TLS_KEY_FILE` 启用可选的 **gRPC TLS**。 - `ReviewContent` 在分类前对不受信任的创建者字段运行 PI-4 输入净化。 - `FetchPublicStats` 应用 worker 端的 SSRF 策略(公开网络强制使用 HTTPS,回环 HTTP 仅限开发环境)。 - Prompt 和 token 上限;对高频 RPC 进行可选的进程内限流。 - 安全回归测试:`tests/**/*_security.py` —— 在 monorepo 根目录下运行 `node ../scripts/verify-ai-security-tests.mjs`。 完整指南: [`docs/SECURITY.md`](./docs/SECURITY.md) ## 技术栈 | 层级 | 技术 | | ---------------- | --------------------------------------- | | 语言 | Python 3.11 | | RPC 框架 | gRPC (`grpcio` 1.80) | | 序列化 | Protocol Buffers (`grpcio-tools`) | | 推理 | Ollama HTTP API (本地宿主机) | | 生成模型 | `qwen2.5:7b-instruct-q4_K_M` (默认) | | Embedding 模型 | `nomic-embed-text` | | 测试 | pytest | | Proto 契约 | 嵌套的 `many_faces_proto` submodule | ## 项目结构 ``` many_faces_ai/ ├── proto/ # Generated Python stubs (from many_faces_proto) ├── scripts/ # proto generation, Docker dev, lint, verify-ci ├── server.py # gRPC server — all RPC servicers ├── moderation_input_sanitize.py # Untrusted-field normalization for ReviewContent ├── test_server.py # gRPC servicer tests (pytest) ├── test_moderation_input_sanitize.py # Sanitizer unit tests ├── services/ │ └── ai_model_service.py # Ollama HTTP adapter (generate + embed) ├── tests/ # Security regression tests (AIH1) ├── requirements.txt # Python dependencies ├── Dockerfile.dev # Dev image └── docs/ ├── SECURITY.md # AIH1 security guide ├── host-profile.md # GetHostProfile RPC + admin panel wiring ├── operator-live-stats-map-reduce.md # Legacy — replaced by RAG └── capability-roadmap-v0.9.0.md # Roadmap ``` ## 入门指南 ### 在 Docker 中运行 (推荐) ``` ./scripts/start-dev.sh ``` 启动位于 `localhost:50051` 的 gRPC 服务器容器。Ollama 必须在宿主机上运行。 ``` ./scripts/stop-dev.sh # stop ./scripts/clear-dev.sh # stop + remove containers and images ./scripts/rebuild-dev.sh # rebuild without starting ``` ### 不使用 Docker ``` pip install -r requirements.txt ./scripts/generate_proto.sh # generate proto stubs python3 server.py ``` ### 模型选择 ``` # 默认 export OLLAMA_MODEL="qwen2.5:7b-instruct-q4_K_M" export OLLAMA_BASE_URL="http://host.docker.internal:11434" # Low-VRAM tuning(4 GB GPU,partial offload) export OLLAMA_NUM_CTX=4096 export OLLAMA_NUM_THREAD=8 export OLLAMA_NUM_GPU=20 export OLLAMA_NUM_BATCH=128 export OLLAMA_KEEP_ALIVE=-1 export OLLAMA_FLASH_ATTENTION=1 export OLLAMA_KV_CACHE_TYPE=q8_0 ``` 模型权重存储在 **Ollama 的模型库**中,而不是在此容器内 —— 重建容器不会删除模型。 ## 配置 | 变量 | 用途 | | -------------------------- | --------------------------------------------- | | `OLLAMA_HOST` | Ollama HTTP 基础 URL | | `OLLAMA_MODEL` | 生成模型名称 | | `OLLAMA_NUM_CTX` | 上下文窗口 token 数 | | `OLLAMA_NUM_GPU` | 要卸载到 GPU 的层数 | | `OLLAMA_KEEP_ALIVE` | 设置为 `-1` 可使模型常驻内存 | | `OLLAMA_FLASH_ATTENTION` | 启用 Flash Attention (低 VRAM 环境) | | `OLLAMA_KV_CACHE_TYPE` | KV cache 精度 (4 GB 显存建议设为 `q8_0`) | | `GRPC_PORT` | gRPC 监听端口 (默认 `50051`) | | `GRPC_TLS_CERT_FILE` | TLS 证书路径 (启用 TLS) | | `GRPC_TLS_KEY_FILE` | TLS 私钥路径 | | `AI_WORKER_EXPECTED_TOKEN` | 必需的 `x-ai-worker-token` metadata 值 | ## 测试 ``` pytest # all tests pytest tests/ -k "security" # AIH1 security subset node ../scripts/verify-ai-security-tests.mjs # monorepo CI gate ``` ## 文档 | 文档 | 用途 | | ------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | | [`docs/SECURITY.md`](./docs/SECURITY.md) | AIH1 安全指南 —— 认证、TLS、SSRF、内容审核、生产环境检查清单 | | [`docs/host-profile.md`](./docs/host-profile.md) | Host profile RPC 及管理员设置面板的线路连接 | | [`docs/operator-live-stats-map-reduce.md`](./docs/operator-live-stats-map-reduce.md) | **旧版** map-reduce —— 降级回退方案;RAG 才是当前的生产路径 | | [`docs/capability-roadmap-v0.9.0.md`](./docs/capability-roadmap-v0.9.0.md) | AI 功能路线图 | | [`../docs/guides/operator-ai-rag-retrieval.md`](../docs/guides/operator-ai-rag-retrieval.md) | 完整的 RAG 架构 + 重建索引操作手册 | | [`../docs/guides/operator-ai-performance.md`](../docs/guides/operator-ai-performance.md) | 7B 调优指南 (GPU 层数、Flash Attention、快速路径) | | [`../docs/guides/admin-operator-ai-chat-threads.md`](../docs/guides/admin-operator-ai-chat-threads.md) | 操作员聊天线程、分页、留存策略 | | [`../docs/guides/ai-assisted-content-approval.md`](../docs/guides/ai-assisted-content-approval.md) | 内容审核 pipeline | | [`../docs/guides/operator-ai-skills.md`](../docs/guides/operator-ai-skills.md) | 技能路由 (统计、报告、审核问答、通用) | | [`../docs/readmes/ai-grpc-overview.md`](../docs/readmes/ai-grpc-overview.md) | Monorepo 级别的 AI gRPC 概览 | ## Proto 契约 标准的 `.proto` 文件位于 `many_faces_ai/many_faces_proto/` 下的嵌套 **`many_faces_proto`** submodule 中。 ``` git submodule update --init --recursive # populate nested submodule ./scripts/generate_proto.sh # regenerate Python stubs after proto changes ``` ## 未来功能建议 | 功能 | 描述 | | ------------------------------- | --------------------------------------------------------------------------------------- | | **Context 快照** | 后端提供的 payload,描述 faces、routes、页面 schema、roles 以及操作信号 | | **报告生成** | 用于管理员报告的类型化 RPC (face 健康状况、使用情况、内容缺口) | | **功能审查** | AI 辅助检查 face 页面完整性和网格安全性 | | **聊天风险评分** | 审查消息中是否包含垃圾信息、骚扰、可疑链接、prompt 注入 | | **可解释的推荐** | 响应中包含原因、置信度以及来源 context | | **审计友好的** | 记录请求 metadata 和模型决策,且不泄露敏感的用户内容 | ## 旧版:操作员统计 RPC ## 项目状态 Many Faces AI monorepo 的活跃 AI 适配器。v0.10.0 —— RAG 操作员聊天 (EmbedText + Generate + GenerateStream)、内容审核 (ReviewContent)、技能路由、Host profile,以及完整的 AIH1 安全回归测试套件。记录在 [`CHANGELOG.md`](./CHANGELOG.md) 中。
标签:AI微服务, AI风险缓解, DLL 劫持, Docker, gRPC, LLM评估, Ollama, Python, Python工具, 内容审核, 大语言模型, 安全规则引擎, 安全防御评估, 无后门, 请求拦截