Установка, настройка, function calling
Ollama — самый простой способ запустить LLM локально. Одна команда для установки, одна для загрузки модели. Qwen 3 — мощная open-source модель от Alibaba с отличной поддержкой function calling.
# Linux: установка Ollama curl -fsSL https://ollama.com/install.sh | sh # macOS: brew install ollama # Windows: скачать с ollama.com/download # Загрузка Qwen 3 (8B — оптимальный баланс скорость/качество) ollama pull qwen3:8b # Если мощная видеокарта — берите 32B ollama pull qwen3:32b # Проверяем что модель работает ollama run qwen3:8b "Привет! Кто ты?" # Смотрим список установленных моделей ollama list
Устанавливаем Python-библиотеку ollama. Она общается с демоном Ollama по HTTP (localhost:11434). Пишем простой клиент для отправки сообщений и получения ответов.
# Установка библиотеки pip install ollama import ollama def ask_qwen(prompt, system=""): """Отправить запрос к Qwen 3 через Ollama.""" messages = [] if system: messages.append({"role": "system", "content": system}) messages.append({"role": "user", "content": prompt}) response = ollama.chat( model="qwen3:8b", messages=messages, options={"temperature": 0.3} ) return response["message"]["content"] # Тестируем answer = ask_qwen( "Объясни что такое function calling в трёх предложениях.", system="Отвечай на русском, кратко и по делу." ) print(answer)
Qwen 3 нативно поддерживает function calling. Определяем схему инструментов в формате OpenAI, передаём в ollama.chat() — модель сама решит, когда вызвать инструмент и вернёт структурированный вызов.
import json tools = [ { "type": "function", "function": { "name": "get_weather", "description": "Получить текущую погоду для города.", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "Название города"} }, "required": ["city"] } } } ] response = ollama.chat( model="qwen3:8b", messages=[{"role": "user", "content": "Какая погода в Берлине?"}], tools=tools ) # Qwen вернёт tool_call в ответе msg = response["message"] if msg.get("tool_calls"): for tc in msg["tool_calls"]: name = tc["function"]["name"] args = tc["function"]["arguments"] print(f"Qwen хочет вызвать {name}({args})") # Вывод: Qwen хочет вызвать get_weather({"city": "Берлин"})
Собираем всё вместе: агент с несколькими инструментами, циклом выполнения и памятью. Это полностью автономный AI-агент, работающий на вашем компьютере без интернета.
import ollama, json, subprocess, os def execute_tool(name, args_str): args = json.loads(args_str) if name == "calculator": return {"result": eval(args["expr"], {"__builtins__": {}}, {})} elif name == "run_shell": try: result = subprocess.run(args["command"], shell=True, capture_output=True, text=True, timeout=10) return {"stdout": result.stdout[:1000], "stderr": result.stderr[:500]} except Exception as e: return {"error": str(e)} elif name == "read_file": try: with open(os.path.expanduser(args["path"]), "r") as f: return {"content": f.read()[:2000]} except Exception as e: return {"error": str(e)} return {"error": f"Unknown tool: {name}"} class LocalAgent: def __init__(self, model="qwen3:8b"): self.model = model self.messages = [{"role": "system", "content": "Ты — AI-агент с инструментами."}] def run(self, user_input): self.messages.append({"role": "user", "content": user_input}) for _ in range(5): resp = ollama.chat(model=self.model, messages=self.messages, tools=tools) msg = resp["message"] if msg.get("tool_calls"): self.messages.append(msg) for tc in msg["tool_calls"]: result = execute_tool(tc["function"]["name"], tc["function"]["arguments"]) self.messages.append({"role": "tool", "content": json.dumps(result)}) else: self.messages.append(msg) return msg["content"] return "⚠️ Агент превысил лимит итераций." agent = LocalAgent() print(agent.run("Сосчитай (150 + 25) * 4")) print(agent.run("Сколько файлов в /tmp?"))
Добавляем стриминг — ответ от модели приходит токен за токеном, как в ChatGPT. Это особенно важно для локальных моделей, которые работают медленнее облачных API.
def stream_ask(prompt): """Стриминг ответа от Qwen 3 — печатаем токены по мере генерации.""" stream = ollama.chat( model="qwen3:8b", messages=[{"role": "user", "content": prompt}], stream=True ) full_response = "" for chunk in stream: token = chunk["message"]["content"] print(token, end="", flush=True) full_response += token print() return full_response # Пользователь видит как текст появляется постепенно stream_ask("Напиши короткое стихотворение про AI.")
Выносим конфигурацию агента в YAML-файл. Модель, системный промпт, доступные инструменты — всё настраивается без изменения кода. Удобно для разных сценариев использования.
# agent_config.yaml model: "qwen3:8b" system_prompt: "Ты — AI-ассистент разработчика. Помогаешь с bash, Python и файлами." temperature: 0.3 max_iterations: 5 tools: - calculator: true - run_shell: true - read_file: true - write_file: false # безопасность: отключаем запись # --- Python-загрузчик конфига --- import yaml def load_config(path="agent_config.yaml"): with open(path) as f: return yaml.safe_load(f) config = load_config() agent = LocalAgent(model=config["model"]) print(f"Агент запущен: {config['model']}, инструментов: {len(config['tools'])}")
Локальные модели требовательны к ресурсам. Вот конкретные приёмы для ускорения Qwen 3: квантование, настройка GPU-слоёв, размер контекста.
# Создаём кастомный Modelfile для Qwen 3 с оптимизациями ollama show qwen3:8b --modelfile > Modelfile.qwen3 # Редактируем Modelfile: FROM qwen3:8b PARAMETER num_ctx 4096 # контекст (по умолчанию 2048) PARAMETER num_gpu 32 # сколько слоёв на GPU PARAMETER num_thread 8 # потоки CPU для слоёв не на GPU PARAMETER temperature 0.3 # Создаём оптимизированную модель ollama create qwen3-fast -f Modelfile.qwen3 # Используем в коде: # agent = LocalAgent(model="qwen3-fast") # Мониторинг использования GPU во время генерации watch -n 0.5 nvidia-smi
Вы развернули полностью локальный AI-агент на базе Qwen 3. Он работает без интернета, все данные остаются на вашем компьютере. Агент умеет: выполнять shell-команды, считать, читать файлы — и сам решает, какой инструмент когда использовать. Qwen 3 отлично справляется с function calling, не уступая облачным аналогам. 8B-версия работает на GPU с 8 ГБ VRAM, 32B — на 24+ ГБ. Для продакшена рекомендую добавить YAML-конфигурацию и стриминг — пользовательский опыт становится indistinguishable от ChatGPT.