定制 owner888/smart-book 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

owner888/smart-book

最新稳定版本:v1.0.0

Composer 安装命令:

composer require owner888/smart-book

包简介

Smart Book AI Server - RAG-based book Q&A with Gemini AI, supporting EPUB parsing, vector search, and MCP protocol

README 文档

README

Latest Version on Packagist License PHP Version

基于 Workerman 的智能书籍问答服务,支持 RAG(检索增强生成)。

安装

通过 Composer 安装

composer require owner888/smart-book

手动安装

git clone https://github.com/owner888/smart-book.git
cd smart-book
composer install

功能特性

  • 📚 RAG 问答 - 基于书籍内容的智能问答
  • 🔍 混合检索 - 关键词 + 向量双重检索
  • 💬 流式响应 - 支持 SSE 和 WebSocket 实时流式输出
  • 🚀 高性能 - 基于 Workerman 异步架构
  • 💾 智能缓存 - Redis 缓存 + 语义相似度匹配

快速开始

1. 安装依赖

composer install

2. 配置环境

cp .env.example .env
# 编辑 .env 文件,填入 GEMINI_API_KEY

3. 启动服务

php server.php start          # 前台运行
php server.php start -d       # 后台运行
php server.php stop           # 停止
php server.php restart        # 重启
php server.php status         # 状态

4. 访问

目录结构

smart-book/
├── config/                     # 配置文件
│   ├── app.php                 # 应用配置(端口、AI、书籍路径)
│   ├── database.php            # 数据库/Redis 配置
│   └── prompts.php             # AI 提示词配置
│
├── src/                        # 源代码
│   ├── AI/                     # AI 客户端
│   │   ├── GeminiClient.php    # Gemini API 同步客户端
│   │   ├── AsyncGeminiClient.php # Gemini API 异步客户端
│   │   ├── AsyncCurlManager.php  # curl_multi 异步管理器
│   │   └── AIService.php       # AI 服务统一管理
│   │
│   ├── Cache/                  # 缓存服务
│   │   ├── CacheService.php    # Redis 缓存(问答/语义索引)
│   │   └── RedisVectorStore.php # Redis 8.0 向量存储
│   │
│   ├── RAG/                    # RAG 系统
│   │   ├── EmbeddingClient.php # 向量嵌入客户端
│   │   ├── VectorStore.php     # 本地向量存储
│   │   ├── DocumentChunker.php # 文档分块器
│   │   └── BookRAGAssistant.php # RAG 书籍助手
│   │
│   ├── Parser/                 # 文档解析器
│   │   └── EpubParser.php      # EPUB 解析器
│   │
│   └── Http/                   # HTTP 处理
│       └── Handlers.php        # 请求处理函数
│
├── static/                     # 静态资源
│   ├── css/main.css
│   └── js/main.js
│
├── tests/                      # 测试文件
│   ├── test_ai.php
│   ├── test_rag.php
│   └── ...
│
├── bootstrap.php               # 初始化/自动加载
├── server.php                  # 服务入口
├── chat.html                   # Web 聊天界面
├── .env.example                # 环境变量模板
└── composer.json               # 依赖配置

API 接口

HTTP API

接口 方法 说明
/api/health GET 健康检查
/api/ask POST RAG 问答(非流式)
/api/chat POST 通用聊天(非流式)
/api/stream/ask POST RAG 问答(SSE 流式)
/api/stream/chat POST 通用聊天(SSE 流式)
/api/cache/stats GET 缓存统计

WebSocket API

连接 ws://localhost:8081,发送 JSON:

{"action": "ask", "question": "孙悟空的师父是谁?"}
{"action": "chat", "messages": [{"role": "user", "content": "你好"}]}

MCP Server API (Streamable HTTP)

MCP Server 运行在端口 8089,实现 MCP 2025-11-25 Streamable HTTP Transport 协议。

端点: http://localhost:8089/mcp

方法 说明
GET 获取服务器信息和能力
POST JSON-RPC 请求(支持批量)
DELETE 终止会话

会话管理:

  • 服务器通过 Mcp-Session-Id HTTP Header 管理会话
  • initialize 请求会创建新会话并返回 Session ID
  • 后续请求应携带 Session ID 以保持状态

JSON-RPC 请求示例:

# 1. 初始化会话
curl -X POST http://localhost:8089/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","clientInfo":{"name":"test","version":"1.0"}},"id":1}'

# 2. 获取工具列表
curl -X POST http://localhost:8089/mcp \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: <session_id>" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":2}'

# 3. 调用工具 - 列出书籍
curl -X POST http://localhost:8089/mcp \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: <session_id>" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"list_books","arguments":{}},"id":3}'

# 4. 调用工具 - 搜索书籍
curl -X POST http://localhost:8089/mcp \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: <session_id>" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"search_book","arguments":{"query":"孙悟空"}},"id":4}'

可用工具:

工具名 说明 参数
list_books 列出所有可用书籍
get_book_info 获取当前书籍信息
select_book 选择要使用的书籍 book: 书籍文件名
search_book 在书籍中搜索内容 query: 搜索词, top_k: 结果数量(可选)

stdio 模式:

也支持 stdio 协议,用于 Cline/Cherry Studio 等客户端:

php mcp-stdio.php

技术架构

Smart Book 系统架构

┌─────────────────────────────────────────────────────────────────────────────┐
│                              Smart Book AI Server                            │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐        │
│  │   chat.html     │     │   HTTP Client   │     │ WebSocket Client│        │
│  │   (Web UI)      │     │   (curl/fetch)  │     │   (Browser)     │        │
│  └────────┬────────┘     └────────┬────────┘     └────────┬────────┘        │
│           │                       │                       │                  │
│           └───────────────────────┼───────────────────────┘                  │
│                                   ▼                                          │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                        Workerman Server                              │    │
│  │  ┌─────────────────────┐         ┌─────────────────────┐            │    │
│  │  │   HTTP Worker       │         │  WebSocket Worker   │            │    │
│  │  │   (Port: 8088)      │         │   (Port: 8089)      │            │    │
│  │  └──────────┬──────────┘         └──────────┬──────────┘            │    │
│  └─────────────┼───────────────────────────────┼───────────────────────┘    │
│                │                               │                             │
│                └───────────────┬───────────────┘                             │
│                                ▼                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                      src/Http/Handlers.php                           │    │
│  │                    (路由分发 / 请求处理)                              │    │
│  └────────────┬────────────────────────────────────┬───────────────────┘    │
│               │                                    │                         │
│               ▼                                    ▼                         │
│  ┌────────────────────────┐           ┌────────────────────────┐            │
│  │     src/AI/            │           │    src/Cache/          │            │
│  │  ┌──────────────────┐  │           │  ┌──────────────────┐  │            │
│  │  │  GeminiClient    │  │           │  │  CacheService    │  │            │
│  │  │  (同步 API)      │  │           │  │  (Redis 缓存)    │  │            │
│  │  └──────────────────┘  │           │  └──────────────────┘  │            │
│  │  ┌──────────────────┐  │           │  ┌──────────────────┐  │            │
│  │  │ AsyncGeminiClient│  │           │  │ RedisVectorStore │  │            │
│  │  │  (异步流式)      │  │           │  │ (Redis 8.0 向量) │  │            │
│  │  └──────────────────┘  │           │  └──────────────────┘  │            │
│  │  ┌──────────────────┐  │           └────────────────────────┘            │
│  │  │ AsyncCurlManager │  │                                                  │
│  │  │ (curl_multi)     │  │                                                  │
│  │  └──────────────────┘  │                                                  │
│  └────────────┬───────────┘                                                  │
│               │                                                              │
│               ▼                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                         src/RAG/                                     │    │
│  │  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐   │    │
│  │  │ EmbeddingClient  │  │   VectorStore    │  │ DocumentChunker  │   │    │
│  │  │ (text-embedding) │  │  (混合检索)      │  │  (文档分块)      │   │    │
│  │  └──────────────────┘  └──────────────────┘  └──────────────────┘   │    │
│  │  ┌──────────────────────────────────────────────────────────────┐   │    │
│  │  │                   BookRAGAssistant                            │   │    │
│  │  │              (RAG 问答编排 / 上下文构建)                      │   │    │
│  │  └──────────────────────────────────────────────────────────────┘   │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│  ┌────────────────────────┐           ┌────────────────────────┐            │
│  │    src/Parser/         │           │    config/prompts.php  │            │
│  │  ┌──────────────────┐  │           │  ┌──────────────────┐  │            │
│  │  │   EpubParser     │  │           │  │  AI 提示词配置    │  │            │
│  │  │  (EPUB 解析)     │  │           │  │ (与 Python 同步)  │  │            │
│  │  └──────────────────┘  │           │  └──────────────────┘  │            │
│  └────────────────────────┘           └────────────────────────┘            │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘
                                   │
                                   ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                           External Services                                  │
│  ┌─────────────────────┐         ┌─────────────────────┐                    │
│  │   Google Gemini API │         │       Redis         │                    │
│  │   (LLM + Embedding) │         │  (缓存 + 向量存储)  │                    │
│  └─────────────────────┘         └─────────────────────┘                    │
└─────────────────────────────────────────────────────────────────────────────┘

RAG 问答流程

用户提问 ──► 语义缓存检查 ──► 命中? ──► 返回缓存
                │              │
                │ 未命中        │
                ▼              │
         生成问题 Embedding     │
                │              │
                ▼              │
         混合检索 (关键词+向量)  │
                │              │
                ▼              │
         构建上下文 Prompt      │
                │              │
                ▼              │
         调用 Gemini API       │
                │              │
                ▼              │
         流式返回 + 缓存结果 ◄──┘

数据流式传输架构

┌─────────────────────────────────────────────────────────────────────────────┐
│                           流式传输架构                                       │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌─────────────┐                                                             │
│  │   Browser   │                                                             │
│  └──────┬──────┘                                                             │
│         │                                                                    │
│         ▼                                                                    │
│  ┌──────────────────────────────────────────────────────────────────────┐   │
│  │                    SSE (Server-Sent Events)                          │   │
│  │                    POST /api/stream/ask                              │   │
│  └──────────────────────────────────────────────────────────────────────┘   │
│         │                                                                    │
│         │  HTTP Response Headers:                                            │
│         │  Content-Type: text/event-stream                                   │
│         │  Cache-Control: no-cache                                           │
│         │                                                                    │
│         ▼                                                                    │
│  ┌──────────────────────────────────────────────────────────────────────┐   │
│  │                      Handlers.php                                    │   │
│  │                                                                      │   │
│  │  handleStreamAskAsync()                                              │   │
│  │       │                                                              │   │
│  │       ├──► sendSSE('sources', json)     // 发送检索来源              │   │
│  │       │                                                              │   │
│  │       └──► AsyncGeminiClient::chatStreamAsync()                      │   │
│  │                   │                                                  │   │
│  │                   ├──► onChunk(text) ──► sendSSE('content', text)    │   │
│  │                   │                       // 实时发送 AI 输出        │   │
│  │                   │                                                  │   │
│  │                   └──► onComplete() ──► sendSSE('done', '')          │   │
│  │                                          // 发送完成信号             │   │
│  └──────────────────────────────────────────────────────────────────────┘   │
│         │                                                                    │
│         ▼                                                                    │
│  ┌──────────────────────────────────────────────────────────────────────┐   │
│  │                    AsyncCurlManager                                  │   │
│  │                                                                      │   │
│  │  ┌────────────────────────────────────────────────────────────────┐ │   │
│  │  │  curl_multi_init()                                              │ │   │
│  │  │       │                                                         │ │   │
│  │  │       ▼                                                         │ │   │
│  │  │  Workerman Timer (10ms 轮询)                                    │ │   │
│  │  │       │                                                         │ │   │
│  │  │       ▼                                                         │ │   │
│  │  │  curl_multi_exec() ──► CURLOPT_WRITEFUNCTION                    │ │   │
│  │  │       │                      │                                  │ │   │
│  │  │       │                      ▼                                  │ │   │
│  │  │       │               解析 SSE 数据流                           │ │   │
│  │  │       │               data: {"candidates":...}                  │ │   │
│  │  │       │                      │                                  │ │   │
│  │  │       │                      ▼                                  │ │   │
│  │  │       │               onData callback ──► onChunk()             │ │   │
│  │  │       │                                                         │ │   │
│  │  │       ▼                                                         │ │   │
│  │  │  curl_multi_info_read() ──► onComplete callback                 │ │   │
│  │  └────────────────────────────────────────────────────────────────┘ │   │
│  └──────────────────────────────────────────────────────────────────────┘   │
│         │                                                                    │
│         ▼                                                                    │
│  ┌──────────────────────────────────────────────────────────────────────┐   │
│  │                     Gemini API (streamGenerateContent)               │   │
│  │                                                                      │   │
│  │  SSE 响应格式:                                                       │   │
│  │  data: {"candidates":[{"content":{"parts":[{"text":"..."}]}}]}      │   │
│  │  data: {"candidates":[{"content":{"parts":[{"text":"..."}]}}]}      │   │
│  │  ...                                                                 │   │
│  └──────────────────────────────────────────────────────────────────────┘   │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

SSE 事件类型:
┌──────────────┬─────────────────────────────────────┐
│ Event        │ Data                                │
├──────────────┼─────────────────────────────────────┤
│ sources      │ [{"text":"...", "score":95.2}, ...] │
│ cached       │ {"hit":true, "similarity":98.5}     │
│ content      │ "AI 生成的文本片段..."               │
│ done         │ ""                                  │
│ error        │ "错误信息"                           │
└──────────────┴─────────────────────────────────────┘

WebSocket 消息类型:
┌──────────────┬─────────────────────────────────────┐
│ Type         │ Data                                │
├──────────────┼─────────────────────────────────────┤
│ sources      │ {"type":"sources", "sources":[...]} │
│ content      │ {"type":"content", "content":"..."}│
│ done         │ {"type":"done"}                     │
│ error        │ {"error":"错误信息"}                 │
└──────────────┴─────────────────────────────────────┘

配置说明

.env 配置

# AI API
GEMINI_API_KEY=your_api_key_here

# 服务端口
HTTP_PORT=8088
WS_PORT=8089

# Redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379

config/app.php

return [
    'server' => [
        'http_port' => getenv('HTTP_PORT') ?: 8088,
        'ws_port' => getenv('WS_PORT') ?: 8089,
    ],
    'ai' => [
        'gemini' => [
            'api_key' => getenv('GEMINI_API_KEY'),
            'model' => 'gemini-2.5-flash',
        ],
    ],
    'books' => [
        'default' => [
            'path' => '/path/to/book.epub',
            'cache' => '/path/to/index.json',
        ],
    ],
];

依赖

  • PHP 8.0+
  • workerman/workerman
  • workerman/redis (异步 Redis)
  • ext-curl
  • ext-zip
  • ext-mbstring

License

MIT

统计信息

  • 总下载量: 1
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-01-08