Az SQL MCP Server használata helyi modellekkel

Important

Az SQL Model Context Protocol (MCP) server a Data API Builder 1.7-es és újabb verziójában érhető el. A legújabb képességek és hibajavítások érdekében használja a legújabb 2.0-s kiadást.

Az SQL Model Context Protocol (MCP) server bármilyen MCP-kompatibilis ügyféllel működik, nem csak a felhőalapú AI-szolgáltatásokkal. Ha a környezet korlátozza a felhőbeli nagy nyelvi modellek (LLM) hozzáférését – ez gyakori az egészségügyi, védelmi, pénzügyi, energia- és tengerészeti iparágakban –, csatlakoztathat egy Ollama vagy hasonló eszközökkel kiszolgált helyi modellt. Ez az útmutató a kis helyi modelleket megbízhatóvá tevő beállítási, mezőadat-konfigurációs és parancssori mintákat ismerteti.

Prerequisites

  • A Data API Builder CLI telepítve és konfigurálva van legalább egy entitással. Telepítse a parancssori felületet.
  • Ollama egy olyan modellel, amely támogatja az eszközhívásokat (például qwen3:8b, llama3.1:8b).
  • Python 3.10+ a mcp és ollama csomagokkal.
  • Egy futó SQL Server-példány adatokkal.

1. lépés: Mező metaadatainak konfigurálása

A mező metaadatai a helyi modell pontosságának legfontosabb konfigurációs lépése. Mezőnevek és leírások nélkül az ügynökök csak az entitásneveket látják, és emiatt rosszul tippelik meg az oszlopneveket.

Warning

A lépés kihagyásával olyan MCP-kiszolgáló jön létre, amely technikailag működik, de funkcionálisan használhatatlan minden olyan modell számára, amely beolvassa az eszköz válaszait. A modell nem rendelkezik az oszlopokkal kapcsolatos információkkal.

Adja hozzá az entitást egy leírással, majd adjon hozzá olyan mezőleírásokat, amelyek a korlátozott oszlopok érvényes értékeit tartalmazzák:

dab add ServerInventory \
  --source dbo.ServerInventory \
  --permissions "anonymous:read" \
  --description "SQL Server instance inventory with version, environment, and sizing data"

dab update ServerInventory \
  --fields.name InstanceName --fields.primary-key true \
  --fields.description "SQL Server instance name (e.g., YOURSERVER01)"

dab update ServerInventory \
  --fields.name Environment \
  --fields.description "Deployment environment. Valid values: Prod, Dev, Test, UAT"

A parancssori felületre vonatkozó teljes referencia és ajánlott eljárások – beleértve a korlátozott értékeket, a paraméterleírásokat és a szkriptelési mintákat – lásd: Leírások hozzáadása entitásokhoz.

Note

A dab update parancssori felület argumentumelválasztóként kezeli a vesszőket. Ha a leírás vesszőt tartalmaz, inkább közvetlenül a dab-config.json elemet szerkessze.

2. lépés: Az SQL MCP Server indítása

dab start

Az SQL MCP Server alapértelmezés szerint a(z) http://localhost:5000/mcp címen figyel, és streamelhető HTTP-transzportot használ. Az MCP protokollt megvalósító összes ügyfél csatlakozhat ehhez a végponthoz.

3. lépés: A helyi modell csatlakoztatása

Hozzon létre egy MCP-ügyfelet, amely összeköti az Ollama-modellt az SQL MCP Serverrel. Az alábbi Python példa a MCP Python SDK és a ollama csomagot használja.

Függőségek telepítése

pip install mcp ollama

Minimális Python tesztkörnyezet

import asyncio
import json
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client
import ollama

MCP_URL = "http://localhost:5000/mcp"
MODEL = "qwen3:8b"

async def get_schema(session: ClientSession) -> str:
    """Call describe_entities and format results for the system prompt."""
    result = await session.call_tool("describe_entities", arguments={})
    entities = json.loads(result.content[0].text)
    lines = []
    for entity in entities.get("entities", []):
        fields = ", ".join(
            f"{f['name']} ({f.get('description', 'no description')})"
            for f in entity.get("fields", [])
        )
        lines.append(f"- {entity['name']}: {entity.get('description', '')}")
        if fields:
            lines.append(f"  Fields: {fields}")
    return "\n".join(lines)

async def run(user_question: str):
    async with streamable_http_client(MCP_URL) as (read, write, _):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # Preinject schema into the system prompt
            schema_text = await get_schema(session)
            system_prompt = f"""You query a SQL database through MCP tools.

Available entities:
{schema_text}

Rules:
- Use the exact field names shown above.
- Answer count questions with the count only.
- Do not produce summaries unless asked.
- Do not invent example data. Only return data from tool responses.
- If no results, say "No results found" and stop.
"""
            # Get available tools for Ollama
            tools_result = await session.list_tools()
            ollama_tools = [
                {
                    "type": "function",
                    "function": {
                        "name": t.name,
                        "description": t.description or "",
                        "parameters": t.inputSchema,
                    },
                }
                for t in tools_result.tools
            ]

            messages = [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_question},
            ]

            # Chat loop: let the model call tools until it produces a final answer
            while True:
                response = ollama.chat(
                    model=MODEL, messages=messages, tools=ollama_tools
                )
                msg = response["message"]
                messages.append(msg)

                if not msg.get("tool_calls"):
                    print(msg["content"])
                    break

                for tc in msg["tool_calls"]:
                    result = await session.call_tool(
                        tc["function"]["name"],
                        arguments=tc["function"]["arguments"],
                    )
                    messages.append(
                        {
                            "role": "tool",
                            "content": result.content[0].text,
                        }
                    )

asyncio.run(run("How many SQL 2019 servers are in production?"))

Ez a heveder kezeli a teljes ciklust: sémaelőzmény, eszközfelderítés, többfordulós eszközhívás és végső válasz kinyerése. Állítsa be a MODEL és MCP_URL elemeket a környezetének megfelelően.

Séma előzetes betöltése indításkor

A kis helyi modellek (14B paraméter alatt) megbízhatóbb eszközhívásokat hoznak létre, amikor a séma metaadatai a rendszer parancssorában jelennek meg a beszélgetés megkezdése előtt. Ahelyett, hogy arra hagyatkozna, hogy a modell a beszélgetés során önállóan meghívja a describe_entities elemet, hívja meg azt az indításkor, és szúrja be az eredményt.

Miért fontos a preinjekció?

Approach Viselkedés kis modellekkel
Dinamikus felderítés A modellnek először a hívás describe_entities mellett kell döntenie, majd értelmeznie kell az eredményeket, majd meg kell hívnia a megfelelő eszközt a megfelelő mezőnevekkel. Több hibapont.
Előinjekció A modell azonnal látja az entitásneveket, a mezőneveket és a leírásokat. Javítsa ki az eszközhívásokat az első kísérlet során.

Ezt a mintát az előző szakaszban szereplő hámminta szemlélteti. A get_schema() függvény indításkor egyszer meghívja a describe_entities elemet, és az eredményt a rendszerutasításba formázza.

Tip

A nagyobb felhőmodellek (GPT-4o, Claude) általában előzetes bejelentkezés nélkül fedezik fel a sémát a beszélgetés során. Ez a minta a legértékesebb a 14B paraméter alatti modellek esetében.

Modellválaszok korlátozása

A modell képes helyes eszközhívást végezni, lekérni a megfelelő adatokat, és továbbra is rossz választ adni. Ha például egy modellt megkérdeznek, hogy „hány éles kiszolgáló van?”, helyesen lekérhet 16 sort, majd a 16 szám helyett egy hallucinált példákat tartalmazó, 40 soros vezetői összefoglalóval válaszolhat.

Explicit negatív szabályok hozzáadása a rendszerkéréshez:

Rules:
- Answer count questions with the count only.
- Do not produce summaries unless the user asks for one.
- Do not invent example data. Only return data from tool responses.
- If a tool returns no results, say "No results found" and stop.

Az eszközhívási hűség és a válaszadási fegyelem két különböző probléma. A DAB biztosítja a pontos adatlekérést az eszközrétegen keresztül. A parancssori heveder szabályozza, hogy a modell hogyan jeleníti meg az eredményeket.

Considerations

Téma Részletek
Hardver Az eszközhívás a szerény hardvereken működik. Egy 8B-paraméteres modell egy fogyasztói Nvidia GPU-n (8 GB videó RAM) hasznos eredményeket hoz. Kérdésenként több tíz másodperces késleltetésre lehet számítani, ami jól illeszkedik a kötegelt feldolgozási feladatokhoz.
Kötegelt és interaktív feldolgozás összehasonlítása A kis modellek jól használhatók kötegelt feldolgozáshoz (teljesítményjelentésekhez, leltár-lekérdezésekhez), ahol a késési tűrés magasabb.
Eszköz rendelkezésre állása Az aggregate_records eszköz csak a 2.0-s és újabb verziókban érhető el. Az 1.7.x verzióban a darabszám- és összesítési lekérdezések arra kényszerítik a modellt, hogy beolvassa az összes egyező sort. Tekintse meg az eszköz rendelkezésre állását verzió szerint.
Szállítás A helyi modellek streamelhető HTTP-n keresztül csatlakoznak a /mcp-hoz. A standard bemeneti/kimeneti (stdio) átvitel alternatívát jelent az egyfolyamatos beállításokhoz.
Authentication Helyi fejlesztéshez használja anonymous az engedélyeket. Éles környezetben konfigurálja a környezetnek megfelelő hitelesítést.