Skip to content

Latest commit

ย 

History

History
747 lines (649 loc) ยท 53.4 KB

File metadata and controls

747 lines (649 loc) ยท 53.4 KB

PubMed Search MCP - ็ณป็ตฑๆžถๆง‹ๆ–‡ไปถ

Architecture Documentation | ็ณป็ตฑๆžถๆง‹่จญ่จˆ่ชชๆ˜Ž

๐Ÿ“‹ ็›ฎ้Œ„


็ณป็ตฑ็ธฝ่ฆฝ

PubMed Search MCP ๆ˜ฏไธ€ๅ€‹ๅŸบๆ–ผ Domain-Driven Design (DDD) ็š„ MCP ไผบๆœๅ™จ๏ผŒๅฐˆ็‚บ AI Agent ๆไพ›ๆ™บๆ…งๆ–‡็ป็ ”็ฉถ่ƒฝๅŠ›ใ€‚

่จญ่จˆๅŽŸๅ‰‡

ๅŽŸๅ‰‡ ่ชชๆ˜Ž
Agent-First ่ผธๅ‡บๆ ผๅผๅ„ชๅŒ–็‚บๆฉŸๅ™จๆฑบ็ญ–๏ผŒ้žไบบ้กž้–ฑ่ฎ€
Task-Oriented ๅทฅๅ…ทไปฅ็ ”็ฉถไปปๅ‹™็‚บๅ–ฎไฝ๏ผŒ่€Œ้žๅบ•ๅฑค API
Domain-Driven ไปฅๆ–‡็ป็ ”็ฉถ้ ˜ๅŸŸ็Ÿฅ่ญ˜็‚บๆ ธๅฟƒๅปบๆจก
Context-Aware ้€้Ž Session ็ถญๆŒ็ ”็ฉถ็‹€ๆ…‹

DDD ้ ˜ๅŸŸ้ฉ…ๅ‹•่จญ่จˆ

็›ฎ้Œ„็ตๆง‹

src/pubmed_search/
โ”œโ”€โ”€ mcp/
โ”‚   โ”œโ”€โ”€ tools/                    # Application Layer - MCP ๅทฅๅ…ท
โ”‚   โ”‚   โ”œโ”€โ”€ discovery.py          # ๆŽข็ดขๅž‹ๅทฅๅ…ท (search, related, citing)
โ”‚   โ”‚   โ”œโ”€โ”€ strategy.py           # ็ญ–็•ฅๅž‹ๅทฅๅ…ท (generate_queries, expand)
โ”‚   โ”‚   โ”œโ”€โ”€ pico.py               # PICO ่งฃๆž
โ”‚   โ”‚   โ”œโ”€โ”€ merge.py              # ็ตๆžœๅˆไฝต
โ”‚   โ”‚   โ”œโ”€โ”€ export.py             # ๅŒฏๅ‡บๅทฅๅ…ท
โ”‚   โ”‚   โ”œโ”€โ”€ citation_tree.py      # ๅผ•็”จ็ถฒ็ตก่ฆ–่ฆบๅŒ–
โ”‚   โ”‚   โ””โ”€โ”€ _common.py            # ๅ…ฑ็”จๅทฅๅ…ทๅ‡ฝๆ•ธ
โ”‚   โ”œโ”€โ”€ session_tools.py          # Session ็ฎก็† (ๅ…ง้ƒจ)
โ”‚   โ””โ”€โ”€ server.py                 # MCP Server ๅ…ฅๅฃ
โ”‚
โ”œโ”€โ”€ entrez/                       # Infrastructure Layer - NCBI API
โ”‚   โ”œโ”€โ”€ searcher.py               # ๆ–‡็ปๆœๅฐ‹ๅ™จ
โ”‚   โ”œโ”€โ”€ fetcher.py                # ๆ–‡็ซ ่ฉณๆƒ…็ฒๅ–
โ”‚   โ””โ”€โ”€ mesh.py                   # MeSH ่ฉžๅฝ™ๆŸฅ่ฉข
โ”‚
โ”œโ”€โ”€ exports/                      # Infrastructure Layer - ๅŒฏๅ‡บๆ ผๅผ
โ”‚   โ”œโ”€โ”€ ris.py                    # RIS ๆ ผๅผ
โ”‚   โ”œโ”€โ”€ bibtex.py                 # BibTeX ๆ ผๅผ
โ”‚   โ”œโ”€โ”€ csv_export.py             # CSV ๆ ผๅผ
โ”‚   โ””โ”€โ”€ medline.py                # MEDLINE ๆ ผๅผ
โ”‚
โ”œโ”€โ”€ domain/                       # Domain Layer - ้ ˜ๅŸŸๆจกๅž‹
โ”‚   โ”œโ”€โ”€ entities/
โ”‚   โ”‚   โ”œโ”€โ”€ article.py            # ๆ–‡็ซ ๅฏฆ้ซ”
โ”‚   โ”‚   โ””โ”€โ”€ search_result.py      # ๆœๅฐ‹็ตๆžœ
โ”‚   โ””โ”€โ”€ value_objects/
โ”‚       โ”œโ”€โ”€ pmid.py               # PMID ๅ€ผ็‰ฉไปถ
โ”‚       โ””โ”€โ”€ query.py              # ๆŸฅ่ฉขๅ€ผ็‰ฉไปถ
โ”‚
โ”œโ”€โ”€ session.py                    # Session ็ฎก็† (ๅ…ง้ƒจๆฉŸๅˆถ)
โ””โ”€โ”€ client.py                     # Python Client API

ๅˆ†ๅฑคๆžถๆง‹ (Onion Architecture)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                              Presentation Layer                              โ”‚
โ”‚                         (MCP Protocol / HTTP API)                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                              Application Layer                               โ”‚
โ”‚                   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚
โ”‚                   โ”‚           MCP Tools                  โ”‚                   โ”‚
โ”‚                   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚                   โ”‚
โ”‚                   โ”‚  โ”‚Discoveryโ”‚  โ”‚Strategy โ”‚  โ”‚Exportโ”‚ โ”‚                   โ”‚
โ”‚                   โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚                   โ”‚
โ”‚                   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                               Domain Layer                                   โ”‚
โ”‚                   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚
โ”‚                   โ”‚         Domain Services              โ”‚                   โ”‚
โ”‚                   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚                   โ”‚
โ”‚                   โ”‚  โ”‚   Search   โ”‚  โ”‚ Citation Tree โ”‚  โ”‚                   โ”‚
โ”‚                   โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚                   โ”‚
โ”‚                   โ”‚         Domain Entities              โ”‚                   โ”‚
โ”‚                   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚                   โ”‚
โ”‚                   โ”‚  โ”‚Article โ”‚  โ”‚ Query  โ”‚  โ”‚Sessionโ”‚  โ”‚                   โ”‚
โ”‚                   โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚                   โ”‚
โ”‚                   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                            Infrastructure Layer                              โ”‚
โ”‚     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”               โ”‚
โ”‚     โ”‚ NCBI Entrez  โ”‚    โ”‚   Exports    โ”‚    โ”‚    Cache     โ”‚               โ”‚
โ”‚     โ”‚     API      โ”‚    โ”‚  (RIS, Bib)  โ”‚    โ”‚   (Memory)   โ”‚               โ”‚
โ”‚     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

MCP ๅทฅๅ…ทๅˆ†ๅฑค

ๅทฅๅ…ทๅˆ†้กž (14 ๅ€‹ๅทฅๅ…ท)

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                            MCP Tools (14)                                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                      Discovery Tools (8)                             โ”‚    โ”‚
โ”‚  โ”‚  ๆŽข็ดขๅž‹ๅทฅๅ…ท - ๆœๅฐ‹ใ€็™ผ็พใ€ๆŽข็ดขๆ–‡็ป                                      โ”‚    โ”‚
โ”‚  โ”‚                                                                      โ”‚    โ”‚
โ”‚  โ”‚  โ€ข search_literature      ๆœๅฐ‹ PubMed ๆ–‡็ป                           โ”‚    โ”‚
โ”‚  โ”‚  โ€ข find_related_articles  ๅฐ‹ๆ‰พไธป้กŒ็›ธไผผๆ–‡็ซ  (PubMed algorithm)         โ”‚    โ”‚
โ”‚  โ”‚  โ€ข find_citing_articles   ๅฐ‹ๆ‰พๅผ•็”จๆญคๆ–‡็š„่ซ–ๆ–‡ (Forward โžก๏ธ)             โ”‚    โ”‚
โ”‚  โ”‚  โ€ข get_article_references ๅ–ๅพ—ๆญคๆ–‡็š„ๅƒ่€ƒๆ–‡็ป (Backward โฌ…๏ธ)            โ”‚    โ”‚
โ”‚  โ”‚  โ€ข fetch_article_details  ๅ–ๅพ—ๆ–‡็ซ ๅฎŒๆ•ด่ณ‡่จŠ                            โ”‚    โ”‚
โ”‚  โ”‚  โ€ข get_citation_metrics   ๅ–ๅพ—ๅผ•็”จๆŒ‡ๆจ™ (iCite RCR/Percentile)        โ”‚    โ”‚
โ”‚  โ”‚  โ€ข build_citation_tree    ๅปบๆง‹ๅผ•็”จ็ถฒ็ตกๆจน (6 ็จฎๆ ผๅผ)                   โ”‚    โ”‚
โ”‚  โ”‚  โ€ข suggest_citation_tree  ่ฉ•ไผฐๆ˜ฏๅฆๅ€ผๅพ—ๅปบๆง‹ๅผ•็”จๆจน                       โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                      Strategy Tools (4)                              โ”‚    โ”‚
โ”‚  โ”‚  ็ญ–็•ฅๅž‹ๅทฅๅ…ท - ๆœๅฐ‹็ญ–็•ฅ็”Ÿๆˆใ€ๆ“ดๅฑ•ใ€ๅˆไฝต                                   โ”‚    โ”‚
โ”‚  โ”‚                                                                      โ”‚    โ”‚
โ”‚  โ”‚  โ€ข parse_pico               ่งฃๆž PICO ่‡จๅบŠๅ•้กŒ (ๆœๅฐ‹ๅ…ฅๅฃ)             โ”‚    โ”‚
โ”‚  โ”‚  โ€ข generate_search_queries  ็”ข็”Ÿๅคšๅ€‹ๆœๅฐ‹็ญ–็•ฅ (ESpell + MeSH)          โ”‚    โ”‚
โ”‚  โ”‚  โ€ข merge_search_results     ๅˆไฝตๅŽป้‡ๆœๅฐ‹็ตๆžœ                          โ”‚    โ”‚
โ”‚  โ”‚  โ€ข expand_search_queries    ๆ“ดๅฑ•ๆœๅฐ‹็ญ–็•ฅ                              โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                       Export Tools (3)                               โ”‚    โ”‚
โ”‚  โ”‚  ๅŒฏๅ‡บๅž‹ๅทฅๅ…ท - ๅŒฏๅ‡บๅผ•็”จใ€ๅ–ๅพ—ๅ…จๆ–‡้€ฃ็ต                                     โ”‚    โ”‚
โ”‚  โ”‚                                                                      โ”‚    โ”‚
โ”‚  โ”‚  โ€ข prepare_export           ๅŒฏๅ‡บๅผ•็”จๆ ผๅผ (RIS/BibTeX/CSV/MEDLINE)    โ”‚    โ”‚
โ”‚  โ”‚  โ€ข get_article_fulltext_links  ๅ–ๅพ—ๅ…จๆ–‡้€ฃ็ต (PMC/DOI)                โ”‚    โ”‚
โ”‚  โ”‚  โ€ข analyze_fulltext_access  ๅˆ†ๆž้–‹ๆ”พๅ–็”จๅฏ็”จๆ€ง                        โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Citation Discovery ๅทฅๅ…ท้—œไฟ‚

                            ๆ‰พๅˆฐ้‡่ฆ่ซ–ๆ–‡ (PMID)
                                    โ”‚
            โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
            โ”‚                       โ”‚                       โ”‚
            โ–ผ                       โ–ผ                       โ–ผ
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚find_related_  โ”‚      โ”‚find_citing_   โ”‚      โ”‚get_article_   โ”‚
    โ”‚articles       โ”‚      โ”‚articles       โ”‚      โ”‚references     โ”‚
    โ”‚               โ”‚      โ”‚               โ”‚      โ”‚               โ”‚
    โ”‚ ็›ธไผผๆ€งๆœๅฐ‹    โ”‚      โ”‚ Forward โžก๏ธ    โ”‚      โ”‚ Backward โฌ…๏ธ   โ”‚
    โ”‚ PubMed ๆผ”็ฎ—ๆณ• โ”‚      โ”‚ ่ขซๅผ•็”จๆ–‡็ซ     โ”‚      โ”‚ ๅƒ่€ƒๆ–‡็ป      โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
            โ”‚                       โ”‚                       โ”‚
            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                    โ”‚
                                    โ–ผ
                          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                          โ”‚build_citation_  โ”‚
                          โ”‚tree             โ”‚
                          โ”‚                 โ”‚
                          โ”‚ BFS ้ๆญท็ถฒ็ตก    โ”‚
                          โ”‚ 6 ็จฎ่ผธๅ‡บๆ ผๅผ    โ”‚
                          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Pipeline ๆŒไน…ๅŒ–่ˆ‡ๆŽ’็จ‹

Status: ่จญ่จˆๅฎŒๆˆ๏ผŒๅฐšๆœชๅฏฆไฝœ ่ฉณ็ดฐ่จญ่จˆๆ–‡ไปถ: docs/PIPELINE_PERSISTENCE_DESIGN.md

่จญ่จˆ่ƒŒๆ™ฏ

Pipeline ็ณป็ตฑ๏ผˆv0.4.0๏ผ‰ๆไพ› DAG ๅŸท่กŒๅผ•ๆ“Žๅ’Œ 4 ๅ€‹ๆจกๆฟ๏ผˆpico, comprehensive, exploration, gene_drug๏ผ‰๏ผŒ ไฝ†็›ฎๅ‰ๆ˜ฏๅฎŒๅ…จ็„ก็‹€ๆ…‹็š„ โ€” ๆฏๆฌก้œ€่ฆ inline ๅ‚ณๅ…ฅ้…็ฝฎ๏ผŒ็„กๆณ•ไฟๅญ˜ใ€้‡่ค‡ไฝฟ็”จใ€ๆˆ–ๅฎšๆœŸๅŸท่กŒใ€‚

Pipeline ๆŒไน…ๅŒ–ๆ“ดๅฑ•ๅˆ†็‚บ 4 ๅ€‹ Phase๏ผš

Phase ๅŠŸ่ƒฝ ็‹€ๆ…‹
1 Pipeline CRUD๏ผˆsave/list/load/delete๏ผ‰ ๐Ÿ”ฒ ่ฆๅŠƒไธญ
2 ๅค–้ƒจ่ผ‰ๅ…ฅ๏ผˆURL / ๆช”ๆกˆ่ทฏๅพ‘๏ผ‰ ๐Ÿ”ฒ ่ฆๅŠƒไธญ
3 ๅŸท่กŒๆญทๅฒ่ˆ‡ Diff ๐Ÿ”ฒ ่ฆๅŠƒไธญ
4 ๆŽ’็จ‹ๆœๅฐ‹๏ผˆasyncio tick loop๏ผ‰ ๐Ÿ”ฒ ่ฆๅŠƒไธญ

ๅ…ฉ่ทฏ็”ฑๆจกๅž‹

ไฝฟ็”จ่€…ๅ•้กŒ
    โ”‚
    โ”œโ”€โ”€ ็ฐกๅ–ฎๆŸฅ่ฉข โ”€โ”€โ”€โ”€โ”€โ”€โ†’ unified_search(query="...")
    โ”‚                      โ†’ ๅณๆ™‚ๅ›žๅ‚ณ็ตๆžœ
    โ”‚
    โ””โ”€โ”€ ่ค‡้›œ/้‡่ค‡้œ€ๆฑ‚ โ”€โ”€โ†’ save_pipeline(name, config)
                           โ†’ unified_search(pipeline="saved:name")
                           โ†’ schedule_pipeline(name, cron)
                           โ†’ load_pipeline / list_pipelines / delete_pipeline

้—œ้ตๅŽŸๅ‰‡๏ผšunified_search ๆ˜ฏๅ”ฏไธ€็š„ๆœๅฐ‹ๅŸท่กŒๅ…ฅๅฃใ€‚Pipeline ๅทฅๅ…ทๅชๅš CRUD + ๆŽ’็จ‹็ฎก็†๏ผŒไธ็›ดๆŽฅๅŸท่กŒๆœๅฐ‹ใ€‚

MCP ๅทฅๅ…ท๏ผˆ6 ๅ€‹็จ็ซ‹ๅทฅๅ…ท๏ผ‰

ๅทฅๅ…ท ็”จ้€” Phase
save_pipeline ไฟๅญ˜ pipeline ้…็ฝฎ๏ผˆupsert๏ผŒๆ”ฏๆด scope ้ธๆ“‡๏ผ‰ 1
list_pipelines ๅˆ—่ˆ‰ๅทฒๅญ˜ pipeline๏ผˆๅˆไฝต workspace + global๏ผ‰ 1
load_pipeline ่ผ‰ๅ…ฅ pipeline๏ผˆname / URL / path๏ผ‰ 1
delete_pipeline ๅˆช้™ค pipeline + ๆญทๅฒ + ๆŽ’็จ‹ 1
get_pipeline_history ๆŸฅ่ฉขๅŸท่กŒๆญทๅฒ่ˆ‡ diff 3
schedule_pipeline ๆŽ’็จ‹/่งฃ้™คๆŽ’็จ‹/ๆŸฅ็œ‹ๆŽ’็จ‹ 4

DDD ๅˆ†ๅฑค

Presentation โ”€โ”€โ”€ tools/pipeline_tools.py (6 MCP tools)
                 resources.py (pipeline://saved/{name}, pipeline://templates/{name})
       โ”‚
Application โ”€โ”€โ”€โ”€ pipeline/store.py     (PipelineStore: CRUD + ้›™ๅฑค scope)
                 pipeline/scheduler.py  (PipelineScheduler: tick loop)
                 pipeline/executor.py   (ๅทฒๆœ‰, ๆ–ฐๅขž run_and_store)
       โ”‚
Domain โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  entities/pipeline.py  (ๆ–ฐๅขž PipelineMeta, PipelineRun, ScheduleEntry)
       โ”‚
Infrastructure
       โ”‚
       โ”œโ”€ Workspace scope (ๅ„ชๅ…ˆ๏ผŒๅฏ git ่ฟฝ่นค)๏ผš
       โ”‚    {workspace}/.pubmed-search/pipelines/{name}.yaml
       โ”‚    {workspace}/.pubmed-search/pipeline_runs/{name}/*.json
       โ”‚
       โ””โ”€ Global scope (fallback๏ผŒ่ทจๅฐˆๆกˆ)๏ผš
            ~/.pubmed-search-mcp/pipelines/{name}.yaml
            ~/.pubmed-search-mcp/pipeline_runs/{name}/*.json
            ~/.pubmed-search-mcp/schedules.json

้›™ๅฑคๅ„ฒๅญ˜ๆจกๅž‹

ๆฑบ็ญ– D7๏ผšๆŽก็”จ workspace + global ้›™ๅฑคๅ„ฒๅญ˜ใ€‚

Scope ่ทฏๅพ‘ ็”จ้€” ๅฏ git ่ฟฝ่นค
workspace {workspace}/.pubmed-search/ ๅฐˆๆกˆ็ดšๆœๅฐ‹็ญ–็•ฅ๏ผŒๅฏๅˆ†ไบซ็ตฆๅ”ไฝœ่€… โœ…
global ~/.pubmed-search-mcp/ ๅ€‹ไบบ้€š็”จ็ญ–็•ฅ๏ผŒ่ทจๅฐˆๆกˆๅฏ็”จ โŒ

่งฃๆž้ †ๅบ๏ผšload(name) โ†’ workspace ๅ„ชๅ…ˆ๏ผŒๆ‰พไธๅˆฐๅ‰‡ global fallbackใ€‚ save_pipeline(scope="auto") ้ ่จญๅญ˜ workspace๏ผˆ่‹ฅๆœ‰๏ผ‰๏ผŒๅฆๅ‰‡ globalใ€‚ ๆŽ’็จ‹ๅƒ…ๅœจ global scope๏ผˆ้œ€่ทจ workspace ้‹ไฝœ๏ผ‰ใ€‚

ๆŽ’็จ‹ๆฉŸๅˆถ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  MCP Server Lifespan             โ”‚
โ”‚                                  โ”‚
โ”‚  startup:                        โ”‚
โ”‚    load schedules.json           โ”‚
โ”‚    start _tick_loop()            โ”‚
โ”‚                                  โ”‚
โ”‚  _tick_loop (ๆฏ60็ง’):            โ”‚
โ”‚    for schedule in schedules:    โ”‚
โ”‚      if should_run(now):         โ”‚
โ”‚        asyncio.create_task(      โ”‚
โ”‚          execute_and_store())    โ”‚
โ”‚        update next_run           โ”‚
โ”‚                                  โ”‚
โ”‚  shutdown:                       โ”‚
โ”‚    save schedules.json           โ”‚
โ”‚    cancel background tasks       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ๅฎ‰ๅ…จ็ด„ๆŸ๏ผšๆœ€ๅฐ้–“้š” 1 ๅฐๆ™‚ใ€ๅŒๆ™‚ๆœ€ๅคš 5 ๆŽ’็จ‹ใ€ๅŸท่กŒ่ถ…ๆ™‚ 5 ๅˆ†้˜ใ€URL ็™ฝๅๅ–ฎใ€‚


HTTPS ้ƒจ็ฝฒๆžถๆง‹

ๆ•ด้ซ”ๆžถๆง‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                           HTTPS Deployment                                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                                     โ”‚
โ”‚   โ”‚      Client       โ”‚                                                     โ”‚
โ”‚   โ”‚    (AI Agent)     โ”‚                                                     โ”‚
โ”‚   โ”‚                   โ”‚                                                     โ”‚
โ”‚   โ”‚ โ€ข Claude Desktop  โ”‚                                                     โ”‚
โ”‚   โ”‚ โ€ข VS Code Copilot โ”‚                                                     โ”‚
โ”‚   โ”‚ โ€ข Custom Client   โ”‚                                                     โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                                     โ”‚
โ”‚             โ”‚                                                                โ”‚
โ”‚             โ”‚ HTTPS (TLS 1.2/1.3)                                           โ”‚
โ”‚             โ”‚ Port 443                                                       โ”‚
โ”‚             โ–ผ                                                                โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”‚
โ”‚   โ”‚                     Nginx Reverse Proxy                          โ”‚       โ”‚
โ”‚   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚       โ”‚
โ”‚   โ”‚  โ”‚                    Security Features                        โ”‚ โ”‚       โ”‚
โ”‚   โ”‚  โ”‚                                                             โ”‚ โ”‚       โ”‚
โ”‚   โ”‚  โ”‚  โœ… TLS Termination (SSL Certificates)                      โ”‚ โ”‚       โ”‚
โ”‚   โ”‚  โ”‚  โœ… Rate Limiting (30 req/s per IP)                         โ”‚ โ”‚       โ”‚
โ”‚   โ”‚  โ”‚  โœ… Security Headers                                        โ”‚ โ”‚       โ”‚
โ”‚   โ”‚  โ”‚     โ€ข X-Frame-Options: SAMEORIGIN                           โ”‚ โ”‚       โ”‚
โ”‚   โ”‚  โ”‚     โ€ข X-Content-Type-Options: nosniff                       โ”‚ โ”‚       โ”‚
โ”‚   โ”‚  โ”‚     โ€ข X-XSS-Protection: 1; mode=block                       โ”‚ โ”‚       โ”‚
โ”‚   โ”‚  โ”‚  โœ… SSE Optimization                                        โ”‚ โ”‚       โ”‚
โ”‚   โ”‚  โ”‚     โ€ข 24h timeout for long-lived connections                โ”‚ โ”‚       โ”‚
โ”‚   โ”‚  โ”‚     โ€ข Buffering disabled                                    โ”‚ โ”‚       โ”‚
โ”‚   โ”‚  โ”‚                                                             โ”‚ โ”‚       โ”‚
โ”‚   โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚       โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ”‚
โ”‚                                   โ”‚                                          โ”‚
โ”‚                                   โ”‚ HTTP (internal only)                     โ”‚
โ”‚                                   โ”‚ Port 8765                                โ”‚
โ”‚                                   โ–ผ                                          โ”‚
โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                  โ”‚
โ”‚              โ”‚           PubMed Search MCP Server          โ”‚                  โ”‚
โ”‚              โ”‚                                             โ”‚                  โ”‚
โ”‚              โ”‚  Endpoints:                                 โ”‚                  โ”‚
โ”‚              โ”‚  โ€ข /          Root                          โ”‚                  โ”‚
โ”‚              โ”‚  โ€ข /sse       SSE Connection (MCP)          โ”‚                  โ”‚
โ”‚              โ”‚  โ€ข /messages  POST messages (MCP)           โ”‚                  โ”‚
โ”‚              โ”‚  โ€ข /exports   Export files list             โ”‚                  โ”‚
โ”‚              โ”‚  โ€ข /download  Download export file          โ”‚                  โ”‚
โ”‚              โ”‚                                             โ”‚                  โ”‚
โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                  โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Docker Compose ๆžถๆง‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        docker-compose.https.yml                              โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚   Network: pubmed-mcp-network                                               โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚                                                                      โ”‚   โ”‚
โ”‚   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚     nginx           โ”‚      โ”‚     pubmed-mcp      โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚  (nginx:alpine)     โ”‚      โ”‚  (custom build)     โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚                     โ”‚      โ”‚                     โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚  Ports:             โ”‚      โ”‚  Expose:            โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚  โ€ข 443:443 (HTTPS)  โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”‚  โ€ข 8765 (internal)  โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚  โ€ข 80:80 (redirect) โ”‚      โ”‚                     โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚                     โ”‚      โ”‚  Environment:       โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚  Volumes:           โ”‚      โ”‚  โ€ข NCBI_EMAIL       โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚  โ€ข nginx.conf       โ”‚      โ”‚  โ€ข NCBI_API_KEY     โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚  โ€ข ssl/             โ”‚      โ”‚                     โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚                     โ”‚      โ”‚  Healthcheck:       โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚  Depends on:        โ”‚      โ”‚  โ€ข curl localhost   โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ”‚  โ€ข pubmed-mcp       โ”‚      โ”‚                     โ”‚               โ”‚   โ”‚
โ”‚   โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ”‚   โ”‚
โ”‚   โ”‚                                                                      โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

SSL ๆ†‘่ญ‰็ตๆง‹

nginx/
โ””โ”€โ”€ ssl/
    โ”œโ”€โ”€ ca.crt          # CA ๆ†‘่ญ‰ (้œ€ๅŠ ๅ…ฅ็ณป็ตฑไฟกไปป)
    โ”œโ”€โ”€ ca.key          # CA ็ง้‘ฐ (ๅ‹ฟๅค–ๆดฉ)
    โ”œโ”€โ”€ server.crt      # ไผบๆœๅ™จๆ†‘่ญ‰
    โ””โ”€โ”€ server.key      # ไผบๆœๅ™จ็ง้‘ฐ (ๅ‹ฟๅค–ๆดฉ)

Endpoints ๅฐ็…ง่กจ

External (HTTPS) Internal (HTTP) Description
https://localhost/ http://pubmed-mcp:8765/ MCP Server root
https://localhost/sse http://pubmed-mcp:8765/sse SSE connection
https://localhost/messages http://pubmed-mcp:8765/messages MCP POST
https://localhost/health http://pubmed-mcp:8765/ Health check
https://localhost/exports http://pubmed-mcp:8765/exports Export list

่ณ‡ๆ–™ๆต็จ‹

ๆœๅฐ‹ๆต็จ‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                           Search Data Flow                                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚   AI Agent                                                                  โ”‚
โ”‚      โ”‚                                                                       โ”‚
โ”‚      โ”‚ search_literature(query="remimazolam sedation")                      โ”‚
โ”‚      โ–ผ                                                                       โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                                   โ”‚
โ”‚   โ”‚    MCP Server       โ”‚                                                   โ”‚
โ”‚   โ”‚   (discovery.py)    โ”‚                                                   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                                   โ”‚
โ”‚              โ”‚                                                               โ”‚
โ”‚              โ”‚ 1. Check cache                                               โ”‚
โ”‚              โ–ผ                                                               โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     Cache Hit?                                    โ”‚
โ”‚   โ”‚    Session Cache    โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                  โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                โ”‚                  โ”‚
โ”‚              โ”‚ No                                        โ”‚                  โ”‚
โ”‚              โ–ผ                                           โ”‚                  โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                โ”‚                  โ”‚
โ”‚   โ”‚  LiteratureSearcher โ”‚                                โ”‚                  โ”‚
โ”‚   โ”‚     (entrez/)       โ”‚                                โ”‚                  โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                โ”‚                  โ”‚
โ”‚              โ”‚                                           โ”‚                  โ”‚
โ”‚              โ”‚ 2. Entrez.esearch()                       โ”‚                  โ”‚
โ”‚              โ”‚ 3. Entrez.efetch()                        โ”‚                  โ”‚
โ”‚              โ–ผ                                           โ”‚                  โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                โ”‚                  โ”‚
โ”‚   โ”‚     NCBI Entrez     โ”‚                                โ”‚                  โ”‚
โ”‚   โ”‚        API          โ”‚                                โ”‚                  โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                โ”‚                  โ”‚
โ”‚              โ”‚                                           โ”‚                  โ”‚
โ”‚              โ”‚ XML Response                              โ”‚                  โ”‚
โ”‚              โ–ผ                                           โ”‚                  โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                โ”‚                  โ”‚
โ”‚   โ”‚   Parse & Format    โ”‚                                โ”‚                  โ”‚
โ”‚   โ”‚   SearchResult[]    โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                  โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                                   โ”‚
โ”‚              โ”‚                                                               โ”‚
โ”‚              โ”‚ 4. Cache results                                             โ”‚
โ”‚              โ”‚ 5. Format output                                             โ”‚
โ”‚              โ–ผ                                                               โ”‚
โ”‚   AI Agent receives formatted results                                       โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Citation Tree ๅปบๆง‹ๆต็จ‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                       Citation Tree Data Flow                                โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚   build_citation_tree(pmid="12345678", depth=2, direction="both")           โ”‚
โ”‚      โ”‚                                                                       โ”‚
โ”‚      โ–ผ                                                                       โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”‚
โ”‚   โ”‚                     BFS Traversal                              โ”‚         โ”‚
โ”‚   โ”‚                                                                โ”‚         โ”‚
โ”‚   โ”‚   Level 0: [12345678]  (seed article)                         โ”‚         โ”‚
โ”‚   โ”‚      โ”‚                                                         โ”‚         โ”‚
โ”‚   โ”‚      โ”œโ”€โ”€ get_citing_articles()  โ”€โ”€โ–บ [A, B, C]                 โ”‚         โ”‚
โ”‚   โ”‚      โ””โ”€โ”€ get_article_references() โ”€โ”€โ–บ [X, Y, Z]               โ”‚         โ”‚
โ”‚   โ”‚      โ”‚                                                         โ”‚         โ”‚
โ”‚   โ”‚   Level 1: [A, B, C, X, Y, Z]                                 โ”‚         โ”‚
โ”‚   โ”‚      โ”‚                                                         โ”‚         โ”‚
โ”‚   โ”‚      โ”œโ”€โ”€ get_citing_articles() for each  โ”€โ”€โ–บ [...]            โ”‚         โ”‚
โ”‚   โ”‚      โ””โ”€โ”€ get_article_references() for each โ”€โ”€โ–บ [...]          โ”‚         โ”‚
โ”‚   โ”‚      โ”‚                                                         โ”‚         โ”‚
โ”‚   โ”‚   Level 2: [...]  (depth reached, stop)                       โ”‚         โ”‚
โ”‚   โ”‚                                                                โ”‚         โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ”‚
โ”‚      โ”‚                                                                       โ”‚
โ”‚      โ”‚ Nodes: [{pmid, title, year, ...}, ...]                               โ”‚
โ”‚      โ”‚ Edges: [{source, target, type}, ...]                                 โ”‚
โ”‚      โ–ผ                                                                       โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”‚
โ”‚   โ”‚                   Format Converter                             โ”‚         โ”‚
โ”‚   โ”‚                                                                โ”‚         โ”‚
โ”‚   โ”‚   output_format="mermaid"  โ”€โ”€โ–บ _to_mermaid()                  โ”‚         โ”‚
โ”‚   โ”‚   output_format="cytoscape" โ”€โ”€โ–บ _to_cytoscape()               โ”‚         โ”‚
โ”‚   โ”‚   output_format="graphml"  โ”€โ”€โ–บ _to_graphml()                  โ”‚         โ”‚
โ”‚   โ”‚   ...                                                          โ”‚         โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         โ”‚
โ”‚      โ”‚                                                                       โ”‚
โ”‚      โ–ผ                                                                       โ”‚
โ”‚   Formatted graph data (JSON/XML/Mermaid)                                   โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ๅ…ง้ƒจๆฉŸๅˆถ

ๅฐ Agent ้€ๆ˜Ž็š„ๆฉŸๅˆถ

้€™ไบ›ๆฉŸๅˆถ่‡ชๅ‹•้‹ไฝœ๏ผŒAgent ็„ก้œ€็ฎก็†๏ผš

ๆฉŸๅˆถ ่ชชๆ˜Ž ๅฏฆไฝœไฝ็ฝฎ
Session ่‡ชๅ‹•ๅปบ็ซ‹ใ€่‡ชๅ‹•ๅˆ‡ๆ›๏ผŒ็ถญๆŒๆœๅฐ‹ไธŠไธ‹ๆ–‡ session.py
Cache ๆœๅฐ‹็ตๆžœ่‡ชๅ‹•ๅฟซๅ–๏ผŒ้ฟๅ…้‡่ค‡ API ๅ‘ผๅซ _common.py
Rate Limit ่‡ชๅ‹•้ตๅฎˆ NCBI API ้™ๅˆถ (0.34s/0.1s with key) entrez/
MeSH Lookup generate_search_queries() ่‡ชๅ‹•ๆŸฅ่ฉข MeSH strategy.py
ESpell ่‡ชๅ‹•ๆ‹ผๅญ—ๆ กๆญฃ (remifentanyl โ†’ remifentanil) strategy.py
Query Analysis ๅˆ†ๆž PubMed ๅฏฆ้š›่งฃ่ฎ€ๆ–นๅผ strategy.py

Rate Limiting

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                           NCBI Rate Limits                                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚   Without API Key:                                                          โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”‚
โ”‚   โ”‚  โ€ข 3 requests per second                                         โ”‚       โ”‚
โ”‚   โ”‚  โ€ข 0.34 second delay between requests                            โ”‚       โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ”‚
โ”‚                                                                              โ”‚
โ”‚   With API Key (NCBI_API_KEY):                                              โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”‚
โ”‚   โ”‚  โ€ข 10 requests per second                                        โ”‚       โ”‚
โ”‚   โ”‚  โ€ข 0.1 second delay between requests                             โ”‚       โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ”‚
โ”‚                                                                              โ”‚
โ”‚   Implementation:                                                            โ”‚
โ”‚   โ€ข time.sleep() between API calls                                          โ”‚
โ”‚   โ€ข Automatic retry on rate limit errors                                    โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

็›ธ้—œๆ–‡ไปถ

ๆ–‡ไปถ ่ชชๆ˜Ž
README.md ๅฟซ้€Ÿ้–‹ๅง‹ใ€ๅŠŸ่ƒฝ็ธฝ่ฆฝ
DEPLOYMENT.md ้ƒจ็ฝฒๆŒ‡ๅ—ใ€ๅฎขๆˆถ็ซฏ้…็ฝฎ
CHANGELOG.md ็‰ˆๆœฌๆ›ดๆ–ฐ่จ˜้Œ„
ROADMAP.md ้–‹็™ผ่ทฏ็ทšๅœ–
docs/PIPELINE_PERSISTENCE_DESIGN.md Pipeline ๆŒไน…ๅŒ–่ˆ‡ๆŽ’็จ‹่ฉณ็ดฐ่จญ่จˆ

ๆŠ€่ก“ๆฑบ็ญ–่จ˜้Œ„ (ADR)

ADR-001: ้ธๆ“‡ DDD ๆžถๆง‹

Context: ้œ€่ฆไธ€ๅ€‹ๅฏ็ถญ่ญทใ€ๅฏๆ“ดๅฑ•็š„ๆžถๆง‹ไพ†่™•็†ๆ–‡็ป็ ”็ฉถ้ ˜ๅŸŸ้‚่ผฏใ€‚

Decision: ๆŽก็”จ Domain-Driven Design (DDD) + Onion Architectureใ€‚

Rationale:

  • ้ ˜ๅŸŸ้‚่ผฏ๏ผˆๆ–‡็ปๆœๅฐ‹ใ€ๅผ•็”จๅˆ†ๆž๏ผ‰่ˆ‡ๅŸบ็คŽ่จญๆ–ฝ๏ผˆNCBI APIใ€ๅฟซๅ–๏ผ‰ๅˆ†้›ข
  • ๆ˜“ๆ–ผๆธฌ่ฉฆ๏ผšDomain Layer ไธไพ่ณดๅค–้ƒจๆœๅ‹™
  • ๆ˜“ๆ–ผๆ“ดๅฑ•๏ผšๆ–ฐๅขžๅทฅๅ…ทๅช้œ€ๅœจ Application Layer ๆทปๅŠ 

ADR-002: ้ธๆ“‡ Nginx ไฝœ็‚บ HTTPS ๅๅ‘ไปฃ็†

Context: ้œ€่ฆ็‚บ็”Ÿ็”ข็’ฐๅขƒๆไพ› TLS ๅŠ ๅฏ†ๅ’Œๅฎ‰ๅ…จ้˜ฒ่ญทใ€‚

Decision: ไฝฟ็”จ Nginx ไฝœ็‚บๅๅ‘ไปฃ็†๏ผŒ่€Œ้žๅœจ Python ๆ‡‰็”จไธญ็›ดๆŽฅ่™•็† HTTPSใ€‚

Rationale:

  • Nginx ๅฐ TLS ็ต‚ๆญขๆœ‰ๆ›ดๅฅฝ็š„ๆ€ง่ƒฝ
  • SSE ้•ท้€ฃๆŽฅ้œ€่ฆ็‰นๆฎŠ้…็ฝฎ๏ผˆ24h timeout, buffering off๏ผ‰
  • Rate limiting ๅœจ Nginx ๅฑค้ขๆ›ด้ซ˜ๆ•ˆ
  • ๅฎ‰ๅ…จๆจ™้ ญ็ตฑไธ€็ฎก็†

ADR-003: Citation Tree ๆ”ฏๆดๅคš่ผธๅ‡บๆ ผๅผ

Context: ไธๅŒ็”จๆˆถๆœ‰ไธๅŒ็š„่ฆ–่ฆบๅŒ–ๅทฅๅ…ทๅๅฅฝใ€‚

Decision: ๆ”ฏๆด 6 ็จฎ่ผธๅ‡บๆ ผๅผ๏ผšmermaid, cytoscape, g6, d3, vis, graphmlใ€‚

Rationale:

  • Mermaid: VS Code ๅ…งๅปบ้ ่ฆฝ๏ผŒ้›ถ้…็ฝฎ
  • Cytoscape: ๅญธ่ก“็•Œๆจ™ๆบ–๏ผŒ็”Ÿ็‰ฉ่ณ‡่จŠๅธธ็”จ
  • GraphML: ๆกŒ้ข่ปŸ้ซ”๏ผˆGephi, VOSviewer๏ผ‰็›ธๅฎน
  • ไฟๆŒๆ ผๅผ่ฝ‰ๆ›้‚่ผฏ็จ็ซ‹๏ผŒไพฟๆ–ผๆ–ฐๅขžๆ ผๅผ

ADR-004: Smart Citation Search ่จญ่จˆ (่ฆๅŠƒไธญ)

Context: Agent ๅˆคๆ–ทๆ–‡็ซ ็›ธ้—œๆ€งๆถˆ่€—ๅคง้‡ token๏ผŒ้œ€่ฆ่ฎ“ MCP ้ ๅ…ˆๆŽ’ๅบใ€‚

Decision: ๆ•ดๅˆ้ ่จˆ็ฎ— API๏ผˆCitation Intentใ€Conceptsใ€Similarity๏ผ‰ๅฏฆ็พ smart_citation_searchใ€‚

Rationale:

  • Agent ๆ˜ฏ็“ถ้ ธ: MCP ๆ‡‰ๅšใ€Œๆ•ธๆ“šๅฏ†้›†ใ€ๅทฅไฝœ๏ผŒAgent ๅšใ€Œๅˆคๆ–ทๅฏ†้›†ใ€ๆฑบ็ญ–
  • Token ็ฏ€็œ: 100 ็ฏ‡ ร— 400 tokens โ†’ 10 ็ฏ‡ ร— 200 tokens = 95% ็ฏ€็œ
  • ้ ่จˆ็ฎ—ๅ„ชๅ…ˆ: ไฝฟ็”จ Semantic Scholar Citation Intentใ€OpenAlex Concepts ็ญ‰้ ่จˆ็ฎ—ๆŒ‡ๆจ™

่จญ่จˆๅŽŸๅ‰‡:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Smart Citation Search ่ท่ฒฌๅˆ†้›ข                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                 โ”‚
โ”‚  โ”‚           MCP ่ท่ฒฌ (ๆ•ธๆ“šๅฏ†้›†)          โ”‚                                 โ”‚
โ”‚  โ”‚  โ€ข ๅคšๆบๆœๅฐ‹ (PubMed, S2, OpenAlex)     โ”‚                                 โ”‚
โ”‚  โ”‚  โ€ข ๅ‘ผๅซ้ ่จˆ็ฎ— API                      โ”‚                                 โ”‚
โ”‚  โ”‚  โ€ข ไพๆŒ‡ๆจ™ๆŽ’ๅบ                          โ”‚                                 โ”‚
โ”‚  โ”‚  โ€ข ่ผธๅ‡บ compact ๆ ผๅผ                   โ”‚                                 โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                 โ”‚
โ”‚                          โ†“                                                   โ”‚
โ”‚                    Top K ็ตๆžœ + ๆŽ’ๅบ็†็”ฑ                                     โ”‚
โ”‚                          โ†“                                                   โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                                 โ”‚
โ”‚  โ”‚          Agent ่ท่ฒฌ (ๅˆคๆ–ทๅฏ†้›†)         โ”‚                                 โ”‚
โ”‚  โ”‚  โ€ข ้–ฑ่ฎ€็ฒพ้ธ็ตๆžœ                        โ”‚                                 โ”‚
โ”‚  โ”‚  โ€ข ๆฑบๅฎšๆ˜ฏๅฆ้œ€่ฆๆ›ดๅคš                    โ”‚                                 โ”‚
โ”‚  โ”‚  โ€ข ็ถœๅˆๅˆ†ๆž่ˆ‡ๅ›ž็ญ”                      โ”‚                                 โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                 โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ADR-005: ็›ธไผผๅบฆๅˆ†ๆ•ธไพ†ๆบ็ญ–็•ฅ (่ฆๅŠƒไธญ)

Context: unified_search ้œ€่ฆ่ฟ”ๅ›ž็›ธไผผๅบฆๅˆ†ๆ•ธ๏ผŒไฝ†ไธๅŒไพ†ๆบๆไพ›ไธๅŒ็š„็›ธไผผๅบฆ่จˆ็ฎ—ใ€‚

Decision: ๆŽก็”จๅคšไพ†ๆบ็›ธไผผๅบฆ่žๅˆ็ญ–็•ฅใ€‚

ไพ†ๆบๅ„ชๅ…ˆ้ †ๅบ:

  1. Semantic Scholar (ๆœ‰ S2 ID) - ๅŸบๆ–ผ citation graph ็š„็›ธไผผๅบฆ
  2. Europe PMC (ๆœ‰ PMID) - ๅŸบๆ–ผ PubMed ็š„ Related Articles ๆผ”็ฎ—ๆณ•
  3. OpenAlex (ๆœ‰ Works ID) - ๅŸบๆ–ผ Concepts ้‡็–Šๅบฆ
  4. TF-IDF (ๅ‚™็”จ) - ๅŸบๆ–ผ title + abstract ็š„ๆ–‡ๆœฌ็›ธไผผๅบฆ

Rationale:

  • API ๆไพ›็š„็›ธไผผๅบฆๆฏ”ๆœฌๅœฐ่จˆ็ฎ—ๆ›ดๆบ–็ขบ๏ผˆ่€ƒๆ…ฎไบ† citation graph ๅ’Œ่ชž็พฉ๏ผ‰
  • ๅคšไพ†ๆบ่žๅˆๆ้ซ˜ coverage
  • TF-IDF ไฝœ็‚บ fallback ็ขบไฟ็ธฝๆ˜ฏๆœ‰็›ธไผผๅบฆๅˆ†ๆ•ธ

่ผธๅ‡บๆ ผๅผ:

{
  "pmid": "12345678",
  "similarity_score": 0.87,
  "similarity_source": "semantic_scholar",
  "similarity_methods": {
    "semantic_scholar": 0.87,
    "europe_pmc": 0.82,
    "concept_overlap": 0.75
  }
}

ๆ™บ่ƒฝๅผ•็”จ็ณป็ตฑๆžถๆง‹ (่ฆๅŠƒไธญ)

5 ๅ€‹้ ่จˆ็ฎ— API ๆ•ดๅˆ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    Pre-computed Intelligence APIs                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ Semantic Scholar    โ”‚    โ”‚ OpenAlex            โ”‚    โ”‚ PubTator        โ”‚  โ”‚
โ”‚  โ”‚ Citation Intent     โ”‚    โ”‚ Concepts            โ”‚    โ”‚ Central         โ”‚  โ”‚
โ”‚  โ”‚                     โ”‚    โ”‚                     โ”‚    โ”‚                 โ”‚  โ”‚
โ”‚  โ”‚ โ€ข background        โ”‚    โ”‚ โ€ข Topic tags        โ”‚    โ”‚ โ€ข Gene          โ”‚  โ”‚
โ”‚  โ”‚ โ€ข methodology       โ”‚    โ”‚ โ€ข Level 0-3         โ”‚    โ”‚ โ€ข Disease       โ”‚  โ”‚
โ”‚  โ”‚ โ€ข result            โ”‚    โ”‚ โ€ข Score 0-1         โ”‚    โ”‚ โ€ข Chemical      โ”‚  โ”‚
โ”‚  โ”‚ โ€ข comparison        โ”‚    โ”‚                     โ”‚    โ”‚ โ€ข Mutation      โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚             โ”‚                          โ”‚                        โ”‚            โ”‚
โ”‚             โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜            โ”‚
โ”‚                                        โ–ผ                                     โ”‚
โ”‚             โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”            โ”‚
โ”‚             โ”‚              Smart Ranker                         โ”‚            โ”‚
โ”‚             โ”‚                                                   โ”‚            โ”‚
โ”‚             โ”‚  Weights (configurable by research_goal):         โ”‚            โ”‚
โ”‚             โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚            โ”‚
โ”‚             โ”‚  โ”‚ methodology goal:                         โ”‚   โ”‚            โ”‚
โ”‚             โ”‚  โ”‚   โ€ข Citation Intent (methodology): 40%    โ”‚   โ”‚            โ”‚
โ”‚             โ”‚  โ”‚   โ€ข RCR: 25%                              โ”‚   โ”‚            โ”‚
โ”‚             โ”‚  โ”‚   โ€ข Concept Overlap: 20%                  โ”‚   โ”‚            โ”‚
โ”‚             โ”‚  โ”‚   โ€ข Recency: 15%                          โ”‚   โ”‚            โ”‚
โ”‚             โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚            โ”‚
โ”‚             โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚            โ”‚
โ”‚             โ”‚  โ”‚ evidence goal:                            โ”‚   โ”‚            โ”‚
โ”‚             โ”‚  โ”‚   โ€ข Citation Intent (result): 35%         โ”‚   โ”‚            โ”‚
โ”‚             โ”‚  โ”‚   โ€ข Study Type (RCT > Cohort): 30%        โ”‚   โ”‚            โ”‚
โ”‚             โ”‚  โ”‚   โ€ข RCR: 20%                              โ”‚   โ”‚            โ”‚
โ”‚             โ”‚  โ”‚   โ€ข Recency: 15%                          โ”‚   โ”‚            โ”‚
โ”‚             โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚            โ”‚
โ”‚             โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜            โ”‚
โ”‚                                        โ”‚                                     โ”‚
โ”‚                                        โ–ผ                                     โ”‚
โ”‚                          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                        โ”‚
โ”‚                          โ”‚    Ranked Results        โ”‚                        โ”‚
โ”‚                          โ”‚    (compact format)      โ”‚                        โ”‚
โ”‚                          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                        โ”‚
โ”‚                                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ OpenCitations       โ”‚                           โ”‚ Europe PMC          โ”‚  โ”‚
โ”‚  โ”‚                     โ”‚                           โ”‚ Similar Articles    โ”‚  โ”‚
โ”‚  โ”‚ โ€ข DOI โ†’ citations   โ”‚                           โ”‚                     โ”‚  โ”‚
โ”‚  โ”‚ โ€ข Citation timeline โ”‚                           โ”‚ โ€ข Similarity score  โ”‚  โ”‚
โ”‚  โ”‚ โ€ข Reference graph   โ”‚                           โ”‚ โ€ข Related by contentโ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ๆช”ๆกˆ็ตๆง‹่ฆๅŠƒ

src/pubmed_search/
โ”œโ”€โ”€ infrastructure/
โ”‚   โ”œโ”€โ”€ ncbi/
โ”‚   โ”‚   โ”œโ”€โ”€ pubtator.py               # ๐Ÿ†• PubTator Central ๅฎขๆˆถ็ซฏ
โ”‚   โ”‚   โ””โ”€โ”€ ...
โ”‚   โ””โ”€โ”€ sources/
โ”‚       โ”œโ”€โ”€ opencitations.py          # ๐Ÿ†• OpenCitations ๅฎขๆˆถ็ซฏ
โ”‚       โ”œโ”€โ”€ semantic_scholar.py       # โœ๏ธ ๆ“ดๅฑ• Citation Intent
โ”‚       โ”œโ”€โ”€ openalex.py               # โœ๏ธ ๆ“ดๅฑ• Concepts API
โ”‚       โ””โ”€โ”€ europe_pmc.py             # โœ๏ธ ๆ“ดๅฑ• Similar Articles
โ”œโ”€โ”€ application/
โ”‚   โ””โ”€โ”€ search/
โ”‚       โ”œโ”€โ”€ smart_ranker.py           # ๐Ÿ†• ๆ™บ่ƒฝๆŽ’ๅบๅ™จ
โ”‚       โ””โ”€โ”€ result_aggregator.py      # โœ๏ธ ๆ“ดๅฑ•็›ธไผผๅบฆ่žๅˆ
โ””โ”€โ”€ presentation/
    โ””โ”€โ”€ mcp_server/
        โ””โ”€โ”€ tools/
            โ””โ”€โ”€ smart_citation.py     # ๐Ÿ†• smart_citation_search ๅทฅๅ…ท