ត្រឡប់ទៅប្លុក

បង្កើតស្រទាប់ MCP Adapter ដោយ Flask៖ ការប្រកាសឧបករណ៍ Routing និង Debugging

MCP Server ដែលមានស្រាប់ភាគច្រើនផ្តល់តែសកម្មភាពមូលដ្ឋាន ដូច្នេះ Agent ត្រូវផ្សំសកម្មភាពអាជីវកម្មឡើងវិញរាល់លើក និងសម្រេចចិត្តដោយខ្លួនឯងពេលជំហានណាមួយបរាជ័យ។ ស្រទាប់ Flask adapter ស្តើងអាចប្រមូលការប្រកាសឧបករណ៍ routing ការប្រតិបត្តិ validation និង error semantics ទុកកន្លែងតែមួយ។

ពេលភ្ជាប់ browser environment ទៅ AI Agent មានរឿងមួយដែលជៀសមិនរួច៖ standard tools ផ្តល់តែសកម្មភាពមូលដ្ឋាន ប៉ុន្តែ business actions ត្រូវផ្សំដោយខ្លួនឯង។

យកឧទាហរណ៍ជាក់ស្តែងមួយ។ ដើម្បីបញ្ចប់ collection run មួយ លំហូរពិតគឺ “បើក environment តាមតំបន់ ភ្ជាប់ outbound connection ចូលមើលម្តងសម្រាប់ warm-up ហើយផ្ទៀងផ្ទាត់ថា outbound connection ប្រើបាន” បន្ទាប់មកទើបប្រគល់ការងារឱ្យ Agent។ MCP Server ដែលមានស្រាប់ជាទូទៅផ្តល់តែ single-step tools ដូចជា បើក environment, navigate, click និង screenshot។ គ្មាននរណាផ្សំលំហូរខាងលើជំនួសអ្នកទេ។ Agent ត្រូវរៀបចំពីសូន្យរាល់លើក ដែលយឺត ហើយបើជំហានកណ្តាលណាមួយបរាជ័យ វាក៏ត្រូវសម្រេចចិត្តដោយខ្លួនឯងថាត្រូវធ្វើអ្វីបន្ទាប់។

ស្រទាប់ adapter មានតួនាទីសម្រាប់រឿងនេះ៖ រក្សា composition logic, validation និង state នៅខាងអ្នក ហើយ expose ទៅខាងក្រៅតែ business action មួយ។

រចនាសម្ព័ន្ធអប្បបរមាដែលអាចដំណើរការ

ស្រទាប់ adapter ដែលអាចដំណើរការបានត្រូវការតែបីផ្នែក៖ tool declaration, request routing និង execution ជាមួយលទ្ធផលត្រឡប់។ ប្រើ Flask អាចដាក់អ្វីៗទាំងអស់ក្នុង process មួយ។

MCP 适配层把工具声明、JSON-RPC 路由、执行器和结构化结果串成可重试的业务流程

ចាប់ផ្តើមពី tool declaration ព្រោះវាកំណត់ថា Agent អាចមើលឃើញអ្វីខ្លះ។

# adapter/tools.py
TOOLS = [
    {
        "name": "prepare_environment",
        "description": "រៀបចំ environment ដែលអាចប្រើបានសម្រាប់តំបន់ ហើយត្រឡប់ environment ID ពេលរួចរាល់",
        "inputSchema": {
            "type": "object",
            "properties": {
                "region": {"type": "string", "description": "តំបន់ outbound ឧទាហរណ៍ US-CA"},
                "purpose": {"type": "string", "description": "Purpose label សម្រាប់ reuse និង quota statistics"},
                "timeout": {"type": "integer", "minimum": 10, "maximum": 120, "default": 60},
            },
            "required": ["region"],
            "additionalProperties": False,
        },
    },
    {
        "name": "open_page",
        "description": "បើក page ក្នុង environment ដែលបានកំណត់ ហើយរង់ចាំរហូតអាច interaction បាន",
        "inputSchema": {
            "type": "object",
            "properties": {
                "env_id": {"type": "string"},
                "url": {"type": "string"},
            },
            "required": ["env_id", "url"],
            "additionalProperties": False,
        },
    },
]

Router បែងចែក JSON-RPC methods។ Client នឹងសួរ tools/list មុន រួចហៅ tools/call តាមឈ្មោះ។

# adapter/app.py
from flask import Flask, request, jsonify
from adapter.tools import TOOLS
from adapter.runner import run_tool

app = Flask(__name__)

@app.post("/mcp")
def mcp():
    req = request.get_json(force=True)
    method, rid = req.get("method"), req.get("id")

    if method == "tools/list":
        return jsonify({"jsonrpc": "2.0", "id": rid, "result": {"tools": TOOLS}})

    if method == "tools/call":
        name = req["params"]["name"]
        args = req["params"].get("arguments", {})
        return jsonify({"jsonrpc": "2.0", "id": rid, "result": run_tool(name, args)})

    return jsonify({"jsonrpc": "2.0", "id": rid,
                    "error": {"code": -32601, "message": "method not found"}})

Execution layer គឺជាកន្លែងតែមួយដែលប៉ះ environment API និង page protocol។ លំហូរច្រើនជំហានត្រូវបានបញ្ចប់នៅទីនេះ ហើយ failures ក៏ត្រូវបានបម្លែងទៅទម្រង់តែមួយនៅទីនេះដែរ។

# adapter/runner.py
def run_tool(name, args):
    try:
        payload = HANDLERS[name](**args)
        return ok(payload)
    except ToolError as e:
        return fail(e.code, e.retryable, e.message)

គួរកំណត់ return format ឱ្យបានឆាប់។ កុំផ្ញើ low-level exceptions ដើមៗទៅ Agent ព្រោះវានឹងព្យាយាម parse strings ទាំងនោះ ហើយអាចសម្រេចចិត្តចម្លែក។ កំណត់ structure មួយដែលមាន result code ដូចជា {"ok": false, "code": "env_unavailable", "retryable": true, "attempts": 3}។ បន្ទាប់មក Agent ត្រូវសម្រេចតែពីររឿង៖ អាច retry បានទេ និងត្រូវបញ្ជូនទៅមនុស្សដោះស្រាយឬអត់។

របៀបរចនាប៉ារ៉ាម៉ែត្រ

Tool granularity គួរបែងចែកតាម business actions មិនមែនតាម APIs ទេ។ បើ wrap low-level endpoint រាល់មួយជាឧបករណ៍ដាច់ដោយឡែក នោះស្ទើរតែគ្មាន abstraction ព្រោះ Agent នៅតែត្រូវរៀបលំដាប់ជំហានដោយខ្លួនឯង។

សម្រាប់ parameters មានព្រំដែនច្បាស់៖ អ្វីដែល model គួរសម្រេច និងអ្វីដែល adapter layer គួរសម្រេចដោយខ្លួនឯង។ Region, purpose និង target URL ស្ថិតក្នុងក្រុមទីមួយ ដូច្នេះឱ្យ model បំពេញ។ Debug port, internal queue names និង environment pool ត្រូវស្ថិតក្នុងក្រុមទីពីរ; កុំដាក់ក្នុង schema ព្រោះមិនយូរមិនឆាប់ model អាចបំពេញខុស។

Selectors ជាចំណុចដែលងាយមានបញ្ហា។ ពេល page structure ប្រែប្រួល calls ដែល hard-code selector អាចខូចជាច្រើនតែម្តង។ ល្អជាងគេគឺឱ្យ model ផ្ញើ semantic target ដូចជា “ប៊ូតុងចូល” ដែលមានភាពថេរជាង ហើយរក្សា selector mapping នៅក្នុង adapter layer។ ដូច្នេះពេល page ផ្លាស់ប្តូរ កែតែមួយកន្លែងគ្រប់គ្រាន់។

Numeric parameters ត្រូវមាន upper limit។ បើ timeout, retry count ឬ page count មិនមាន maximum ក្នុង schema ទេ model អាចផ្ញើតម្លៃធំណាស់ ហើយ call មួយអាចអូសលើសដប់នាទី។ Tool ណាដែលមាន loop semantics ត្រូវមានចំណុចបញ្ចប់ច្បាស់។ ប្រើ field ដូចជា max_pages ដើម្បីកំណត់ដែន ជំនួសឱ្យ “បន្តទំព័ររហូតដល់អស់ទិន្នន័យ”។

Idempotency ក៏ត្រូវគិតដែរ។ ឱ្យ caller ផ្ញើ task_id; request ដដែលអាចត្រឡប់លទ្ធផលមុនភ្លាមៗ ដើម្បីជៀសវាង Agent retry ហើយបើក environment ពីរដង។

រក្សា return values ឱ្យតូច។ កុំត្រឡប់ screenshot ជា base64; ត្រឡប់ file reference។ សម្រាប់ list results ត្រូវមាន count និង truncation flag ជំនួសឱ្យដាក់ទាំងតារាងចូលក្នុង context។

ពេល Debug សូមពិនិត្យបីចំណុចនេះមុន

បើប្រើ stdio នោះ JSON-RPC ប្រើ stdout ដូច្នេះ logs មិនត្រូវសរសេរទៅ stdout ដាច់ខាត។ print មួយបន្ទាត់អាចធ្វើឱ្យ protocol parsing ខូចភ្លាម ហើយចំណាយពេល debug យូរ។ ផ្ញើ logs ទៅ stderr ឬ file ជាប្រព័ន្ធ។

MCP 适配层按标准输出分流、工具列表、逐步追踪和固定夹具的顺序排查问题

tools/list ជា checkpoint ដំបូង។ បើ declarations មិនត្រូវបាន load ទេ calls បន្ទាប់ទាំងអស់នឹងមិនកើតឡើង។ ពិនិត្យ tool names, schema structure និងមើលថា additionalProperties រារាំង parameter ណាមួយឬអត់។

Checkpoint ទីពីរគឺ trace តាមជំហាន។ សម្រាប់ call រាល់មួយ កត់ task_id, parameter summary, ពេលវេលា និង result code។ ពេលមានបញ្ហា អ្នកអាចដឹងថាវាជាប់នៅ environment creation, navigation ឬ validation។ រក្សា parameters ដើមនៃ failed cases ដើម្បី replay ដូចដើម — bug ដែលអាច reproduce បានជួសជុលលឿនជាង។

Checkpoint ទីបីគឺ fixed fixtures មួយសំណុំ៖ test page ដែលមានមាតិកាថេរ និង element locators មួយចំនួនដែលមិនប្រែប្រួល។ រាល់ពេលកែ adapter layer សូមរត់ smoke test ម្តង វាសន្សំពេលជាងការផ្ទៀងផ្ទាត់ដោយពាក្យសំដី។

ព្រំដែនសិទ្ធិ

Adapter layer គឺជាកន្លែងដែលសិទ្ធិប្រមូលផ្តុំខ្លាំងបំផុតក្នុងប្រព័ន្ធទាំងមូល៖ credentials, environments និង page operations ស្ថិតក្នុងដៃវា។ ដូច្នេះព្រំដែនត្រូវកំណត់នៅទីនេះ។

រក្សា credentials ក្នុង server-side configuration មិនដាក់ក្នុង tool parameters ឬ model context។ បែងចែក tools តាមកម្រិតហានិភ័យ៖ read-only tools ដូចជា screenshot និង text extraction បើកជាលំនាំដើម; write tools ដូចជា click, submit និង delete បិទជាលំនាំដើម ហើយបើកបណ្តោះអាសន្នតាម task។ វាធ្វើឱ្យការខូចខាតមានកម្រិត ទោះ model សម្រេចខុសក៏ដោយ។

បំបែក environments តាម purpose។ Accounts ផ្សេង និង tasks ផ្សេងត្រូវប្រើ environments ផ្សេង មិនលាយគ្នាក្នុង environment មួយ។ ក្នុង multi-account management ការបង្កើត environment, network outbound binding និង state maintenance អាចប្រគល់ឱ្យ environment layer ពិសេស។ Tools ដូចជា PurpleMark បំបែក layer នេះចេញ ហើយ adapter layer ទទួលខុសត្រូវតែ business composition និង validation។

រក្សា audit logs។ ត្រូវអាច export តាមពេលវេលាថា task ណាប្រើ environment ណា និងបានហៅ write tools អ្វីខ្លះ។ ពេលមានបញ្ហាពិត កំណត់ត្រានេះជាវិធីតែមួយក្នុងការស្ដារលំហូរឡើងវិញ។

ចុងក្រោយគឺព្រំដែនរឹង៖ adapter layer មិនគួរផ្តល់ផ្លូវណាមួយសម្រាប់រំលងច្បាប់របស់ platform ទេ។ សកម្មភាពដូចជា bulk registration, bypass verification ឬក្លែងអត្តសញ្ញាណ មិនត្រូវ package ជា tools ហើយក៏មិនត្រូវលាក់ក្រោមឈ្មោះ internal tools។ ពេល tool ត្រូវបាន expose ទៅ model calls អាចកើតឡើងស្វ័យប្រវត្តិ; មុនកើតហេតុគ្មានកន្លែងទប់ស្កាត់ដែលទុកចិត្តបាន ហើយក្រោយកើតហេតុក៏មិនអាចលុបផលប៉ះពាល់វិញបាន។

សម្រាប់ protocol versions និង field definitions សូមយោងឯកសារ MCP ផ្លូវការ។