مستند زنده معماری پیادهسازیشده: مرز مسئولیت سرویسها، قراردادهای HTTP و رویداد،
جریان داده و artifact، جزئیات workerها، خط لولههای AI و استقرار فعلی Docker.
اجزای اصلی
این جدول ownership و رابط هر جزء را نشان میدهد. core-api، RabbitMQ، Object Storage
و providerهای AI وابستگیهای بیرونی این repository هستند.
جزء
نقش
رابط
رفتار مهم
core-api (بیرون از این مخزن)
مالک پرونده و orchestrator گردشکارهای ناهمزمان
RabbitMQ: patent_genie.events
کلید artifactها را در رویداد درخواست میفرستد و نتیجه workerها را از inboxها دریافت میکند.
info-extraction (بیرون از این مخزن)
پارس PDF/DOCX/TXT، OCR و نرمالسازی متن
queue: document.extraction.requested
فایل اصلی را read-only از Object Storage میخواند و normalized_text_inline را در completed برمیگرداند؛ chunking، embedding و Milvus ندارد.
FastAPI API
رابط HTTP همزمان برای health، استخراج، پیشینه فنی، claims و description
docker-compose: api · /api/v1/*
استخراج فقط فایل UTF-8 با پسوند .txt میپذیرد؛ search، report، draft/claims و draft/description ورودی JSON دارند.
Context extraction worker
استخراج زمینه اختراع و مدیریت چرخه سؤالهای تکمیلی
queue: context.extraction.requested
artifactهای ورودی را فقط میخواند و snapshot را داخل رویداد منتشر میکند؛ inbox در core-api آن را در DB و S3 پایدار میسازد.
Prior-art search worker
جستجوی پیشینه فنی، غنیسازی IPC/CPC و رتبهبندی مراجع
queue: prior_art.search.requested
InventionContext را از Object Storage میخواند و نتیجه JSON بههمراه manifest را در آن مینویسد.
Prior-art report worker
تولید گزارش فارسی پیشینه فنی
queue: prior_art.report.requested
نتیجه search را میخواند و report.md، report JSON و manifest را ذخیره میکند.
Claims draft worker
تولید ادعانامه فارسی از context و نتیجه جستجوی پیشینه
queue: draft.claims.requested
ورودیها را فقطخواندنی از S3 میگیرد و claims_draft را inline در completed برمیگرداند؛ خروجی را در Object Storage نمینویسد.
Description draft worker
تولید توصیف و خلاصه فارسی از context، claims و prior-art اختیاری
queue: draft.description.requested
ورودیها فقطخواندنیاند؛ description_draft (شامل abstract جدا) inline در completed منتشر میشود و progress مرحلهبهمرحله دارد.
RabbitMQ
انتقال durable رویدادهای requested، progress، completed، questions_required و failed
exchange: patent_genie.events
Topic exchange، صفهای durable، prefetch=1 و DLX مستقل patent_genie.dlx دارد.
Object Storage (S3/Ceph)
انتقال artifactهای حجیم میان core-api و workerها
bucket: OBJECT_STORAGE_BUCKET_NAME
info-extraction، context و draft workerها دسترسی read-only دارند؛ workerهای prior-art دسترسی read/write برای JSON، manifest و report دارند.
LLM و providerهای بیرونی
استخراج ساختیافته، عاملهای ReAct، جستجو، واکشی محتوا و rerank
provider فعال از environment انتخاب میشود؛ tracing اختیاری با Langfuse در عاملهای draft پشتیبانی میشود.
مرز سرویس در پلتفرم
این مخزن لایه اجرای AI است، نه مالک پرونده و نه پردازشگر فایل خام. core-api وضعیت محصول را نگه میدارد؛ info-extraction متن را از PDF/DOCX/TXT استخراج میکند؛ ai-workflow روی متن نرمالشده، InventionContext، prior-art و پیشنویس claims/description کار میکند.
ورودی این سرویس متن UTF-8 (.txt) یا JSON ساختیافته PatentContextExtractionInput است؛ PDF، DOCX و OCR در info-extraction انجام میشود.
core-api با info-extraction از طریق RabbitMQ در ارتباط است: document.extraction.requested را منتشر و completed یا failed را از inbox دریافت میکند.
info-extraction فایل اصلی را read-only از S3/Ceph میخواند و متن نرمالشده را inline در completed میفرستد؛ core-api آن را بهعنوان artifact در Object Storage ذخیره میکند.
info-extraction فقط پارس، OCR و نرمالسازی میکند؛ بدون chunking، embedding یا Milvus.
core-api کلید artifact متن نرمالشده را در context.extraction.requested به ai-workflow میفرستد؛ context worker آن را read-only از Object Storage میخواند.
پس از آمادهشدن InventionContext و (در صورت نیاز) prior-art، core-api میتواند draft.claims.requested و سپس draft.description.requested را با کلید artifactهای ورودی منتشر کند.
ذخیره نهایی پرونده، اعمال مجوزها و تصمیم درباره مرحله بعد بر عهده core-api است.
یکپارچهسازی async استخراج زمینه در core-api پیادهسازی شده است؛ قرارداد workerهای prior-art و draft در این مخزن آماده است، اما publisher/inbox متناظر prior-art و draft هنوز در core-api فعلی دیده نمیشود.
flowchart TB
user["کاربر / Frontend"] --> core["core-api"]
core --> store[("S3 / Ceph")]
providers["LLM / Search / Rerank"]
subgraph stage1 ["1. Document extraction"]
direction LR
docReq["document.extraction.requested"] --> ie["info-extraction"] --> docDone["completed / failed"]
end
subgraph stage2 ["2. Context extraction"]
direction LR
ctxReq["context.extraction.requested"] --> ctxW["context worker"] --> ctxDone["completed / questions_required / failed"]
end
subgraph stage3 ["3. Drafting contract"]
direction LR
draftReq["draft.claims / description.requested"] --> draftW["claims + description workers"] --> draftDone["progress / completed / failed"]
end
core --> docReq
store -.-> ie
docDone --> core
core --> ctxReq
store -.-> ctxW
ctxDone --> core
ctxW --> providers
core -.-> draftReq
store -.-> draftW
draftDone -.-> core
draftW --> providers
مسیر HTTP همزمان
FastAPI مسیر مستقیمی برای توسعه، Swagger، ATP و یکپارچهسازی همزمان فراهم میکند. هر درخواست تا پایان فراخوانیهای AI باز میماند و RabbitMQ در این مسیر دخیل نیست.
POST /api/v1/extract فقط multipart file با پسوند .txt، کدگذاری UTF-8 و سقف API_MAX_UPLOAD_MB میپذیرد؛ خروجی شامل context، missing_questions، failures و metrics است.
POST /api/v1/prior-art/search یک InventionContext یا {context: ...} میگیرد و فقط نتیجه مرحله جستجو را برمیگرداند (include_report=false).
POST /api/v1/prior-art/report کل خروجی search را میگیرد و JSON گزارش یا فایل Markdown قابل دانلود برمیگرداند؛ report بهطور خودکار بعد از search اجرا نمیشود.
POST /api/v1/draft/claims: InventionContext + PriorArtSearchResult → claims JSON یا Markdown فارسی (.claims.md) از Claims ReAct agent.
POST /api/v1/draft/description: context + claims_draft + prior_art اختیاری → description JSON با markdown_fa و abstract_markdown_fa جدا؛ download=true/description یا download=abstract.
GET /، /atp/، /architecture/: صفحات HTML فارسی برای health، ATP و معماری.
Swagger/ReDoc فقط در local، docker-dev یا با ENABLE_API_DOCS=true فعال است. در کد فعلی middleware احراز هویت API وجود ندارد و CORS روی همه originها باز است.
در مسیر تولید، core-api رویداد درخواست حاوی شناسهها و کلید artifact را publish میکند. هر worker فقط صف اختصاصی خود را با prefetch=1 مصرف میکند و نتیجه terminal را به exchange برمیگرداند.
Context worker متن را با client فقطخواندنی از Object Storage میگیرد؛ snapshot را inline در event منتشر میکند و inbox سمت core-api آن را در PostgreSQL و S3 ذخیره میکند.
شکاف outstanding فقط severity برابر BLOCKING یا HIGH است؛ MEDIUM/LOW completed را مسدود نمیکنند. HIGH بهتنهایی questions_required میفرستد (severity سؤال: recommended) و BLOCKING با severity=blocking در question_round میآید.
completeness_summary شامل blocking_gap_count و outstanding_gap_count است. پس از حداکثر CONTEXT_EXTRACTION_MAX_QUESTION_ROUNDS (پیشفرض ۲) خروجی forced-complete با forced_complete_after_max_rounds منتشر میشود.
Search worker نتیجه JSON و manifest؛ Report worker خروجی Markdown، JSON و manifest را در Object Storage مینویسند. manifest باعث idempotency و republish امن completed در تحویل مجدد میشود.
Claims و description workerها ورودی را فقط از S3 میخوانند، کلیدها را با workspace_id validate میکنند، و payload نتیجه را inline در completed برمیگردانند (بدون نوشتن نتیجه به Object Storage). description رویداد progress تفصیلی دارد.
رویدادهای context کل snapshot را حمل میکنند؛ prior-art فقط کلید artifact، checksum، اندازه و manifest را برمیگردانند؛ draft نتیجه ساختیافته را inline حمل میکند.
صفهای requested به DLX متصلاند. خطاهای شناختهشده توسط handler به failed تبدیل و ack میشوند؛ خطای مدیریتنشده مانند payload نامعتبر reject شده و به DLQ میرود.
مرحله report و draft مستقلاند: orchestrator پس از مشاهده نتیجه قبلی باید requested بعدی را جداگانه منتشر کند؛ orchestration سمت core-api برای prior-art و draft هنوز پیادهسازی نشده است.
تنها پروفایل فعلی sectioned-device-parallel-fulltext است: ورودی یکبار آماده میشود، شش بخش مستقل همزمان استخراج میشوند و compiler آنها را به مدل canonical تبدیل میکند.
A: مسئله و پیشینه؛ B: اجزا؛ C: توپولوژی؛ D: ویژگیهای ابتکاری؛ E: آثار فنی؛ F: دامنه و جایگزینها.
ThreadPoolExecutor با حداکثر ۶ worker اجرا میشود و در حالت عادی هر thread نمونه LLM مستقل دارد تا structured-output schemaها با هم تداخل نکنند.
هر node retry دارد و nodeهای retryable ناموفق میتوانند در recovery pass دوباره اجرا شوند؛ شکست جزئی در section_failures ثبت میشود.
Compiler (مرحله G) InventionContext، provenance، missing_questions و آمادگی را میسازد؛ metrics شامل زمان nodeها و مصرف LLM در پاسخ HTTP قابل مشاهده است.
در مسیر async، snapshot_mapping فقط gaps با severity برابر BLOCKING یا HIGH را outstanding میشمارد و readiness_state را questions_required میکند؛ MEDIUM/LOW مانع completed نیستند.
داده ساختگی مجاز نیست: مقادیر باید به متن منبع متصل باشند و شکافها بهصورت missing یا inferred همراه دلیل ثبت شوند.
flowchart TB
input["PatentContextExtractionInput / .txt"] --> n0["N0 prepare"]
n0 --> parallel["A B C D E F parallel extract"]
parallel --> compile["G canonical compiler"]
parallel -.-> recovery["retry + recovery"] -.-> compile
compile --> out["InventionContext + missing_questions"]
out --> gaps["snapshot_mapping outstanding = BLOCKING or HIGH"]
gaps --> ready{"outstanding gaps?"}
ready -->|yes| qr["questions_required"]
ready -->|no| done["completed or forced-complete"]
خط لوله پیشینه فنی
پیشینه فنی دو مرحله مستقل دارد: عامل جستجو مراجع و شواهد را تولید میکند؛ عامل گزارش فقط پس از دریافت PriorArtSearchResult، مراجع منتخب را تحلیل و گزارش فارسی میسازد.
ابتدا خلاصه راهکار و featureهای فنی از InventionContext استخراج و عناصر جستجو با LLM تولید میشوند.
عامل LangGraph ReAct جستجو را با محدودیت تعداد step/call اجرا میکند؛ provider تنظیمشده Tavily است که در حالت AvalAI از ابزار Tavily آن و در حالت OpenAI از TavilyClient استفاده میکند.
نتایج normalize و deduplicate میشوند، متن منتخب با Firecrawl غنی میشود، کدهای IPC/CPC استخراج و برای refinement استفاده میشوند و در صورت فعال بودن با مدل Cohere از طریق AvalAI rerank میشوند.
خروجی search شامل strategy، records، references، classification candidates، preliminary report، warnings، trace و metrics است؛ این جستجو جایگزین جستجوی رسمی اداره ثبت اختراع نیست.
عامل report حداکثر top-k مرجع (پیشفرض ۳) را انتخاب، محتوای آنها را واکشی و تحلیل مقایسهای تولید میکند؛ خروجی نهایی Markdown فارسی است و در خطا ممکن است fallback template همراه warning برگردد.
flowchart TB
subgraph prepare ["۱. آمادهسازی جستجو"]
direction LR
ctx["InventionContext"] --> features["Technical summary + features"] --> terms["LLM search elements"]
end
subgraph retrieval ["۲. جستجو و غنیسازی"]
direction LR
agent["LangGraph ReAct ۳ ابزار جستجو"] --> search["Tavily AvalAI tool یا TavilyClient"] --> enrich["Firecrawl + IPC enrichment IPC refinement searches"]
end
subgraph ranking ["۳. رتبهبندی و خروجی جستجو"]
direction LR
normalize["Normalize + dedupe references"] --> rerank["Cohere rerank via AvalAI اختیاری"] --> result["PriorArtSearchResult"]
end
subgraph reporting ["۴. تولید گزارش — درخواست مستقل"]
direction LR
select["انتخاب top-k + metadata enrichment"] --> report["Report ReAct agent ۷ ابزار تحلیل"] --> doc["Persian synthesis JSON / Markdown"]
end
terms --> agent
enrich --> normalize
result -.->|"درخواست مرحله دوم"| select
خط لوله پیشنویس ادعا و توصیف
پیشنویس دو مرحله متوالی دارد: Claims ReAct agent ادعانامه ساختیافته میسازد؛ Description ReAct agent از context، claims و prior-art اختیاری، توصیف و خلاصه جدا تولید میکند.
ورودی claims: InventionContext + PriorArtSearchResult؛ خروجی schema claims.v2 با لایههای grounding، prose، claims، validation و markdown_fa.
ورودی description: context + PatentClaimsDraft (+ prior_art اختیاری)؛ خروجی description.v2 با sections، support_matrix، markdown_fa و abstract_markdown_fa جدا.
HTTP: download برای claims فایل .claims.md؛ برای description مقدار true/description → .description.md و abstract → .abstract.md.
Workerها کلید artifact را با workspace_id validate میکنند؛ کلید نامعتبر → failed با INVALID_ARTIFACT_KEY (non-retryable).
Claims خالی یا validation.is_valid≠true بهعنوان Completed منتشر نمیشود (CLAIMS_GENERATION_ERROR). description رویدادهای progress مرحلهای (plan/section/validation) دارد.
نتیجه draft در Object Storage نوشته نمیشود؛ payload در رویداد completed به inbox قرارداد core.draft.events میرود.
Compose شش container از یک image میسازد: یک API و پنج process worker. RabbitMQ و S3 داخل این compose تعریف نشدهاند و باید از قبل روی شبکه external در دسترس باشند.
API پورت داخلی 8000 را روی ${API_PORT:-8002} منتشر میکند و اکنون uvicorn را با --reload و bind-mountهای src/data/docs/logs اجرا میکند.
workerها پورت عمومی و healthcheck فعال ندارند و با restart: unless-stopped اجرا میشوند.
هر پنج worker به rabbitmq:5672 و s3:7480 روی شبکه patent-genie-local متصل میشوند؛ credentialها و تنظیمات provider از .env میآیند.