Skip to main content
Glama
ndodth

MCPTest

by ndodth

สรุประบบ: (MCP + AI Agent)


1. ระบบนี้ทำอะไร

ระบบ MCP ที่คอยคุมการทำงานของ AI เป็นผู้ช่วยตอบคำถามเรื่องข้อมูล

  • ผู้ใช้ถาม $\rightarrow$ Agent เลือก tool $\rightarrow$ tool เช็ก cache ก่อน ไม่มีค่อยไป DB จริง $\rightarrow$ ถ้า DB เปลี่ยน ระบบแจ้งเตือนกลับมาล้าง cache ทันที


Related MCP server: Enterprise Financial Compliance Audit Framework

2. องค์ประกอบหลัก

ไฟล์

หน้าที่

main.py

AI Agent — รับคำถาม, ตัดสินใจเรียก tool ผ่าน Gemini

server.py

MCP Server — เปิด tools ให้ Agent เรียกใช้ฐานข้อมูล

semantic_cache.py

Cache ชั้น 1 — เก็บคำถาม-คำตอบเดิมแบบ embedding

webhook_cdc.py

รับแจ้งเตือนจาก Supabase เมื่อข้อมูลเปลี่ยน แล้วล้าง cache

schema.sql

โครงสร้าง DB (customers, purchase_ledger, customer_interactions)


3. ในฐานข้อมูล (DB) เก็บอะไรไว้บ้าง และป้องกันยังไง

DB (PostgreSQL บน Supabase) มี 3 ตารางหลัก:

ตาราง

เก็บอะไร

การป้องกัน / กลไก

customers

ข้อมูลโปรไฟล์ลูกค้า (ชื่อ, ข้อมูลติดต่อ ฯลฯ)

แก้ไขได้ปกติ แต่ทุกครั้งที่แก้ trigger จะยิง webhook แจ้งล้าง cache

purchase_ledger

ประวัติธุรกรรม/ยอดการเงินของลูกค้า

Append-only — ห้าม UPDATE/DELETE เด็ดขาด ผ่าน DB Trigger ที่บล็อกไว้ตรงๆ ที่ระดับฐานข้อมูล (ต่อให้เจาะเข้ามาตรงๆ ก็แก้ไม่ได้)

customer_interactions

ประวัติการพูดคุย/โต้ตอบกับลูกค้า พร้อมเก็บ embedding vector (ใช้ extension pgvector)

ใช้สำหรับ semantic search ย้อนดูบทสนทนาเก่าที่เกี่ยวข้อง

Hash Chain (สำหรับ purchase_ledger โดยเฉพาะ):

  • แต่ละ record ในตารางนี้จะมีค่า entry_hash ที่คำนวณจากข้อมูลของ record นั้น + prev_hash (hash ของ record ก่อนหน้า) ด้วย SHA-256

  • ทำให้ record ทั้งหมดเชื่อมกันเป็น "โซ่" ถ้ามีใครแอบไปแก้ข้อมูลตรงกลางโซ่ (แม้จะพยายามเลี่ยง trigger ก็ตาม) hash ของ record ถัดไปจะไม่ตรงกันทันที ตรวจจับได้ตอน audit

  • พูดง่ายๆ: ต่อให้ป้องกันด้วย trigger แล้ว hash chain คือ "เช็คซ้ำอีกชั้น" ว่าข้อมูลไม่ถูกแตะต้องจริงๆ

PROMPT ของ AI

SYSTEM_PROMPT = """
You are an Enterprise CRM & Financial Audit Ledger AI Assistant.
You have access to trusted backend tools that provide customer profiles, live financial transactions, audit logs, and historical interaction text search.
...
"""

4. Workflow

[1] ผู้ใช้พิมพ์คำถามเข้า main.py
      │
      ▼
[2] ระบบแปลงคำถามเป็น embedding (ด้วย Sentence-Transformers, รันในเครื่อง ไม่เสีย token)
      │
      ▼
[3] เช็ค Layer 1 – Semantic Cache ใน Redis
    ค้นด้วย key: semantic_cache:customer:{customer_id}:*
    เทียบ embedding คำถามใหม่ กับคำถามเก่าที่เคยถามและตอบไปแล้ว (cosine similarity)
      │
      ├───────────────────────────────┐
      ▼ (similarity ≥ 0.92)           ▼ ไม่เจอ / ไม่คล้ายพอ (MISS)
[4a] ส่งคำตอบเดิมกลับทันที          [4b] ส่งคำถาม + รายชื่อ tool ที่มีให้ Gemini
     จบ flow ตรงนี้                     (ไม่เรียก DB, ไม่เรียก DB cache เลย)
                                      │
                                      ▼
                                [5] Gemini ตัดสินใจว่าจะเรียก MCP tool ไหน
                                    (เช่น get_customer_profile, get_customer_financial_summary)
                                      │
                                      ▼
                                [6] Tool ทำงานผ่าน server.py
                                    เช็ค Layer 2 – DB Result Cache ใน Redis ก่อน
                                    key: cache:db:profile:{customer_id}
                                    หรือ cache:db:financial:{customer_id}:{page}:{limit}
                                      │
                                ┌─────┴──────┐
                                ▼ HIT        ▼ MISS
                          [7a] ดึงข้อมูล      [7b] Query PostgreSQL จริง
                               จาก Redis          แล้วเก็บผลลัพธ์ลง Redis
                               (เร็ว ไม่กิน DB)     (ตั้ง TTL 24 ชม.)
                                │            │
                                └─────┬──────┘
                                      ▼
                                [8] ได้ข้อมูลดิบกลับมาที่ Agent
                                      │
                                      ▼
                                [9] เรียก Gemini อีกครั้ง เพื่อเรียบเรียงข้อมูลดิบ
                                    ให้เป็นคำตอบภาษาคนอ่านง่าย
                                      │
                                      ▼
                                [10] ตอบกลับผู้ใช้
                                     + บันทึกคำถาม-คำตอบคู่นี้ลง Layer 1 cache
                                     (ไว้ให้คำถามคล้ายๆ กันครั้งหน้า hit ได้)
  • Layer 1 เช็คจาก ความหมายของคำถาม

  • Layer 2 เช็คจาก ผลลัพธ์ของ DB query ที่เคยทำมาก่อน — เป็นด่านที่สองที่กัน DB ไม่ให้โดนถามซ้ำ

  • ทั้งสอง layer แยกกันทำงานคนละหน้าที่ ไม่ใช่ตัวเดียวกัน


5. Webhook + Backend สำหรับล้าง Cache (CDC) — Workflow ละเอียด

[1] มีการเปลี่ยนแปลงข้อมูลจริงในตาราง customers หรือ purchase_ledger
    (เช่น เพิ่มธุรกรรมใหม่ / แก้โปรไฟล์ลูกค้า)
      │
      ▼
[2] PostgreSQL Trigger บนตารางนั้นทำงานทันที (ก่อน trigger นี้จะเรียกฟังก์ชัน notify_cache_invalidation() ที่เขียนไว้)
      │
      ▼
[3] ฟังก์ชันเรียก net.http_post(...) (มาจาก extension pg_net) ยิง HTTP POST ออกไปหา backend ภายนอก
      │
      ▼
[4] Backend ที่ deploy แยกไว้บน Render (ไฟล์ webhook_cdc.py, เขียนด้วย FastAPI) รับ request ที่ endpoint POST /api/webhook/db-change
      │
      ▼
[5] Backend ตรวจสอบ header x-supabase-signature เทียบกับ secret ที่ตั้งไว้
    → ถ้าไม่ตรง ปฏิเสธทันที (กัน webhook ปลอมยิงเข้ามาสั่งล้าง cache มั่ว)
      │
      ▼
[6] แกะ payload ดูว่า:
    - TG_TABLE_NAME = ตารางไหนที่เปลี่ยน (customers หรือ purchase_ledger)
    - ถ้า table = customers → เอา customer_id จาก record.id
    - ถ้า table = purchase_ledger → เอา customer_id จาก record.customer_id
      │
      ▼
[7] สั่งลบ key ใน Redis:
    - ลบ Layer 1 เสมอ: semantic_cache:customer:{customer_id}:*
      (เพราะคำตอบเก่าที่เคย cache ไว้อาจอ้างอิงข้อมูลลูกค้ารายนี้ที่เปลี่ยนไปแล้ว)
    - ลบ Layer 2 เฉพาะส่วนที่เกี่ยวกับตารางที่เปลี่ยน:
      cache:db:profile:{id} หรือ cache:db:financial:{id}:*
      │
      ▼
[8] ครั้งต่อไปที่มีคนถามถึงลูกค้ารายนี้ → Layer 1 และ Layer 2 จะ miss โดยอัตโนมัติ
    → ระบบไปดึงข้อมูลจาก DB จริง → ได้ข้อมูลล่าสุดเสมอ (Zero-Stale Data)

6. ทำไมเอา Redis มาใช้ (2-Layer Cache)

ปัญหาที่เจอ: ทุกครั้งที่ผู้ใช้ถามคำถาม ถ้าปล่อยให้ระบบวิ่งไปเรียก LLM หรือ query DB ใหม่ทุกครั้ง จะช้าและสิ้นเปลือง โดยเฉพาะกับคำถามที่ถามซ้ำๆ หรือคล้ายเดิม เลยเพิ่ม Redis เข้ามาเป็น cache 2 ชั้น:

  • ชั้น 1 (Semantic Cache) — คำถามคล้ายเดิม ตอบกลับเลยไม่ต้องเรียก LLM ใหม่

  • ชั้น 2 (DB Result Cache) — ผลลัพธ์จาก DB ที่ไม่ค่อยเปลี่ยน ดึงจาก Redis แทนที่จะยิง query เข้า PostgreSQL ใหม่ทุกครั้ง


7. ปัญหาการใช้ Token (LLM) และวิธีลด

ปัญหา: การเรียก Gemini ทุกครั้งที่มีคำถามเข้ามา ทำให้เสีย token และมี latency สูง โดยเฉพาะเวลาที่มีคนถามคำถามซ้ำๆ หรือคล้ายกัน วิธีที่แก้:

  1. Semantic Cache (Layer 1) — เช็คก่อนเรียก Gemini ทุกครั้งว่าเคยมีคนถามคำถามที่ "ความหมายคล้ายกัน" ไหม ถ้าคล้าย $\ge$ 0.92 $\rightarrow$ ข้ามการเรียก Gemini ไปเลย

  2. ใช้ Local Embeddings (Sentence-Transformers) แทนการยิง embedding ผ่าน API ของ Gemini/OpenAI — ขั้นตอนเช็คความคล้ายนี้เลยไม่เสีย token เพิ่มเลย เพราะรันฟรีแบบ offline

  3. แยก cache ตาม customer_id (multi-tenant) กันคำตอบของลูกค้ารายหนึ่งไปปนกับอีกราย

IMPORTANT

ข้อควรรู้: Layer 2 (DB cache) ช่วยลดแค่ฝั่ง DB load/latency เท่านั้น ไม่ได้ลด token ฝั่ง Gemini เพราะไม่ว่า Layer 2 จะ hit หรือ miss ตัว Agent ก็ยังต้องเรียก Gemini อย่างน้อย 2 ครั้งอยู่ดี (เลือก tool + สรุปคำตอบ) — ตัวเดียวที่ลด token จริงคือ Layer 1


8. ภาพรวมทั้งระบบ (End-to-End)

  1. ผู้ใช้ถามผ่าน main.py

  2. เช็ค Semantic Cache ก่อน — คล้ายพอก็ตอบเลย ไม่เรียก Gemini

  3. ถ้าไม่เจอ $\rightarrow$ Gemini เลือก tool ที่เหมาะสม

  4. Tool เช็ค DB Cache ก่อนค่อยไป PostgreSQL จริง

  5. ตอบกลับ + จำคำตอบไว้ใน cache

  6. ถ้า DB เปลี่ยนเมื่อไหร่ $\rightarrow$ Webhook ยิงมาล้าง cache อัตโนมัติทันที


NOTE

python3 -m venv venv
source venv/bin/activate # (สำหรับ Windows ให้ใช้: venv\Scripts\activate)
pip install -r requirements.txt

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that integrates with MySQL databases, enabling secure read and write operations through LLM-driven interfaces with support for transaction handling and performance monitoring.
    84
    18
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A production-ready MCP server for MySQL database integration with AI agents, enabling database exploration, CRUD operations, schema management, and performance monitoring through natural language.
    285
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    A governed MCP server that enforces a trust layer between AI agents and databases, requiring sign-off on joins and metrics and producing auditable receipts for every query.
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ndodth/MCPTest'

If you have feedback or need assistance with the MCP directory API, please join our Discord server