🐋

DeepSeek API: создание AI-агента на Python

Инструменты, память, цепочки вызовов

intermediate ⏱ 22 мин
👤 Пользователь 🐋 DeepSeek Agent • System prompt • Conversation history • Tool definitions • Function call parser • Response formatter 🔍 web_search requests + BeautifulSoup 🧮 calculator eval() в sandbox 📁 read_file pathlib + open() 🌐 api.deepseek.com deepseek-chat / deepseek-reasoner Архитектура: DeepSeek Agent с инструментами на Python

# 1. Получение API-ключа и установка библиотек

Регистрируемся на platform.deepseek.com, получаем API-ключ. Устанавливаем openai-совместимую библиотеку — DeepSeek API полностью совместим с OpenAI SDK, поэтому менять код почти не придётся.

# Установка зависимостей
pip install openai httpx python-dotenv

# Создаём .env файл с ключом
echo 'DEEPSEEK_API_KEY=sk-your-key-here' > .env

# 2. Базовый клиент для DeepSeek API

Инициализируем клиент OpenAI с base_url указывающим на DeepSeek. Проверяем что всё работает простым запросом. Модель deepseek-chat — это V3, deepseek-reasoner — R1.

import os
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()

client = OpenAI(
    api_key=os.getenv("DEEPSEEK_API_KEY"),
    base_url="https://api.deepseek.com"
)

# Тестовый запрос
response = client.chat.completions.create(
    model="deepseek-chat",
    messages=[
        {"role": "system", "content": "Ты — полезный AI-ассистент."},
        {"role": "user", "content": "Какая погода в Москве?"}
    ],
    max_tokens=200
)

print(response.choices[0].message.content)

# 3. Инструменты (function calling) для агента

Определяем доступные агенту инструменты в формате OpenAI function calling. DeepSeek поддерживает этот формат. Агент сам решает, когда и какой инструмент вызвать, и передаёт параметры.

tools = [
    {
        "type": "function",
        "function": {
            "name": "calculator",
            "description": "Вычисляет математическое выражение. Поддерживает +, -, *, /, **, sqrt.",
            "parameters": {
                "type": "object",
                "properties": {
                    "expression": {
                        "type": "string",
                        "description": "Математическое выражение, например '(15 + 7) * 3'"
                    }
                },
                "required": ["expression"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "read_file",
            "description": "Читает содержимое текстового файла с диска.",
            "parameters": {
                "type": "object",
                "properties": {
                    "filepath": {"type": "string", "description": "Путь к файлу"}
                },
                "required": ["filepath"]
            }
        }
    }
]

# 4. Цикл агента: распознавание и выполнение tool calls

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

import json

def execute_tool(name, args):
    if name == "calculator":
        expr = args["expression"]
        try:
            # safe eval: разрешены только числа, операторы и math
            result = eval(expr, {"__builtins__": {}}, {"sqrt": lambda x: x**0.5})
            return {"result": result}
        except Exception as e:
            return {"error": str(e)}
    elif name == "read_file":
        try:
            with open(args["filepath"], "r") as f:
                content = f.read()[:2000]
            return {"content": content}
        except Exception as e:
            return {"error": str(e)}
    return {"error": f"Unknown tool: {name}"}

messages = [
    {"role": "system", "content": "Ты агент с доступом к инструментам. Используй их когда нужно."},
    {"role": "user", "content": "Сколько будет (256 * 4) / 8?"}
]

for _ in range(5):  # максимум 5 итераций
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=messages,
        tools=tools,
        tool_choice="auto"
    )
    msg = response.choices[0].message

    if msg.tool_calls:
        messages.append(msg)
        for tool_call in msg.tool_calls:
            name = tool_call.function.name
            args = json.loads(tool_call.function.arguments)
            result = execute_tool(name, args)
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result)
            })
    else:
        print(msg.content)
        break

# 5. Добавление памяти: хранение истории диалога

Агент с памятью хранит всю историю сообщений. При каждом запросе история отправляется заново — так модель помнит контекст всей беседы. Ограничиваем историю последними 20 сообщениями, чтобы не переполнять токены.

class DeepSeekAgent:
    def __init__(self, system_prompt):
        self.system_prompt = system_prompt
        self.history = []  # вся история диалога
        self.max_history = 20

    def chat(self, user_input):
        self.history.append({"role": "user", "content": user_input})

        messages = [{"role": "system", "content": self.system_prompt}]
        messages += self.history[-self.max_history:]

        response = client.chat.completions.create(
            model="deepseek-chat",
            messages=messages,
            tools=tools,
            tool_choice="auto"
        )
        answer = response.choices[0].message.content
        self.history.append({"role": "assistant", "content": answer})
        return answer

agent = DeepSeekAgent("Ты — DeepSeek агент. Отвечай на русском, кратко.")
print(agent.chat("Кто ты?"))
print(agent.chat("Помнишь мой первый вопрос?"))  # да, помнит!

# 6. Веб-поиск как инструмент агента

Добавляем агенту возможность искать информацию в интернете. Используем бесплатный SerpAPI или прямой парсинг DuckDuckGo. Агент сам решает, когда нужно искать.

import httpx
from urllib.parse import quote

def web_search(query):
    """Поиск через DuckDuckGo Instant Answer API (бесплатно, без ключа)."""
    url = f"https://api.duckduckgo.com/?q={quote(query)}&format=json&no_html=1"
    resp = httpx.get(url, timeout=10)
    data = resp.json()
    results = []
    if data.get("AbstractText"):
        results.append({"title": data.get("AbstractSource"), "snippet": data["AbstractText"]})
    for topic in data.get("RelatedTopics", [])[:3]:
        if "Text" in topic:
            results.append({"snippet": topic["Text"]})
    return results[:5]

# Регистрируем в tools и execute_tool — агент сам вызовет когда нужно

# 7. LangChain + DeepSeek: продвинутый агент

Используем LangChain для более сложной логики: автоматическое управление памятью, цепочки вызовов, шаблоны промптов. LangChain работает с DeepSeek через ChatOpenAI c кастомным base_url.

# pip install langchain langchain-openai
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain.tools import tool
from langchain_core.prompts import ChatPromptTemplate

llm = ChatOpenAI(
    model="deepseek-chat",
    openai_api_key=os.getenv("DEEPSEEK_API_KEY"),
    openai_api_base="https://api.deepseek.com",
    temperature=0.3
)

@tool
def calculator(expression: str) -> str:
    """Вычисляет математическое выражение."""
    return str(eval(expression, {"__builtins__": {}}, {}))

prompt = ChatPromptTemplate.from_messages([
    ("system", "Ты полезный AI-агент. Используй инструменты когда нужно."),
    ("placeholder", "{chat_history}"),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}"),
])

agent = create_tool_calling_agent(llm, [calculator], prompt)
executor = AgentExecutor(agent=agent, tools=[calculator], verbose=True)

result = executor.invoke({"input": "Сколько будет 125 * 37?"})
print(result["output"])
✅ Итог

Вы создали полноценного AI-агента на Python с DeepSeek API. Агент умеет: выполнять математические вычисления, читать файлы с диска, искать информацию в интернете, хранить историю диалога. Благодаря совместимости DeepSeek с OpenAI SDK, переход занимает ровно одну строку — смена base_url. Для продакшена используйте LangChain — он берёт на себя управление памятью и потоком выполнения. DeepSeek при этом значительно дешевле конкурентов: $0.27 за миллион входных токенов против $2.50 у GPT-4o.

🔗 Полезные ссылки

📖 DeepSeek API Docs 💻 GitHub 🔗 LangChain Docs