Używanie programu SQL MCP Server z modelami lokalnymi

Ważna

Serwer MCP (SQL Model Context Protocol) jest dostępny w narzędziu Data API Builder w wersji 1.7. Aby uzyskać najnowsze możliwości i poprawki błędów, użyj wersji zapoznawczej 2.0.

Serwer MCP (SQL Model Context Protocol) współpracuje z dowolnym klientem zgodnym z mcP, a nie tylko usługami sztucznej inteligencji hostowanymi w chmurze. Jeśli środowisko ogranicza dostęp do dużych modeli językowych (LLM) w chmurze — typowych w dziedzinie opieki zdrowotnej, obrony, finansów, energii i przemysłu morskiego — możesz połączyć lokalny model obsługiwany za pośrednictwem Ollama lub podobnych narzędzi. W tym przewodniku opisano konfigurację konfiguracji, konfigurację metadanych pól i wzorce monitów, które sprawiają, że małe modele lokalne są niezawodne.

Wymagania wstępne

  • Narzędzie wiersza polecenia Data API builder zostało zainstalowane i skonfigurowane z co najmniej jedną encją. Zainstaluj CLI.
  • Ollama z modelem obsługującym wywoływanie narzędzi (na przykład qwen3:8b, llama3.1:8b).
  • Python 3.10+ z pakietami mcp i ollama.
  • Uruchomione wystąpienie SQL Server z danymi.

Krok 1. Konfigurowanie metadanych pola

Metadane pola to najważniejszy krok konfiguracji dla dokładności modelu lokalnego. Bez nazw pól i opisów agenci widzą tylko nazwy encji i błędnie odgadują nazwy kolumn.

Warning

Pominięcie tego kroku skutkuje utworzeniem serwera MCP, który technicznie działa, ale jest funkcjonalnie bezużyteczny dla każdego modelu, który odczytuje odpowiedzi narzędzi. Model nie ma informacji o Twoich kolumnach.

Dodaj jednostkę z opisem, a następnie dodaj opisy pól zawierające prawidłowe wartości dla kolumn ograniczonych:

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"

Aby uzyskać pełną dokumentację interfejsu wiersza polecenia i najlepsze rozwiązania — w tym ograniczone wartości, opisy parametrów i wzorce skryptów — zobacz Dodawanie opisów do jednostek.

Note

Interfejs wiersza poleceń dab update traktuje przecinki jako separatory argumentów. Jeśli opis zawiera przecinki, edytuj dab-config.json bezpośrednio.

Krok 2. Uruchamianie programu SQL MCP Server

dab start

Program SQL MCP Server domyślnie nasłuchuje http://localhost:5000/mcp przy użyciu przesyłanego strumieniowo transportu HTTP. Każdy klient, który implementuje protokół MCP, może nawiązać połączenie z tym punktem końcowym.

Krok 3. Łączenie modelu lokalnego

Utwórz klienta MCP, który łączy model Ollama z programem SQL MCP Server. W poniższym przykładzie Python użyto MCP Python SDK i pakietu ollama.

Instalowanie zależności

pip install mcp ollama

Minimalna uprzęża Python

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?"))

Ten mechanizm obsługuje pełny cykl: wstępne wstrzykiwanie schematu, wykrywanie narzędzi, wywoływanie narzędzi w wielu turach oraz wyodrębnianie odpowiedzi końcowej. Dostosuj MODEL i MCP_URL do swojego środowiska.

Wstępne wstrzyknięcie schematu podczas uruchamiania

Małe modele lokalne (poniżej 14B parametrów) generują bardziej niezawodne wywołania narzędzi, gdy metadane schematu są wyświetlane w wierszu polecenia systemu przed rozpoczęciem konwersacji. Zamiast polegać na tym, że model sam wywoła describe_entities podczas rozmowy, wywołaj je podczas uruchamiania harnessu i wstrzyknij wynik.

Dlaczego przedwtrysk ma znaczenie

Metoda Zachowanie przy użyciu małych modeli
Odnajdywanie dynamiczne Model musi zdecydować, że najpierw wywoła describe_entities, następnie zinterpretuje wyniki, a potem wywoła właściwe narzędzie z poprawnymi nazwami pól. Wiele punktów awarii.
Wstępny wtrysk Model natychmiast widzi nazwy jednostek, nazwy pól i opisy. Poprawne wywołania narzędzia przy pierwszej próbie.

Przykład harnessu z poprzedniej sekcji pokazuje ten wzorzec. Funkcja get_schema() wywołuje describe_entities raz podczas uruchamiania i formatuje wynik w monicie systemowym.

Wskazówka

Większe modele chmurowe (GPT-4o, Claude) zwykle wykrywają schemat w trakcie rozmowy bez uprzedniego wstrzyknięcia. Ten wzorzec jest najbardziej cenny w przypadku modeli pod kątem parametrów 14B.

Ograniczanie odpowiedzi modelu

Model może wykonać poprawne wywołanie narzędzia, pobrać odpowiednie dane i nadal utworzyć niewłaściwą odpowiedź. Na przykład model, któremu zadano pytanie „ile serwerów produkcyjnych?”, może poprawnie pobrać 16 wierszy, a następnie odpowiedzieć 40-wierszowym podsumowaniem dla kierownictwa zawierającym zmyślone przykłady zamiast liczby 16.

Dodaj jawne reguły ujemne do monitu systemowego:

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.

Dokładność wywoływania narzędzi i dyscyplina odpowiedzi to dwa różne problemy. DAB zapewnia dokładne pobieranie danych za pośrednictwem warstwy narzędziowej. Mechanizm promptu określa, w jaki sposób model prezentuje wyniki.

Considerations

Temat Szczegóły
Sprzęt Wywoływanie narzędzi działa na niewymagającym sprzęcie. Model o 8 mld parametrów uruchomiony na konsumenckiej karcie graficznej Nvidia (8 GB pamięci wideo RAM) daje użyteczne wyniki. Należy oczekiwać opóźnienia rzędu kilkudziesięciu sekund dla każdego pytania, co sprawdza się w przypadku obciążeń wsadowych.
Wsadowe a interaktywne Małe modele dobrze nadają się do przetwarzania wsadowego (raporty wydajności, zapytania dotyczące stanów magazynowych), tam, gdzie dopuszczalna jest większa tolerancja opóźnień.
Dostępność narzędzi aggregate_records jest dostępny tylko w wersji zapoznawczej 2.0 i nowszej. W wersji 1.7.x liczba i zapytania agregacji wymuszają na modelu odczytywanie wszystkich pasujących wierszy. Zobacz dostępność narzędzia według wersji.
Transport Lokalne modele łączą się za pośrednictwem przesyłanego strumieniowo protokołu HTTP do /mcp. Standardowy transport wejściowy/wyjściowy (stdio) jest alternatywą dla konfiguracji jednoprocesowych.
Uwierzytelnianie Do lokalnego programowania użyj uprawnień anonymous. W przypadku środowiska produkcyjnego skonfiguruj uwierzytelnianie odpowiednie dla danego środowiska.