agent detail 4

2026-03-05




# 離線 AI Agent 系統分析文件(SA)

 

> **版本**:1.0  

> **日期**:2026-03-05  

> **適用環境**:機構設計研發人員離線繪圖筆電 + 整合部後端伺服器  

> **文件定位**:本文件為可執行開發之系統分析文件,涵蓋系統架構、元件設計、資料模型、API 規格、流程定義及開發里程碑。

 

---

 

## 目錄

 

1. [專案概述](#1-專案概述)

2. [設計原則與約束](#2-設計原則與約束)

3. [系統架構總覽](#3-系統架構總覽)

4. [元件設計](#4-元件設計)

5. [資料模型與資料庫設計](#5-資料模型與資料庫設計)

6. [API 規格](#6-api-規格)

7. [核心流程定義](#7-核心流程定義)

8. [技術選型決策矩陣](#8-技術選型決策矩陣)

9. [安全性設計](#9-安全性設計)

10. [開發計畫與里程碑](#10-開發計畫與里程碑)

11. [驗收準則](#11-驗收準則)

12. [風險管理與降級策略](#12-風險管理與降級策略)

13. [交付物清單](#13-交付物清單)

14. [附錄:Mermaid 圖檔索引](#14-附錄mermaid-圖檔索引)

 

---

 

## 1. 專案概述

 

### 1.1 目標

 

建置一套部署於**離線環境**的 AI Agent 系統,提供機構設計研發人員以下能力:

 

- **文件知識庫**:批次匯入含文字與圖片的 PDF,建立可檢索的向量知識庫。

- **RAG 對話**:基於檢索增強生成(Retrieval-Augmented Generation)的智慧問答。

- **多模態支援**:處理文字與圖片的混合查詢與回應。

- **MCP/Skills 整合**:可插拔的工具與技能模組,擴展 Agent 能力。

 

### 1.2 使用者角色

 

| 角色 | 說明 |

|------|------|

| **研發工程師** | 主要使用者,透過 UI 或 CLI 進行 RAG 對話、上傳文件 |

| **系統管理員** | 負責部署、維護後端服務、管理使用者權限 |

| **整合人員** | 透過 RESTful API 將 Agent 能力串接至其他系統 |

 

### 1.3 系統邊界

 

```

┌─────────────────────────┐     內部網路      ┌──────────────────────────┐

│   Client(繪圖筆電)     │ ◄──────────────► │   Server(整合部 Host)    │

│ - UI / CLI              │    REST API       │ - API Gateway            │

│ - Local Agent Client    │    (TLS + Token)  │ - Inference Service      │

│ - Local Cache (SQLite)  │                   │ - RAG Pipeline           │

│ - Local Skills/MCP      │                   │ - PostgreSQL + pgvector  │

│ - Optional Local LLM    │                   │ - Document Processor     │

└─────────────────────────┘                   │ - MCP/Skills Engine      │

                                              └──────────────────────────┘

                                                        ▲

                                                        │ 批次匯入

                                              ┌─────────┴──────────┐

                                              │   KM 系統(文件來源)│

                                              └────────────────────┘

```

 

---

 

## 2. 設計原則與約束

 

### 2.1 強制約束

 

| 約束項目 | 說明 |

|----------|------|

| **離線運行** | 核心功能(推理、檢索、向量搜尋、文件匯入)必須在無外網環境運作 |

| **無 Docker** | 不以容器為部署單位,使用系統服務或 Python 虛擬環境 |

| **資源限制** | Client 端:~8GB RAM + 獨立 GPU(與 CAD 共享);需預留資源給 CAD 應用 |

| **資料庫** | PostgreSQL + pgvector 作為關聯式 + 向量資料庫 |

| **可複製部署** | 任何人依照本文件即可自行架設系統 |

 

### 2.2 設計原則

 

| 原則 | 實踐方式 |

|------|----------|

| **最小依賴** | 優先選擇輕量、單一用途的工具,避免全棧框架鎖定 |

| **可替換性** | 每個元件定義清晰介面,可獨立替換底層實作 |

| **漸進增強** | MVP 先跑通核心流程,再逐步增加多模態、安全性等功能 |

| **失敗安全** | 推理/檢索失敗時提供降級回應,不讓系統崩潰 |

 

### 2.3 推理引擎優先順序

 

```

1. llama.cpp        ← 首選(輕量、純 API、離線原生支援)

2. Foundry Local    ← 次選

3. LM Studio CLI   ← 需確認離線 API 能力

4. Ollama           ← 備援(功能較多但非必要)

```

 

---

 

## 3. 系統架構總覽

 

> 完整架構圖請參閱 [architecture.mmd](architecture.mmd)

 

### 3.1 分層架構

 

系統採用四層架構,Client 與 Server 透過 RESTful API 通訊:

 

```

┌──────────────────────────────────────────────────────┐

│                  Presentation Layer                   │

│  (Desktop UI / CLI / Web UI)                         │

├──────────────────────────────────────────────────────┤

│                  Client Agent Layer                   │

│  (連線管理 / 本地快取 / 離線 Skills / 本地推理)        │

├──────────────────────────────────────────────────────┤

│                  API Gateway Layer                    │

│  (認證 / 路由 / Rate Limiting / Request Validation)   │

├──────────────────────────────────────────────────────┤

│                  Service Layer                        │

│  ┌───────────┐ ┌───────────┐ ┌───────────────────┐   │

│  │ Inference │ │ Retrieval │ │ Document Processor│   │

│  │ Service   │ │ Service   │ │ Service           │   │

│  └───────────┘ └───────────┘ └───────────────────┘   │

│  ┌───────────┐ ┌───────────┐                         │

│  │ MCP/Skill │ │ Context   │                         │

│  │ Engine    │ │ Manager   │                         │

│  └───────────┘ └───────────┘                         │

├──────────────────────────────────────────────────────┤

│                  Data Layer                           │

│  (PostgreSQL + pgvector / File Storage)              │

└──────────────────────────────────────────────────────┘

```

 

### 3.2 部署拓撲

 

| 部署位置 | 元件 | 資源預算 |

|----------|------|----------|

| **Client(繪圖筆電)** | UI, Agent Client, SQLite Cache, Local Skills | RAM ≤ 1.5GB, GPU 共享 |

| **Server(整合部 Host)** | API Gateway, All Services, PostgreSQL, Model Files | RAM ≥ 16GB 建議, GPU 用於推理 |

 

---

 

## 4. 元件設計

 

### 4.1 Client 端元件

 

#### 4.1.1 UI 層(Presentation)

 

| 屬性 | 說明 |

|------|------|

| **技術選項** | Electron(桌面應用)或本地 Web UI(Flask/FastAPI 提供靜態頁面) |

| **啟動方式** | 桌面 icon 單擊啟動 |

| **功能** | 對話介面、文件上傳介面、系統狀態顯示 |

| **資源上限** | RAM ≤ 500MB |

 

#### 4.1.2 Agent Client

 

```python

# 模組結構

agent_client/

├── __init__.py

├── connection.py        # 伺服器連線管理(含斷線重連、健康檢查)

├── cache.py             # SQLite 本地快取管理

├── local_inference.py   # 本地推理(可選,quantized LLM)

├── skills/              # 本地 Skills/MCP 工具

│   ├── __init__.py

│   ├── base.py          # Skill 基底類別

│   ├── file_converter.py

│   └── cad_helper.py

└── config.py            # 設定管理

```

 

| 職責 | 說明 |

|------|------|

| **連線管理** | 維持與 Server API 的連線、自動重連、健康檢查 |

| **本地快取** | SQLite 存放近期對話、常用檢索結果、技能快取 |

| **離線 Skills** | 不需遠端的本地工具(檔案格式轉換、簡單計算等) |

| **本地推理** | (可選)使用 quantized LLM + llama.cpp 做簡單推理,RAM 限制 ≤ 2GB |

 

#### 4.1.3 Local Cache Schema(SQLite)

 

```sql

-- 對話快取

CREATE TABLE conversation_cache (

    id          TEXT PRIMARY KEY,

    session_id  TEXT NOT NULL,

    role        TEXT NOT NULL CHECK(role IN ('user', 'assistant', 'system')),

    content     TEXT NOT NULL,

    created_at  DATETIME DEFAULT CURRENT_TIMESTAMP,

    expires_at  DATETIME

);

 

-- 技能快取

CREATE TABLE skill_cache (

    key         TEXT PRIMARY KEY,

    value       BLOB,

    skill_name  TEXT NOT NULL,

    created_at  DATETIME DEFAULT CURRENT_TIMESTAMP,

    ttl_seconds INTEGER DEFAULT 3600

);

```

 

### 4.2 Server 端元件

 

#### 4.2.1 API Gateway

 

| 屬性 | 說明 |

|------|------|

| **框架** | FastAPI(Python,async 支援、自動 OpenAPI 文件) |

| **認證** | Bearer Token(JWT 或 API Key) |

| **傳輸** | HTTPS(TLS,內部 CA) |

| **功能** | 路由分發、請求驗證、Rate Limiting、錯誤處理 |

 

```python

# 模組結構

server/

├── main.py              # FastAPI 應用入口

├── api/

│   ├── __init__.py

│   ├── routes/

│   │   ├── upload.py    # 文件上傳相關端點

│   │   ├── query.py     # RAG 查詢端點

│   │   ├── document.py  # 文件管理端點

│   │   └── health.py    # 健康檢查

│   ├── deps.py          # 依賴注入(DB session, auth)

│   └── middleware.py    # 中介層(logging, CORS, rate limit)

├── core/

│   ├── config.py        # 環境設定

│   ├── security.py      # 認證與授權邏輯

│   └── exceptions.py    # 自訂例外

├── services/

│   ├── inference.py     # 推理服務介面

│   ├── retrieval.py     # 檢索服務

│   ├── document.py      # 文件處理服務

│   ├── embedding.py     # Embedding 服務

│   ├── context.py       # 上下文管理

│   └── skill_engine.py  # MCP/Skill 引擎

├── models/

│   ├── database.py      # SQLAlchemy ORM 模型

│   └── schemas.py       # Pydantic 請求/回應 schema

├── workers/

│   ├── doc_processor.py # 背景文件處理 worker

│   └── task_queue.py    # 任務佇列管理

└── utils/

    ├── chunking.py      # 文本切片策略

    ├── pdf_parser.py    # PDF 解析

    ├── ocr.py           # OCR 處理

    └── reranker.py      # Reranking 模組

```

 

#### 4.2.2 Inference Service(推理服務)

 

```

┌─────────────────────────────────────────┐

│          Inference Service              │

│                                         │

│  ┌──────────────────────────────────┐   │

│  │     Inference Adapter Interface  │   │

│  │     (統一介面)                    │   │

│  ├──────────────────────────────────┤   │

│  │  LlamaCppAdapter  (首選)         │   │

│  │  FoundryAdapter   (次選)         │   │

│  │  OllamaAdapter    (備援)         │   │

│  └──────────────────────────────────┘   │

│                                         │

│  ┌──────────────────────────────────┐   │

│  │     Context Manager              │   │

│  │  - Token 計數                    │   │

│  │  - Sliding Window                │   │

│  │  - Summarization Fallback        │   │

│  └──────────────────────────────────┘   │

└─────────────────────────────────────────┘

```

 

**Adapter Interface 定義:**

 

```python

from abc import ABC, abstractmethod

from dataclasses import dataclass

from typing import List, Optional

 

@dataclass

class InferenceRequest:

    messages: List[dict]          # [{"role": "user", "content": "..."}]

    max_tokens: int = 2048

    temperature: float = 0.7

    stop_sequences: Optional[List[str]] = None

 

@dataclass

class InferenceResponse:

    content: str

    usage: dict                   # {"prompt_tokens": N, "completion_tokens": M}

    model: str

    finish_reason: str

 

class InferenceAdapter(ABC):

    @abstractmethod

    async def generate(self, request: InferenceRequest) -> InferenceResponse:

        """送出推理請求並取得回應"""

        ...

 

    @abstractmethod

    async def health_check(self) -> bool:

        """檢查推理引擎是否可用"""

        ...

 

    @abstractmethod

    def get_context_limit(self) -> int:

        """回傳此引擎的 context window 上限(token 數)"""

        ...

```

 

#### 4.2.3 Retrieval Service(檢索服務)

 

| 職責 | 說明 |

|------|------|

| **向量檢索** | 使用 pgvector 的 cosine similarity 搜尋 |

| **Metadata 過濾** | 依來源、日期、文件類型等條件篩選 |

| **Reranking** | 使用 Cross-Encoder 對初步結果重新排序 |

| **Multi-hop** | 支援多輪檢索以處理複雜查詢 |

 

```python

@dataclass

class RetrievalResult:

    chunk_id: str

    content: str

    score: float                  # 相似度分數

    metadata: dict                # 來源、頁碼、檔案名稱等

    rerank_score: Optional[float] # reranking 後的分數

 

class RetrievalService:

    async def search(

        self,

        query_embedding: List[float],

        top_k: int = 10,

        filters: Optional[dict] = None

    ) -> List[RetrievalResult]:

        """向量相似搜尋 + metadata 篩選"""

        ...

 

    async def rerank(

        self,

        query: str,

        results: List[RetrievalResult],

        top_n: int = 5

    ) -> List[RetrievalResult]:

        """使用 Cross-Encoder 重新排序"""

        ...

 

    async def multi_hop_search(

        self,

        query: str,

        max_rounds: int = 3

    ) -> List[RetrievalResult]:

        """多輪檢索:檢索 → 生成中間查詢 → 再檢索"""

        ...

```

 

#### 4.2.4 Document Processor Service(文件處理服務)

 

```

文件上傳 ──► 格式偵測 ──► 解析 ──► 清理 ──► 切片 ──► Embedding ──► 存入 pgvector

                │                    │         │

                ▼                    ▼         ▼

           PDF: PyMuPDF         HTML清理    語意切片

           掃描PDF: Tesseract   去雜訊      固定長度切片

           圖片: PIL + CLIP     正規化      Overlap 切片

```

 

#### 4.2.5 MCP/Skill Engine

 

```python

class SkillRegistry:

    """技能註冊中心,管理所有可用的 MCP 工具與 Skills"""

 

    def register(self, skill: BaseSkill) -> None:

        """註冊一個 Skill"""

        ...

 

    def match(self, query: str, context: dict) -> Optional[BaseSkill]:

        """根據查詢內容與上下文,判斷是否有適合的 Skill"""

        ...

 

    def list_skills(self) -> List[SkillInfo]:

        """列出所有已註冊的 Skills"""

        ...

 

class BaseSkill(ABC):

    name: str

    description: str

    trigger_conditions: List[str]  # 觸發條件描述

 

    @abstractmethod

    async def execute(self, params: dict) -> dict:

        """執行 Skill 並回傳結果"""

        ...

 

    @abstractmethod

    def can_handle(self, query: str, context: dict) -> float:

        """回傳信心分數 0.0~1.0,表示此 Skill 處理該查詢的適合度"""

        ...

```

 

#### 4.2.6 Context Manager(上下文管理器)

 

處理 LLM context window 限制的核心元件:

 

```python

class ContextManager:

    """管理 LLM 的 context window,避免超限導致異常"""

 

    def __init__(self, max_tokens: int, strategy: str = "adaptive"):

        self.max_tokens = max_tokens

        self.strategy = strategy  # "truncate" | "summarize" | "adaptive"

 

    async def fit_context(

        self,

        system_prompt: str,

        conversation_history: List[dict],

        retrieved_chunks: List[str],

        reserved_for_output: int = 1024

    ) -> dict:

        """

        調整輸入使其符合 context window 限制。

 

        策略優先順序:

        1. 篩選/Rerank:取 top-k 最相關的檢索結果

        2. 精簡(Condense):摘要化多個片段

        3. 滑動窗口:截斷較早的對話歷史

        4. 錯誤回退:若推理仍異常,減少 context 並重試

 

        回傳:

        {

            "messages": [...],      # 調整後的訊息列表

            "total_tokens": N,      # 預估 token 數

            "strategy_used": "...", # 使用的策略

            "dropped_chunks": [...]  # 被丟棄的片段(供 logging)

        }

        """

        ...

 

    def count_tokens(self, text: str) -> int:

        """估算文本的 token 數"""

        ...

```

 

---

 

## 5. 資料模型與資料庫設計

 

> 完整 ER 圖請參閱 [database_schema.mmd](database_schema.mmd)

 

### 5.1 PostgreSQL Schema

 

```sql

-- ===================================================

-- 使用者與認證

-- ===================================================

CREATE TABLE users (

    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    username    VARCHAR(100) UNIQUE NOT NULL,

    password_hash VARCHAR(255) NOT NULL,

    role        VARCHAR(20) NOT NULL DEFAULT 'user'

                CHECK(role IN ('admin', 'user', 'viewer')),

    is_active   BOOLEAN DEFAULT TRUE,

    created_at  TIMESTAMPTZ DEFAULT NOW(),

    updated_at  TIMESTAMPTZ DEFAULT NOW()

);

 

CREATE TABLE api_tokens (

    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    user_id     UUID NOT NULL REFERENCES users(id),

    token_hash  VARCHAR(255) NOT NULL,

    name        VARCHAR(100),

    expires_at  TIMESTAMPTZ,

    created_at  TIMESTAMPTZ DEFAULT NOW()

);

 

-- ===================================================

-- 文件管理

-- ===================================================

CREATE TABLE documents (

    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    filename        VARCHAR(500) NOT NULL,

    original_path   TEXT,

    file_type       VARCHAR(20) NOT NULL,       -- 'pdf', 'image', 'zip'

    file_size_bytes BIGINT,

    file_hash       VARCHAR(64),                -- SHA-256 用於去重

    source          VARCHAR(100) DEFAULT 'upload', -- 'upload', 'km_system'

    uploaded_by     UUID REFERENCES users(id),

    status          VARCHAR(20) DEFAULT 'pending'

                    CHECK(status IN ('pending', 'processing', 'completed', 'failed')),

    error_message   TEXT,

    metadata        JSONB DEFAULT '{}',

    created_at      TIMESTAMPTZ DEFAULT NOW(),

    updated_at      TIMESTAMPTZ DEFAULT NOW()

);

 

CREATE INDEX idx_documents_status ON documents(status);

CREATE INDEX idx_documents_file_hash ON documents(file_hash);

 

-- ===================================================

-- 文件切片與向量

-- ===================================================

CREATE EXTENSION IF NOT EXISTS vector;

 

CREATE TABLE document_chunks (

    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    document_id     UUID NOT NULL REFERENCES documents(id) ON DELETE CASCADE,

    chunk_index     INTEGER NOT NULL,           -- 在原文件中的順序

    content         TEXT NOT NULL,              -- 文字內容

    content_type    VARCHAR(20) DEFAULT 'text'

                    CHECK(content_type IN ('text', 'image', 'table', 'mixed')),

    embedding       vector(768),               -- 文字 embedding 維度(依模型調整)

    image_embedding vector(512),               -- 圖像 embedding(CLIP,可選)

    token_count     INTEGER,

    metadata        JSONB DEFAULT '{}',        -- 頁碼、段落索引、座標等

    created_at      TIMESTAMPTZ DEFAULT NOW()

);

 

CREATE INDEX idx_chunks_document ON document_chunks(document_id);

CREATE INDEX idx_chunks_embedding ON document_chunks

    USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);

CREATE INDEX idx_chunks_image_embedding ON document_chunks

    USING ivfflat (image_embedding vector_cosine_ops) WITH (lists = 100);

 

-- ===================================================

-- 批次上傳任務

-- ===================================================

CREATE TABLE upload_tasks (

    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    user_id         UUID REFERENCES users(id),

    total_files     INTEGER NOT NULL DEFAULT 0,

    processed_files INTEGER NOT NULL DEFAULT 0,

    failed_files    INTEGER NOT NULL DEFAULT 0,

    status          VARCHAR(20) DEFAULT 'pending'

                    CHECK(status IN ('pending', 'processing', 'completed', 'partial', 'failed')),

    error_log       JSONB DEFAULT '[]',

    created_at      TIMESTAMPTZ DEFAULT NOW(),

    completed_at    TIMESTAMPTZ

);

 

CREATE TABLE upload_task_files (

    task_id     UUID NOT NULL REFERENCES upload_tasks(id) ON DELETE CASCADE,

    document_id UUID NOT NULL REFERENCES documents(id),

    PRIMARY KEY (task_id, document_id)

);

 

-- ===================================================

-- 對話與審計

-- ===================================================

CREATE TABLE conversations (

    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    user_id     UUID REFERENCES users(id),

    title       VARCHAR(500),

    created_at  TIMESTAMPTZ DEFAULT NOW(),

    updated_at  TIMESTAMPTZ DEFAULT NOW()

);

 

CREATE TABLE messages (

    id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    conversation_id UUID NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,

    role            VARCHAR(20) NOT NULL CHECK(role IN ('user', 'assistant', 'system')),

    content         TEXT NOT NULL,

    token_count     INTEGER,

    sources         JSONB DEFAULT '[]',         -- 引用的 chunk IDs 與置信度

    skill_used      VARCHAR(100),               -- 使用的 Skill 名稱

    model_used      VARCHAR(100),               -- 使用的模型名稱

    latency_ms      INTEGER,                    -- 回應延遲

    created_at      TIMESTAMPTZ DEFAULT NOW()

);

 

CREATE INDEX idx_messages_conversation ON messages(conversation_id);

 

-- ===================================================

-- MCP/Skills 註冊

-- ===================================================

CREATE TABLE skills (

    id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),

    name        VARCHAR(100) UNIQUE NOT NULL,

    description TEXT,

    version     VARCHAR(20),

    is_active   BOOLEAN DEFAULT TRUE,

    config      JSONB DEFAULT '{}',

    created_at  TIMESTAMPTZ DEFAULT NOW()

);

 

-- ===================================================

-- 審計日誌

-- ===================================================

CREATE TABLE audit_logs (

    id          BIGSERIAL PRIMARY KEY,

    user_id     UUID REFERENCES users(id),

    action      VARCHAR(50) NOT NULL,           -- 'query', 'upload', 'login', 'skill_exec'

    resource    VARCHAR(100),

    details     JSONB DEFAULT '{}',

    ip_address  INET,

    created_at  TIMESTAMPTZ DEFAULT NOW()

);

 

CREATE INDEX idx_audit_created ON audit_logs(created_at);

```

 

### 5.2 Embedding 維度規劃

 

| 用途 | 模型選項 | 維度 | 說明 |

|------|----------|------|------|

| 文字 Embedding | Sentence-BERT / BGE / Qwen-Embed | 768 | 切片文字向量化 |

| 圖像 Embedding | CLIP ViT-B/32 | 512 | 圖片特徵抽取 |

| 多模態 Embedding | CLIP Text + Vision | 512 | 統一文字圖片空間(可選) |

 

> **注意**:向量維度需依實際選用模型調整,上表為建議值。Schema 中 `vector(768)` 與 `vector(512)` 需對應實際值。

 

---

 

## 6. API 規格

 

### 6.1 共用約定

 

| 項目 | 規格 |

|------|------|

| **Base URL** | `https://{server_host}:{port}/api/v1` |

| **認證** | `Authorization: Bearer <token>` |

| **Content-Type** | `application/json`(查詢)/ `multipart/form-data`(上傳) |

| **錯誤格式** | `{"error": {"code": "ERR_XXX", "message": "..."}}` |

 

### 6.2 端點定義

 

#### 6.2.1 文件上傳

 

```

POST /api/v1/upload-batch

```

 

**Request**(multipart/form-data):

| 欄位 | 類型 | 必填 | 說明 |

|------|------|------|------|

| files | File[] | 是 | PDF、圖片或 ZIP 檔案(上限 50 個) |

| source | string | 否 | 來源標記,預設 `"upload"` |

| metadata | JSON string | 否 | 附加 metadata |

 

**Response**(202 Accepted):

```json

{

  "task_id": "550e8400-e29b-41d4-a716-446655440000",

  "total_files": 5,

  "status": "pending",

  "created_at": "2026-03-05T10:00:00Z"

}

```

 

#### 6.2.2 上傳進度查詢

 

```

GET /api/v1/upload-status/{task_id}

```

 

**Response**(200 OK):

```json

{

  "task_id": "550e8400-...",

  "status": "processing",

  "total_files": 5,

  "processed_files": 3,

  "failed_files": 0,

  "error_log": [],

  "progress_percent": 60.0

}

```

 

#### 6.2.3 RAG 查詢

 

```

POST /api/v1/query

```

 

**Request**:

```json

{

  "query": "這個零件的材質規格是什麼?",

  "conversation_id": "optional-uuid",

  "options": {

    "top_k": 5,

    "use_reranking": true,

    "enable_multi_hop": false,

    "filters": {

      "source": "design_manual",

      "file_type": "pdf"

    }

  }

}

```

 

**Response**(200 OK):

```json

{

  "answer": "根據設計手冊第 3.2 節,該零件主要材質為 SUS304 不鏽鋼...",

  "sources": [

    {

      "chunk_id": "abc-123",

      "document_id": "doc-456",

      "filename": "design_manual_v2.pdf",

      "page": 42,

      "relevance_score": 0.92,

      "content_preview": "3.2 材質規格:本零件採用 SUS304..."

    }

  ],

  "confidence": 0.87,

  "model_used": "qwen2-7b-q4",

  "skill_used": null,

  "conversation_id": "conv-789",

  "usage": {

    "prompt_tokens": 1520,

    "completion_tokens": 256,

    "retrieval_time_ms": 120,

    "inference_time_ms": 3400

  }

}

```

 

#### 6.2.4 文件查詢與下載

 

```

GET /api/v1/doc/{document_id}

```

 

**Response**(200 OK):

```json

{

  "id": "doc-456",

  "filename": "design_manual_v2.pdf",

  "file_type": "pdf",

  "file_size_bytes": 2048000,

  "source": "km_system",

  "status": "completed",

  "chunk_count": 47,

  "metadata": { "pages": 120, "author": "設計部" },

  "created_at": "2026-03-01T08:00:00Z"

}

```

 

```

GET /api/v1/doc/{document_id}/download

```

 

回傳原始檔案(`application/octet-stream`)。

 

#### 6.2.5 健康檢查

 

```

GET /api/v1/health

```

 

**Response**(200 OK):

```json

{

  "status": "healthy",

  "components": {

    "database": "ok",

    "inference_engine": "ok",

    "embedding_service": "ok"

  },

  "version": "1.0.0",

  "uptime_seconds": 86400

}

```

 

#### 6.2.6 對話歷史

 

```

GET /api/v1/conversations

GET /api/v1/conversations/{conversation_id}/messages

```

 

---

 

## 7. 核心流程定義

 

### 7.1 文件上傳與向量化流程

 

> Sequence 圖請參閱 [sequence_upload.mmd](sequence_upload.mmd)

 

```

步驟    動作                            負責元件                 失敗處理

────    ────                            ────────                 ────────

1       用戶上傳檔案(PDF/圖片/ZIP)     API Gateway              驗證格式,拒絕不支援類型

2       建立 upload_task 記錄           API → DB                 回傳 task_id

3       檔案寫入暫存目錄                 API Gateway              磁碟滿 → 回傳 503

4       觸發背景處理 Worker             Task Queue               Worker 不可用 → 標記 pending

5       格式偵測與解壓縮                 Document Processor       ZIP 損壞 → 記錄錯誤,跳過

6       PDF 解析                        pdf_parser               PyMuPDF 失敗 → fallback pdfminer

  6a    文字抽取                        PyMuPDF / pdfminer       —

  6b    圖像區塊抽取                    PyMuPDF                  —

  6c    掃描 PDF → OCR                  Tesseract                OCR 錯誤 → 記錄,存空白

7       文字清理與正規化                 Document Processor       —

8       文本切片(Chunking)             chunking module          —

  8a    語意/段落切片(優先)            —                        —

  8b    固定長度 + 重疊切片(備選)       —                        —

  8c    記錄 metadata(頁碼、段落索引)   —                        —

9       Embedding 生成                  Embedding Service        模型載入失敗 → 排入重試佇列

  9a    文字片段 → 文字 embedding       Sentence-BERT/BGE        —

  9b    圖像片段 → 圖像 embedding       CLIP                     —

10      寫入 document_chunks 表         DB(pgvector)           寫入失敗 → 重試 3 次

11      更新 document 狀態 → completed  DB                       —

12      更新 upload_task 計數           DB                       —

```

 

### 7.2 RAG 對話流程

 

> Sequence 圖請參閱 [sequence_rag.mmd](sequence_rag.mmd)

 

```

步驟    動作                              負責元件              說明

────    ────                              ────────              ────

1       接收使用者查詢                     API Gateway           含 query、conversation_id、options

2       載入對話歷史                       DB                    取最近 N 輪對話

3       查詢 Embedding 生成               Embedding Service     將 query 轉為向量

4       向量檢索                           Retrieval Service     pgvector cosine similarity

5       Metadata 篩選                     Retrieval Service     依 filters 參數過濾

6       Reranking(可選)                  Reranker              Cross-Encoder 重排序

7       Skill 匹配檢查                     Skill Engine          判斷是否需呼叫 MCP 工具

  7a    若匹配 → 執行 Skill               Skill Engine          取得 Skill 輸出

  7b    若不匹配 → 跳過                    —                     —

8       Context 組裝                       Context Manager       組合 system prompt + history + chunks

  8a    Token 計數                        Context Manager       確認不超過 context window

  8b    若超限 → 執行精簡策略              Context Manager       Rerank/Summarize/Truncate

9       送入 LLM 推理                      Inference Service     透過 Adapter 呼叫推理引擎

  9a    推理成功 → 取得回應                —                     —

  9b    推理異常 → 錯誤回退                Context Manager       減少 context 重試 / 降級回應

10      Answer Verification(可選)        Retrieval Service     用檢索片段驗證答案正確性

11      組裝回應(含來源、置信度)          API Gateway           —

12      儲存對話記錄                       DB                    messages 表

13      寫入審計日誌                       DB                    audit_logs 表

14      回傳回應給使用者                   API Gateway           —

```

 

### 7.3 上下文管理策略流程

 

```

輸入 token 數 = system_prompt + conversation_history + retrieved_chunks + reserved_output

                  │

                  ▼

           超過 context window?

            /           \

          否              是

          │               │

          ▼               ▼

      直接送入推理    ┌─ 策略 1: Top-K 篩選(降低 chunks 數量)

                     │     重新計算 token → 仍超限?

                     │        │

                     │       是

                     │        ▼

                     ├─ 策略 2: Summarize(合併 chunks 為摘要)

                     │     重新計算 token → 仍超限?

                     │        │

                     │       是

                     │        ▼

                     ├─ 策略 3: Sliding Window(截斷早期對話)

                     │     重新計算 token → 仍超限?

                     │        │

                     │       是

                     │        ▼

                     └─ 策略 4: 強制截斷 + 降級警告

```

 

---

 

## 8. 技術選型決策矩陣

 

### 8.1 推理引擎比較

 

| 評估項目 | llama.cpp | Foundry Local | LM Studio CLI | Ollama |

|----------|-----------|---------------|---------------|--------|

| **離線支援** | ✅ 原生 | ✅ 原生 | ⚠️ 需確認 | ✅ |

| **API 介面** | HTTP Server (OpenAI 相容) | REST API | ⚠️ 需確認 | REST + OpenAI 相容 |

| **資源需求** | 極低(純 C++) | 中等 | 中等 | 中等 |

| **Context 超限行為** | 明確截斷 | 待測 | 待測 | ⚠️ 可能回傳異常 |

| **社群活躍度** | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |

| **授權風險** | MIT(低風險) | 待確認 | 商業 | MIT→ 需追蹤 |

| **更新頻率** | 每週 | 月度 | 月度 | 每週 |

| **GPU 加速** | CUDA/Metal/Vulkan | DirectML | CUDA | CUDA/Metal |

| **優先等級** | 🥇 首選 | 🥈 次選 | 🥉 需評估 | 🔄 備援 |

 

### 8.2 LLM 模型選項

 

| 模型 | 參數量 | 量化 | RAM 需求 | 授權 | 適用場景 |

|------|--------|------|----------|------|----------|

| Qwen2-7B | 7B | Q4_K_M | ~5GB | Apache 2.0 | 主力對話推理 |

| Gemma3-9B | 9B | Q4_K_M | ~6GB | Gemma License | 備選對話推理 |

| Qwen2-VL-7B | 7B | Q4 | ~5GB | Apache 2.0 | 多模態(含視覺) |

| LLaMA3-8B | 8B | Q4_K_M | ~5GB | Meta License | 英文場景 |

| BGE-M3 | — | FP16 | ~1GB | MIT | 文字 Embedding |

| CLIP ViT-B/32 | — | FP16 | ~0.5GB | MIT | 圖像 Embedding |

 

### 8.3 其他技術選型

 

| 元件 | 選型 | 替代方案 | 理由 |

|------|------|----------|------|

| **Web 框架** | FastAPI | Flask | Async 支援、自動 OpenAPI 文件 |

| **ORM** | SQLAlchemy 2.0 | — | 成熟、支援 async |

| **任務佇列** | Celery + Redis 或 Python asyncio | RQ | 離線環境可用 Redis;若不裝則用 asyncio |

| **PDF 解析** | PyMuPDF | pdfminer.six | 速度快、支援圖像抽取 |

| **OCR** | Tesseract + pytesseract | PaddleOCR | 離線可用、多語言 |

| **Reranker** | Cross-Encoder (sentence-transformers) | BGE-Reranker | 離線可用 |

| **Client UI** | Electron 或 Tauri | Flask 本地 Web | 桌面體驗 |

| **本地 Cache** | SQLite | — | 輕量、零配置 |

 

---

 

## 9. 安全性設計

 

### 9.1 網路安全

 

```

┌─────────────┐                    ┌──────────────────┐

│  Client     │──── TLS 1.2+ ────►│  Server          │

│  (內部網段)  │     API Token     │  (整合部網段)     │

└─────────────┘                    │                  │

                                   │  僅開放端口:      │

                                   │  - 443 (HTTPS)   │

                                   │  - 5432 (PG,     │

                                   │    僅 localhost)  │

                                   └──────────────────┘

```

 

### 9.2 認證與授權

 

| 機制 | 實作方式 |

|------|----------|

| **使用者認證** | JWT Token(有效期 24h)或長期 API Key |

| **權限模型** | RBAC(admin / user / viewer) |

| **密碼儲存** | bcrypt hash |

 

### 9.3 權限矩陣

 

| 操作 | admin | user | viewer |

|------|-------|------|--------|

| 上傳文件 | ✅ | ✅ | ❌ |

| RAG 查詢 | ✅ | ✅ | ✅ |

| 下載文件 | ✅ | ✅ | ✅ |

| 管理使用者 | ✅ | ❌ | ❌ |

| 查看審計日誌 | ✅ | ❌ | ❌ |

| 管理 Skills | ✅ | ❌ | ❌ |

 

### 9.4 資料保護

 

- **備份策略**:PostgreSQL `pg_dump` 每日排程備份,保留 7 天

- **檔案加密**:視需求啟用磁碟層級加密(BitLocker / LUKS)

- **審計日誌**:所有 API 操作記錄至 `audit_logs` 表,不可刪除

 

---

 

## 10. 開發計畫與里程碑

 

### 10.1 總覽時程

 

```

Week  0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18

      ├──M1──┤                                                    環境 + MVP

               ├─────M2─────┤                                     文件匯入

                              ├─────M3──────┤                     RAG 對話

                                              ├─────M4─────┤     多模態 + 前端

                                                             ├──M5──┤ 安全+部署

      ├─────E1──────┤                                             推理引擎評估

                     ├──E2──┤                                     效能測試

```

 

### 10.2 M1:環境準備與 MVP(第 0–2 週)

 

| 工作項目 | 交付物 | 負責 |

|----------|--------|------|

| PostgreSQL + pgvector 安裝與設定 | 可連線的 DB、pgvector 擴充啟用 | 後端 |

| Python 虛擬環境建置 | `requirements.txt`、venv 建立腳本 | 後端 |

| FastAPI 骨架建置 | `/health` 端點可回應 | 後端 |

| llama.cpp 安裝與測試 | 本地推理可透過 HTTP API 呼叫 | 後端 |

| Inference Adapter 介面定義 | `InferenceAdapter` ABC | 後端 |

| LlamaCppAdapter 實作 | 可呼叫 llama.cpp 的 adapter | 後端 |

| 基礎 DB Schema 建立 | Migration 腳本(Alembic) | 後端 |

| 開發環境文件 | `docs/setup.md` | 全員 |

 

**M1 驗收條件**:

- [x] `GET /api/v1/health` 回傳 200

- [x] llama.cpp 可載入量化模型並回應簡單 prompt

- [x] PostgreSQL + pgvector 可進行向量寫入/查詢

 

### 10.3 M2:文件匯入與向量化 Pipeline(第 3–6 週)

 

| 工作項目 | 交付物 | 負責 |

|----------|--------|------|

| PDF 解析模組 | `pdf_parser.py`(文字 + 圖像抽取) | 後端 |

| OCR 模組 | `ocr.py`(Tesseract 整合) | 後端 |

| Chunking 模組 | `chunking.py`(語意切片 + 固定長度切片) | 後端 |

| Embedding 服務 | `embedding.py`(文字 + 圖像 embedding) | 後端 |

| 批次上傳 API | `POST /api/v1/upload-batch` | 後端 |

| 任務狀態 API | `GET /api/v1/upload-status/{task_id}` | 後端 |

| 背景 Worker | `doc_processor.py`(非同步文件處理) | 後端 |

| 文件管理 API | `GET /api/v1/doc/{id}` | 後端 |

| 單元測試 | 各模組測試(≥ 80% coverage) | 後端 |

 

**M2 驗收條件**:

- [x] 上傳 1 個 PDF → 系統完成解析、切片、embedding、存入 pgvector

- [x] 批次上傳 10 個 PDF → 任務狀態 API 正確回報進度

- [x] 支援含圖片的 PDF 與掃描 PDF

 

### 10.4 M3:RAG 與基本對話 API(第 7–10 週)

 

| 工作項目 | 交付物 | 負責 |

|----------|--------|------|

| Retrieval Service | `retrieval.py`(向量搜尋 + metadata filter) | 後端 |

| Reranker 模組 | `reranker.py`(Cross-Encoder) | 後端 |

| Context Manager | `context.py`(token 管理、精簡策略) | 後端 |

| RAG 查詢 API | `POST /api/v1/query` | 後端 |

| Prompt 組裝邏輯 | System prompt + context template | 後端 |

| MCP/Skill Engine 基礎框架 | `skill_engine.py` + `BaseSkill` | 後端 |

| 範例 Skill x 2 | 檔案查詢 Skill、計算 Skill | 後端 |

| 對話歷史 API | conversations 相關端點 | 後端 |

| RAG 精準度基準測試 | 測試報告(含 reranking 效果比較) | 後端 |

| 整合測試 | 上傳 → 檢索 → 回應端到端測試 | 全員 |

 

**M3 驗收條件**:

- [x] 上傳文件後,RAG 查詢可回傳正確答案與來源

- [x] Reranking 啟用後精準度提升可量化

- [x] context 超限時系統不崩潰,正確降級

- [x] 至少 1 個 Skill 可被自動觸發

 

### 10.5 M4:多模態支援與前端整合(第 11–14 週)

 

| 工作項目 | 交付物 | 負責 |

|----------|--------|------|

| 圖像 Embedding 支援 | CLIP 整合至 pipeline | 後端 |

| 多模態查詢處理 | 支援含圖片的查詢 | 後端 |

| Client Agent 開發 | `agent_client/`(連線、快取、離線 skills) | 前端 |

| 桌面 UI 或 CLI 工具 | 可操作的前端介面 | 前端 |

| Local Cache 實作 | SQLite 快取模組 | 前端 |

| Client ↔ Server 整合測試 | 端到端功能驗證 | 全員 |

 

**M4 驗收條件**:

- [x] 圖片文件可被正確 embedding 並檢索

- [x] 前端 UI 可完成上傳、查詢、查看來源的完整流程

- [x] Client 離線時 Local Skills 可獨立運作

 

### 10.6 M5:安全性強化與部署文件(第 15–18 週)

 

| 工作項目 | 交付物 | 負責 |

|----------|--------|------|

| JWT 認證實作 | `security.py` | 後端 |

| TLS 設定 | 內部 CA 憑證 + HTTPS 設定 | 運維 |

| RBAC 權限控制 | 中介層權限檢查 | 後端 |

| 備份排程 | `pg_dump` cron job + 腳本 | 運維 |

| 審計日誌完善 | 所有端點 audit logging | 後端 |

| 部署手冊 | `docs/deployment.md`(可複製步驟) | 全員 |

| 維運手冊 | `docs/operations.md` | 全員 |

| Mermaid 圖檔定版 | 所有 `.mmd` 圖檔 | 全員 |

 

**M5 驗收條件**:

- [x] 無 Token 的請求被拒絕(401)

- [x] 非 admin 無法存取管理端點(403)

- [x] 備份腳本可自動執行

- [x] 新人可依部署手冊在新環境完成安裝

 

### 10.7 E1-E2:推理引擎評估(並行,第 0–6 週)

 

| 階段 | 工作內容 | 交付物 |

|------|----------|--------|

| **E1(第 0–4 週)** | 功能矩陣比較:llama.cpp / Foundry Local / LM Studio CLI / Ollama | 比較報告(含 API 支援、離線能力、資源使用、授權分析) |

| **E2(第 4–6 週)** | 效能與穩定性測試(含 context 超限邊界測試) | 測試報告(含錯誤模式與回退策略建議) |

 

---

 

## 11. 驗收準則

 

### 11.1 系統級驗收

 

| 項次 | 驗收條件 | 對應里程碑 |

|------|----------|-----------|

| AC-1 | 在離線環境下,從文件上傳 → 向量化 → 檢索 → RAG 回應完整走通 | M3 |

| AC-2 | 批次匯入 100 篇 PDF,處理成功率 ≥ 90% | M2 |

| AC-3 | RAG 回答包含來源 metadata(檔案名、頁碼)且通過功能驗收 | M3 |

| AC-4 | 推理引擎在 context 超限時不崩潰,系統正確降級 | M3 |

| AC-5 | 多模態查詢(含圖片)可正確回應 | M4 |

| AC-6 | TLS + Token 認證在所有端點生效 | M5 |

| AC-7 | 新環境部署可在 4 小時內完成 | M5 |

 

### 11.2 效能指標(參考值)

 

| 指標 | 目標值 | 量測方式 |

|------|--------|----------|

| 單文件向量化延遲 | ≤ 30 秒 / 頁 | M2 階段測試 |

| RAG 查詢延遲(端到端) | ≤ 15 秒 | M3 階段測試 |

| 向量檢索延遲(10K chunks) | ≤ 500ms | M3 階段測試 |

| 系統 RAM 佔用(Server) | ≤ 12GB | 持續監控 |

| Client RAM 佔用 | ≤ 1.5GB | M4 階段測試 |

 

---

 

## 12. 風險管理與降級策略

 

| 風險項目 | 可能性 | 影響 | 降級策略 |

|----------|--------|------|----------|

| Ollama 授權變更或停止維護 | 中 | 中 | 降級至 llama.cpp(已有 Adapter) |

| LLM 模型授權限制收緊 | 低 | 高 | 切換至其他 Apache 2.0 / MIT 授權模型 |

| Agent 框架(Dify/LangFlow)商業化 | 中 | 中 | 回退至 LangChain 純程式化實作 |

| GPU 記憶體不足以執行推理 | 中 | 高 | 使用更小量化模型(Q2/Q3)或純 CPU 推理 |

| Tesseract OCR 辨識率不佳 | 中 | 低 | 替換為 PaddleOCR 或 EasyOCR |

| pgvector 效能瓶頸(>100K chunks) | 低 | 中 | 加入 HNSW 索引、分區表 |

| 模型 embedding 維度不匹配 | 低 | 高 | Schema migration + 重新 embedding |

 

---

 

## 13. 交付物清單

 

| 交付物 | 格式 | 狀態 |

|--------|------|------|

| SA 文件(本檔) | Markdown | ✅ |

| [architecture.mmd](architecture.mmd) — 系統架構圖 | Mermaid | ✅ |

| [use_case.mmd](use_case.mmd) — Use Case 圖 | Mermaid | ✅ |

| [uml_class.mmd](uml_class.mmd) — UML Class 圖 | Mermaid | ✅ |

| [database_schema.mmd](database_schema.mmd) — Database ER 圖 | Mermaid | ✅ |

| [sequence_rag.mmd](sequence_rag.mmd) — RAG 對話 Sequence 圖 | Mermaid | ✅ |

| [sequence_upload.mmd](sequence_upload.mmd) — 文件上傳 Sequence 圖 | Mermaid | ✅ |

| 原始碼 | Python | 依里程碑交付 |

| 部署手冊 | Markdown | M5 交付 |

| 維運手冊 | Markdown | M5 交付 |

 

---

 

## 14. 附錄:Mermaid 圖檔索引

 

| 圖檔 | 說明 |

|------|------|

| [architecture.mmd](architecture.mmd) | 系統整體架構圖,展示 Client/Server 元件與資料流 |

| [use_case.mmd](use_case.mmd) | 使用者與系統互動的 Use Case 圖 |

| [uml_class.mmd](uml_class.mmd) | 核心類別的 UML Class 圖(Adapter, Service, Skill 等) |

| [database_schema.mmd](database_schema.mmd) | PostgreSQL 資料表的 ER 圖 |

| [sequence_rag.mmd](sequence_rag.mmd) | RAG 對話流程的 Sequence 圖 |

| [sequence_upload.mmd](sequence_upload.mmd) | 文件上傳與向量化流程的 Sequence 圖 |

 

---

 

> **文件維護**:本文件隨開發迭代更新。每個里程碑結束時,需檢視並更新對應章節內容。

 







Login to like - 0 Likes



Comments...


No Comments Yet...



Add Comment...



shumin

A graduated biotechnology engineer. Now is a software engineer


Latest Posts



Footer with Icons