← بازگشت به صفحه اصلی
Architecture

معماری سرویس استخراج اطلاعات

مستند زنده معماری پیاده‌سازی‌شده: مرز مسئولیت در پلتفرم Patent Genie، قراردادهای RabbitMQ، خط لوله LangGraph، مسیر dev ingest و استقرار Docker.

اجزای اصلی

این جدول ownership و رابط هر جزء را نشان می‌دهد. core-api، RabbitMQ و Object Storage وابستگی‌های بیرونی این repository هستند.

جزء نقش رابط رفتار مهم
core-api (بیرون از این مخزن) مالک پرونده، آپلود سند و orchestrator استخراج ناهمزمان RabbitMQ: patent_genie.events DocumentExtractionRequested را publish می‌کند و completed/failed را از inbox دریافت و متن نرمال‌شده را در Object Storage ذخیره می‌کند.
FastAPI API health، ATP، صفحه معماری و dev ingest همزمان docker-compose profile: api · /api/v1/* POST /api/v1/dev/ingest/extract فقط در APP_ENV=local|docker-dev فعال است؛ Swagger در production به‌طور پیش‌فرض غیرفعال است.
Extraction worker مصرف‌کننده DocumentExtractionRequested و اجرای خط لوله LangGraph queue: document.extraction.requested فایل اصلی را از Object Storage می‌خواند، checksum را اعتبارسنجی می‌کند و متن نرمال‌شده را inline در completed منتشر می‌کند.
LangGraph intake pipeline validate → parse (pdf/docx/txt) → normalize src/graphs/intake_graph.py PDF با PyPDFLoader، PyMuPDF و OCR fallback؛ DOCX/TXT با loader اختصاصی؛ خروجی صفحات نرمال‌شده با metadata کیفیت و زبان.
RabbitMQ انتقال durable رویدادهای requested، completed و failed exchange: patent_genie.events Topic exchange، صف document.extraction.requested با prefetch=1؛ خطاهای retryable دوباره در صف قرار می‌گیرند.
Object Storage (S3/Ceph) ذخیره فایل اصلی سند؛ worker فقط read-only bucket: storage_bucket در رویداد کلید artifact با workspace_id اعتبارسنجی می‌شود؛ worker نتیجه را روی دیسک پایدار نمی‌نویسد.
OCR engine fallback برای PDF اسکن‌شده یا متن ضعیف src/ingestion/ocr.py وقتی متن native از PDF کوتاه‌تر از آستانه باشد، OCR فارسی/انگلیسی اجرا می‌شود؛ فایل‌های موقت پس از پردازش حذف می‌شوند.

مرز سرویس در پلتفرم

این مخزن مسئول پارس و نرمال‌سازی متن خام PDF، DOCX و TXT است. core-api مالک پرونده و وضعیت محصول است؛ ai-workflow روی متن نرمال‌شده استخراج زمینه اختراع انجام می‌دهد.

flowchart TB
  user["کاربر / Frontend"]
  core["core-api<br/>مالک پرونده"]
  store[("S3 / Ceph<br/>فایل اصلی + artifact متن")]
  aw["ai-workflow<br/>استخراج زمینه اختراع"]

  user --> core
  core -->|"آپلود سند"| store

  subgraph extraction ["info-extraction — این مخزن"]
    direction LR
    docReq["RabbitMQ<br/>document.extraction.requested"]
    worker["extraction-worker<br/>LangGraph intake"]
    docResult["RabbitMQ<br/>document.extraction.completed / failed"]
    docReq --> worker --> docResult
  end

  core --> docReq
  store -->|"خواندن read-only"| worker
  docResult -->|"متن نرمال‌شده inline"| core
  core -->|"ذخیره artifact متن"| store
  core -->|"context.extraction.requested"| aw
  store -->|"خواندن متن نرمال‌شده"| aw

مسیر ناهمزمان (RabbitMQ)

در production، core-api رویداد درخواست را publish می‌کند. extraction-worker با prefetch=1 هر پیام را پردازش می‌کند و رویداد terminal را به exchange برمی‌گرداند.

flowchart TB
  core["core-api"]
  ex[("Topic exchange<br/>patent_genie.events")]
  q["queue: document.extraction.requested<br/>prefetch=1"]
  worker["extraction-worker<br/>extraction_job.process_*"]
  s3[("S3 / Ceph<br/>read-only")]
  inbox["core.document.extraction.events"]
  validate["validate_event + artifact key + checksum"]
  intake["ingest_document<br/>LangGraph"]
  publish["publish completed / failed"]

  core -->|"DocumentExtractionRequested"| ex --> q --> worker
  s3 -->|"download_object"| worker
  worker --> validate --> intake --> publish
  publish --> ex --> inbox --> core

خط لوله LangGraph (intake)

همه مسیرها — production worker و dev ingest — از یک گراف LangGraph validate → parse → normalize عبور می‌کنند.

flowchart TB
  input["PDF / DOCX / TXT"]
  validate["validate_input<br/>detect file type"]
  pdf["parse_pdf<br/>native → PyMuPDF → OCR"]
  docx["parse_docx"]
  txt["parse_txt"]
  normalize["normalize_text<br/>Persian + language + quality"]
  out["normalized_pages + warnings"]
  input --> validate
  validate -->|"pdf"| pdf --> normalize
  validate -->|"docx"| docx --> normalize
  validate -->|"txt"| txt --> normalize
  normalize --> out

مسیر HTTP همزمان

FastAPI برای health، ATP، معماری و dev ingest در دسترس است. مسیر dev ingest همان intake graph را بدون RabbitMQ اجرا می‌کند.

flowchart TB
  client["Client / Swagger / ATP"]
  api["FastAPI — info-extraction/api"]
  home["GET /"]
  health["GET /api/v1/health"]
  atp["GET /atp/*"]
  arch["GET /architecture/"]
  dev["POST /api/v1/dev/ingest/extract<br/>dev only"]
  intakePipeline["ingest_document<br/>LangGraph"]
  response["DevIngestResponse<br/>pages + full text + metrics"]
  client --> api
  api --> home
  api --> health
  api --> atp
  api --> arch
  api --> dev --> intakePipeline --> response

استقرار Docker Compose

Compose دو profile دارد: api برای HTTP و extraction-worker برای مصرف RabbitMQ. RabbitMQ و S3/Ceph روی شبکه external patent-genie-local باید از قبل در دسترس باشند.

flowchart TB
  subgraph compose ["docker-compose.yml"]
    api["api (profile: api)<br/>uvicorn :8000 --reload"]
    worker["extraction-worker (profile: worker)<br/>run_event_worker.py"]
  end
  net[["external network<br/>patent-genie-local"]]
  rmq[("RabbitMQ :5672")]
  s3[("S3 / Ceph rgw:7480")]
  api --- net
  worker --- net
  net --- rmq
  net --- s3