Использование SQL MCP Server с локальными моделями

Important

Сервер контекста модели SQL (MCP) доступен в построителе данных версии 1.7. Для последних возможностей и исправлений ошибок используйте предварительную версию версии 2.0.

Сервер контекста модели SQL (MCP) работает с любым клиентом, совместимым с MCP, а не только облачными службами ИИ. Если ваша среда ограничивает доступ к облачной крупной языковой модели (LLM), распространенной в области здравоохранения, обороны, финансов, энергетики и морских отраслей, вы можете подключить локальную модель, обслуживаемую с помощью Ollama или аналогичных инструментов. В этом руководстве рассматриваются настройки, конфигурация метаданных поля и шаблоны запросов, которые делают небольшие локальные модели надежными.

Необходимые условия

  • Интерфейс командной строки Data API Builder, установленный и настроенный хотя бы с одной сущностью. Установите ИНТЕРФЕЙС командной строки.
  • Ollama с моделью, которая поддерживает вызов инструментов (например, qwen3:8b, llama3.1:8b).
  • Python 3.10+ с пакетами mcp и ollama.
  • Запущенный экземпляр SQL Server с данными.

Шаг 1. Настройка метаданных поля

Метаданные поля — это наиболее важный шаг конфигурации для точности локальной модели. Без имен полей и описаний агенты видят только имена сущностей и неправильно угадывают имена столбцов.

Предупреждение

Пропуск этого шага создает сервер MCP, который технически работает, но функционально не используется любой моделью, которая считывает ответы средства. У модели нет информации о ваших столбцах.

Добавьте сущность с описанием, а затем добавьте описания полей, которые содержат допустимые значения для ограниченных столбцов:

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"

Полные справочные материалы и рекомендации по CLI, включая ограниченные значения, описания параметров и шаблоны сценариев, см. в разделе "Добавление описаний в сущности".

Note

Интерфейс командной dab update строки обрабатывает запятые как разделители аргументов. Если описание содержит запятые, вместо этого редактируйте dab-config.json напрямую.

Шаг 2. Запуск SQL MCP Server

dab start

SQL MCP Server по умолчанию прослушивает http://localhost:5000/mcp с использованием потокового HTTP-транспорта. Любой клиент, реализующий протокол MCP, может подключаться к этой конечной точке.

Шаг 3. Подключение локальной модели

Создайте клиент MCP, который подключает модель Ollama к SQL MCP Server. В следующем примере Python используется пакет SDK MCP Python и пакет ollama.

Установка зависимостей

pip install mcp ollama

Минимальное использование 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?"))

Этот модуль обеспечивает полный цикл: предварительное внедрение схемы, поиск инструментов, многошаговое обращение к инструментам и извлечение окончательного ответа. Настройте MODEL и MCP_URL для вашей среды.

Предварительно внедрить схему при запуске

Небольшие локальные модели (под параметрами 14B) создают более надежные вызовы инструментов при появлении метаданных схемы в системном запросе до начала беседы. Вместо того чтобы полагаться на то, что модель сама вызовет describe_entities в ходе диалога, вызовите его при запуске harness и подставьте результат.

Почему важна предварительная инъекция

Подход Поведение с небольшими моделями
Динамическое обнаружение Модель должна сначала вызвать describe_entities, затем интерпретировать результаты, а потом вызвать нужный инструмент с правильными именами полей. Несколько точек сбоя.
Предварительное впрыскивание Модель сразу видит имена сущностей, имена полей и описания. Корректные вызовы инструментов с первой попытки.

Пример с harness в предыдущем разделе демонстрирует этот шаблон. Функция get_schema() один раз при запуске вызывает describe_entities и вставляет результат в системный промпт в отформатированном виде.

Tip

Более крупные облачные модели (GPT-4o, Claude) обычно выявляют схему в ходе диалога без предварительного внедрения. Этот шаблон наиболее полезен для моделей с числом параметров менее 14 млрд.

Ограничение ответов модели

Модель может выполнить правильный вызов инструмента, получить нужные данные и всё равно дать неверный ответ. Например, модель с запросом "сколько рабочих серверов?" может правильно получить 16 строк, а затем ответить с 40-строкой исполнительной сводки, содержащей галлюцинированные примеры вместо числа 16.

Добавьте явные отрицательные правила в системный запрос:

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.

Точность вызова инструментов и дисциплина ответов — это разные проблемы. DAB обеспечивает точное получение данных через инструментальный слой. Подсказка определяет, как модель представляет результаты.

Considerations

Тема Сведения
Оборудование Вызов функций работает даже на маломощном оборудовании. Модель 8B-параметров на пользовательском GPU Nvidia (8 ГБ видео ОЗУ) дает полезные результаты. Ожидается задержка в десятках секунд на вопрос, которая подходит для пакетных рабочих нагрузок.
Пакетный и интерактивный режимы Небольшие модели хорошо подходят для пакетной обработки (отчёты о производительности, инвентарные запросы), где допустима более высокая задержка.
Доступность инструментов aggregate_records доступен только в предварительной версии 2.0 и более поздних версиях. В версии 1.7.x запросы подсчета и агрегирования принудительно позволяют модели считывать все соответствующие строки. Просмотр доступности инструментов по версии.
Транспорт Локальные модели подключаются по потоковому HTTP к /mcp. Стандартный транспорт ввода и вывода (stdio) является альтернативой для однопроцессных настроек.
Аутентификация Для локальной разработки используйте anonymous разрешения. Для рабочей среды настройте проверку подлинности , соответствующую вашей среде.