📅
🕵️‍♂️ อ่าน ~3 นาที

คดีที่ 32: ผ่าพิมพ์เขียว open-science — ถอดรหัสสถาปัตยกรรม AI ยุคใหม่ (4.9k Stars)


🕵️‍♂️ ปมคดีและที่มา: ทำไมวงการถึงต้องจับตามอง?

ทำไมโปรเจกต์ aipoch/open-science ถึงได้รับความนิยมและมียอดกด Star ทะลุ 4.9k บน GitHub?

เบื้องหลังความสำเร็จนี้ไม่ใช่แค่การเป็นเครื่องมือสำเร็จรูป แต่คือการแก้ปัญหาทางวิศวกรรมที่เจ็บปวด: A: Check the API Key for missing characters or spaces, verify the Base URL and region, use the provider’s exact model ID, and confirm network access and account balance. For a Claude subscription, retry the shared browser login or refresh the isolated claude setup-token credential, depending on the selected mode.


📊 ตารางเปรียบเทียบเชิงลึก: วิธีดั้งเดิม vs สถาปัตยกรรมสมัยใหม่

มิติการเปรียบเทียบ สถาปัตยกรรมเดิม (Traditional Approaches) สถาปัตยกรรม {clean_name}
ความยืดหยุ่น ผูกติดกับ Cloud Provider รายใหญ่ Modular Engine รองรับทั้ง Local และ API มาตรฐาน
ประสิทธิภาพ Token บริโภค Context สูง ขาดการแคชที่ดี ออกแบบ Layer แยก Context และ Execution ออกจากกัน
ความง่ายในการ Integrate ต้องเขียน Custom Glue Code มหาศาล เชื่อมต่อผ่าน Standardized Protocols (MCP/REST)

🔍 แกะรอยสถาปัตยกรรมระบบ (Deep Architecture Breakdown)

พิมพ์เขียวสถาปัตยกรรมเบื้องหลังระบบนี้ ถูกออกแบบมาเพื่อแก้ปัญหาคอขวดด้านประสิทธิภาพและความปลอดภัย:

flowchart TD
    subgraph 👤 User & Agent Layer
        User["👨‍💻 Developer / AI Agent"] -->|"Task / Intent"| Router["⚡ Protocol Router (MCP / CLI)"]
    end

    subgraph 🧠 Core Intelligence Engine
        Router --> Engine["⚙️ open-science Engine"]
        Engine --> Decision["🎯 Intelligent Decision Core"]
        Engine --> Memory["💾 Persistent Session & Cache"]
    end

    subgraph 🛠️ Execution & Tooling
        Decision --> Tools["🔧 Specialized Execution Modules"]
        Tools --> Output["📊 Filtered & Optimized Results"]
    end

    Output -->|"Clean Context"| User

3 เสาหลักของการออกแบบระบบ (System Design Pillars):

  1. Decoupled Execution & Protocol-First: สื่อสารผ่านโปรโตคอลมาตรฐาน ทำให้ถอดเปลี่ยนสมองกล (LLM) ได้อิสระโดยไม่ต้องเขียน Logic การเชื่อมต่อ Tool ใหม่
  2. Context & Token Economy: ป้องกันไม่ให้ Output ดิบขนาดมหึมาทะลักเข้าสู่หน้าต่างบริบท ช่วยลดอาการ Hallucination และประหยัดค่าใช้จ่าย
  3. Resilience & State Continuity: มีกลไก Handle Exception และบันทึก State ความคืบหน้า เพื่อให้การทำงานแบบ Multi-step สามารถรันต่อได้จนจบภารกิจ

💻 ผ่ารหัสลับของจริง (Source Code Autopsy)

จากการผ่าโครงสร้าง Repo ของจริง เราพบชิ้นส่วนโค้ดสำคัญที่เป็นหัวใจของการขับเคลื่อนระบบ:

📄 ผ่าไฟล์จริง: package.json

{
  "name": "open-science",
  "productName": "Open-Science",
  "desktopName": "open-science.desktop",
  "version": "0.32.0",
  "description": "Open-Science \u2014 an open-source, model-agnostic AI workbench for scientific discovery.",
  "main": "./out/main/index.js",
  "author": "aipoch",
  "license": "Apache-2.0",
  "homepage": "https://www.aipoch.com/open-science",
  "bin": {
    "open-science": "cli/index.mjs"
  },
  "scripts": {
    "format": "prettier --write .",
    "lint": "eslint --cache .",
    "pretest": "node scripts/check-prisma-client.mjs",
    "test": "vitest run",
    "test:module": "node scripts/ci/module-test-impact.mjs module",
    "test:affected": "node scripts/ci/module-test-impact.mjs affected",
    "test:affected:explain": "node scripts/ci/module-test-impact.mjs affected --explain",
    "build:e2e": "node --max-old-space-size=4096 node_modules/electron-vite/bin/electron-vite.js build",
    "test:e2e": "playwright test",
    "test:e2e:journey": "playwright test e2e/brand-storage.spec.ts e2e/electron-foundation.spec.ts e2e/settings-persistence.spec.ts e2e/windows-window-system.spec.ts e2e/wsl-setup-conversation.spec.ts e2e/session-package.spec.ts e2e/session-package-drop.spec.ts e2e/session-fork.spec.ts e2e/session-diagnostics.spec.ts e2e/specialist-marketplace-redirect.spec.ts",
    "test:e2e:wsl-setup": "playwright test e2e/wsl-setup-conversation.spec.ts",
    "test:e2e:workspace": "playwright test e2e/launch-environment.spec.ts e2e/message-tool-layout-stability.spec.ts e2e/workspace-project-switcher.spec.ts e2e/workspace-conversation.spec.ts e2e/workspace-files.spec.ts",
    "test:e2e:regressions": "playwright test e2e/pdf-annotations.spec.ts e2e/pdf-notebook-capacity.spec.ts e2e/background-result-delivery.spec.ts e2e/renderer-startup-dependencies.spec.ts e2e/interaction-restart.spec.ts e2e/interrupted-turn-recovery.spec.ts e2e/provider-connection-validation.spec.ts e2e/global-search.spec.ts e2e/search-file-navigation.spec.ts e2e/transcript-capacity.spec.ts e2e/session-residency-capacity.spec.ts e2e/compute-execution-mode.spec.ts e2e/find-overlay.spec.ts e2e/literature-client-sync.spec.ts e2e/session-client-consistency.spec.ts e2e/runtime-writer-browser.spec.ts e2e/mermaid-block.spec.ts e2e/message-queue-presentation-gate.spec.ts e2e/mobile-message-handoff.spec.ts e2e/message-scroll-anchor.spec.ts e2e/message-scroll-reanchor.spec.ts e2e/message-scroll-release.spec.ts e2e/message-tool-order.spec.ts e2e/preview-context-menu.spec.ts e2e/reproducibility-preview.spec.ts e2e/skill-permission-card.spec.ts e2e/window-presentation.spec.ts e2e/ux-quality.spec.ts e2e/side-chat-admission.spec.ts e2e/artifact-task-lifecycle.spec.ts e2e/artifact-resume-finalization.spec.ts",
    "test:e2e:delegation": "playwright test e2e/subagent-model-release-gate.spec.ts e2e/subagent-release-gate.spec.ts",
    "test:e2e:accessibility": "playwright test e2e/accessibility.spec.ts",
    "test:e2e:accessibility:signal": "node scripts/ci/run-accessibility-e2e.mjs",
    "test:e2e:visual": "playwright test e2e/visual-regression.spec.ts",
    "perf:runtime": "node scripts/performance/run-runtime-profile.mjs",
    "test:e2e:p0": "playwright test e2e/certification",
    "test:cli": "vitest run packages/open-science",
    "test:npm-release": "vitest run scripts/validate-npm-release.test.ts",
    "test:session-isolation:live": "node scripts/test-session-isolation-live.mjs",
    "test:coverage": "vitest run --coverage",
    "eval:reviewer": "node scripts/reviewer-model-evaluation.mjs",
    "eval:reviewer:live": "electron scripts/reviewer-model-evaluation-live.mjs",
    "typecheck:node": "node --max-old-space-size=6144 node_modules/typescript/bin/tsc --noEmit -p tsconfig.node.json --composite false && npm run typecheck:sandbox",
    "typecheck:sandbox": "npm --prefix packages/notebook-network-sandbox run typecheck",
    "typecheck:web": "tsc --noEmit -p tsconfig.web.json --composite false",
    "typecheck": "npm run typecheck:node && npm run typecheck:web",
    "gen:web-api-map": "node scripts/generate-web-api-map.mjs",
    "check:web-api-map": "node scripts/generate-web-api-map.mjs --check",
    "db:schema:generate": "node scripts/generate-database-schema.mjs",
    "db:schema:check": "node scripts/generate-database-schema.mjs --check",
    "check:cli-package": "npm pack ./packages/open-science --dry-run --json --cache ./node_modules/.cache/npm-pack",
    "check:claude-acp-patch": "node scripts/check-claude-acp-patch.mjs",
    "build:web": "npm run gen:web-api-map && vite build --config vite.web.config.ts",
    "start": "electron-vite preview",
    "dev": "electron-vite dev",
    "dev:native-send-now": "node scripts/dev-native-send-now.cjs",
    "dev:web": "node scripts/dev-app-branding.cjs && node scripts/dev-web.cjs",
    "dev:headless": "node scripts/dev-app-branding.cjs && node scripts/dev-web.cjs --headless",
    "cli": "node cli/index.mjs",
    "build": "npm run typecheck && electron-vite build && npm run build:web",
    "postinstall": "node scripts/prepare-shadcn-patch.mjs && patch-package --error-on-fail && node scripts/check-claude-acp-patch.mjs && prisma generate && electron-builder install-app-deps && node scripts/fix-electron-path.cjs",
    "build:unpack": "npm run build && electron-builder --dir",
    "build:mac": "npm run build:web && electron-vite build && electron-builder --mac",
    "build:linux": "npm run build:web && electron-vite build && electron-builder --linux",
    "build:win": "npm run build:web && electron-vite build && electron-builder --win",
    "stage-default-envs": "node scripts/stage-default-envs.mjs",
    "predev": "node scripts/check-prisma-client.mjs && node scripts/dev-app-branding.cjs",
    "test:e2e:browser": "playwright test --config playwright.browser.config.ts"
  },
  "dependencies": {
    "@agentclientprotocol/claude-agent-acp": "^0.70.0",
    "@agentclientprotocol/sdk": "^1.2.1",
    "@aipoch/credential-identity-probe-native": "file:packages/credential-identity-probe-native",
    "@aipoch/notebook-network-sandbox": "file:packages/notebook-network-sandbox",
    "@aipoch/process-tree-native": "file:packages/process-tree-native",
    "@aipoch/safe-file-publisher-native": "file:packages/safe-file-publisher-native",
    "@anthropic-ai/tokenizer": "^0.0.4",
    "@bokuweb/zstd-wasm": "^0.0.27",
    "@electron-toolkit/utils": "^4.0.0",
    "@lobehub/icons": "^5.14.0",
    "@modelcontextprotocol/sdk": "^1.30.0",
    "@napi-rs/canvas": "0.1.100",
    "@peculiar/x509": "2.1.0",

การทำงานทางวิศวกรรม:

  • โค้ดส่วนนี้ทำหน้าที่เป็นแกนกลางในการควบคุม Flow ของข้อมูล
  • แยกหน้าที่การทำงานชัดเจน (Separation of Concerns) ทำให้สเกลเครื่องมือใหม่ๆ เข้าสู่ระบบได้ทันทีโดยไม่ต้องแก้ Core Engine

📄 ผ่าไฟล์จริง: AGENTS.md

# Open-Science — Agent Notes

## i18n — translating new user-visible strings

The renderer ships eight translated locales: **de** (German), **es** (Spanish), **fr** (French),
**zh-Hans** (Simplified Chinese), **zh-Hant** (Traditional Chinese), **ja** (Japanese), **ko**
(Korean), and **ru** (Russian). Every
user-visible string added to the renderer must have a corresponding entry in the `renderer`
namespace for all translated locales unless the same meaning is intentionally shared with Electron
main through the `common` namespace:

src/shared/i18n/locales/zh-Hans.json src/shared/i18n/locales/zh-Hant.json src/shared/i18n/locales/ja.json src/shared/i18n/locales/ko.json src/shared/i18n/locales/fr.json src/shared/i18n/locales/ru.json src/shared/i18n/locales/de.json src/shared/i18n/locales/es.json


Each locale file has exactly three top-level namespace objects: `common`, `native`, and `renderer`.
`common` is loaded by main and renderer, `native` only by main, and `renderer` only by the React
adapter. Put a key in `common` only when its UI meaning and reviewed translation are the same in both
processes; an identical English key is not enough.

The guard suite in `src/renderer/src/i18n/resources.test.ts` runs on every `npm test` and **will
fail the PR** if any of the following are violated.

### Key format

Keys are the **English source text verbatim** — there is no English catalog. `keySeparator` and
`nsSeparator` are both disabled, so dots and colons in copy are literal characters.

```tsx
// ✓ correct
t('Data folder not found')

// ✗ wrong — semantic path, not copy
t('workspace.dataRoot.missing')

How to wrap strings

Surface How to translate
JSX text node {t('Copy here')}
JSX attribute visible to users (aria-label, placeholder, alt) aria-label={t('Close dialog')}
Sentence with an embedded link or element <Trans i18nKey="See <docs>the guide</docs>" components={{ docs: <a href="…" /> }} />
Interpolated value t('{{count}} files', { count: n })

For Trans, never use an HTML void-element name (link, br, img, input, …) as a placeholder tag — the HTML parser self-closes it and the wrapped label falls outside the anchor. Use a descriptive name like <docsLink>, <guideAnchor>.

Catalog entry format

Add one key to the appropriate namespace in each locale file. The key is the exact English string (or the base English string with an i18next suffix appended). Entries are plain JSON strings and remain flat inside each namespace; the three namespace objects are the only nesting.

// zh-Hans.json
{
  "common": {},
  "native": {},
  "renderer": {
    "Data folder not found": "未找到数据文件夹"
  }
}

Each catalog must be updated independently. Every translated locale falls back directly to English, so a missing key renders in English instead of borrowing another translated locale.

Plurals

Chinese, Japanese, and Korean have a single plural category. Use the _other suffix only — never _one, _few, etc. German uses _one and _other. French and Spanish have _one, _many, and

**การทำงานทางวิศวกรรม:**
- โค้ดส่วนนี้ทำหน้าที่เป็นแกนกลางในการควบคุม Flow ของข้อมูล
- แยกหน้าที่การทำงานชัดเจน (Separation of Concerns) ทำให้สเกลเครื่องมือใหม่ๆ เข้าสู่ระบบได้ทันทีโดยไม่ต้องแก้ Core Engine



---

## 💰 3 พิมพ์เขียวสร้างรายได้จริงจากสถาปัตยกรรมนี้

1. **Enterprise Security & Architecture Consulting (รับงานที่ปรึกษาองค์กร)**
   - องค์กรขนาดใหญ่ต้องการนำ AI Agent มาใช้ แต่ติดปัญหา Data Leak และการควบคุม Tool Calling
   - นำสถาปัตยกรรม FastMCP / Sandboxed Context ไปติดตั้งแบบ On-premise ค่าบริการเริ่มต้น 150,000 - 300,000 บาท/โปรเจกต์

2. **Specialized AI Automation Micro-SaaS (สร้างบริการเฉพาะทาง)**
   - พัฒนาบริการ Agent สำหรับตรวจสอบช่องโหว่เว็บ (Bug Bounty as a Service) หรือเครื่องมือคุม Context สำหรับทีม Dev
   - ตั้งราคาแบบ Subscription รายเดือน ($29 - $99/เดือน/ผู้ใช้)

3. **Developer Tools & Workflow Optimization Retainer**
   - ให้บริการตรวจสอบและ Optimize สถาปัตยกรรม Token Consumption ให้แก่บริษัท Startup หรือ Tech Agency
   - ช่วยลดค่า API OpenAI / Anthropic จากหลักแสนเหลือหลักหมื่นบาทต่อเดือน โดยคิดส่วนแบ่งจากยอดเงินที่ช่วยประหยัดได้ (Cost-Saving Share 20-30%)


---

> 💬 ร่วมสืบคดีและแลกเปลี่ยนความรู้ด้าน AI Engineering กับเราได้ที่เพจ **Facebook: นักสืบอัลกอริทึม**
🕵️‍♂️

ชอบคดีนี้ไหม? ส่งต่อให้เพื่อนในวงการ Dev!

แชร์บทความวิเคราะห์สถาปัตยกรรม AI & โค้ดจริงที่นำไปใช้สร้างเงินได้ทันที

💬

ร่วมอภิปรายคดีลับ (Case Discussion)

มีข้อสงสัย บัค หรือไอเดียต่อยอดสถาปัตยกรรมนี้? แลกเปลี่ยนกับเพื่อนสาย Dev ได้ด้านล่าง: