Руководства

LangChain

LangChain через AITUNNEL: ChatOpenAI и эмбеддинги, один ключ, оплата в рублях, VPN не нужен.

LangChain — стандартный интерфейс чат-моделей и эмбеддингов. AITUNNEL — OpenAI-совместимый API: подключайте ChatOpenAI / OpenAIEmbeddings из langchain-openai и base_url. Не берите ChatAnthropic, init_chat_model("claude-…") или langchain-openrouter — они уйдут мимо AITUNNEL.

Установка

pip install -U langchain-openai

Чат

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="claude-sonnet-4.6",
    api_key="sk-aitunnel-xxx",
    base_url="https://api.aitunnel.ru/v1/",
    max_tokens=1000,
)

response = llm.invoke("Объясни, что такое LangChain, в трёх предложениях.")
print(response.content)

Эмбеддинги

from langchain_openai import OpenAIEmbeddings

embeddings = OpenAIEmbeddings(
    model="text-embedding-3-small",
    api_key="sk-aitunnel-xxx",
    base_url="https://api.aitunnel.ru/v1/",
)

vectors = embeddings.embed_documents([
    "Искусственный интеллект",
    "Машинное обучение",
    "Нейронные сети",
])

print(len(vectors), "векторов,", len(vectors[0]), "измерений")

Полный пайплайн поиска и ответа — руководство по RAG.

Примеры

Цепочка

цепочка
from langchain_core.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "Ты — эксперт по {topic}. Отвечай кратко и по делу."),
    ("user", "{question}"),
])

chain = prompt | llm

response = chain.invoke({
    "topic": "Python",
    "question": "Какие основные отличия list и tuple?",
})

print(response.content)

Стриминг

stream
for chunk in llm.stream("Напиши короткий рассказ о роботе"):
    print(chunk.content, end="", flush=True)

RAG

RAG
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_core.vectorstores import InMemoryVectorStore
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

llm = ChatOpenAI(
    model="gemini-3.5-flash",
    api_key="sk-aitunnel-xxx",
    base_url="https://api.aitunnel.ru/v1/",
)

embeddings = OpenAIEmbeddings(
    model="text-embedding-3-small",
    api_key="sk-aitunnel-xxx",
    base_url="https://api.aitunnel.ru/v1/",
)

texts = [
    "AITUNNEL — единый OpenAI-совместимый API к GPT, Claude, Gemini и другим.",
    "Оплата в AITUNNEL — pay-as-you-go, в рублях.",
    "AITUNNEL поддерживает чат, картинки, видео, аудио и эмбеддинги.",
]
vectorstore = InMemoryVectorStore.from_texts(texts, embedding=embeddings)
retriever = vectorstore.as_retriever()

prompt = ChatPromptTemplate.from_template(
    "Контекст: {context}\n\nВопрос: {question}\n\nОтвет:"
)

chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

print(chain.invoke("Как работает оплата?"))

InMemoryVectorStore входит в langchain-core (зависимость langchain-openai). Для продакшена — руководство по RAG.

Быстрая и умная модель

две модели
fast_llm = ChatOpenAI(
    model="gemini-3.5-flash",
    api_key="sk-aitunnel-xxx",
    base_url="https://api.aitunnel.ru/v1/",
)

smart_llm = ChatOpenAI(
    model="claude-sonnet-4.6",
    api_key="sk-aitunnel-xxx",
    base_url="https://api.aitunnel.ru/v1/",
)

classification = fast_llm.invoke(
    "Классифицируй: 'Хочу вернуть товар' → жалоба/вопрос/благодарность"
)
response = smart_llm.invoke(
    f"Напиши вежливый ответ клиенту: {classification.content}"
)

Практика

  1. Модель под шаг. Промежуточная классификация — gemini-3.5-flash, финальный ответ — claude-sonnet-4.6 или gpt-5.6-sol.
  2. Стриминг. .stream() для UI.
  3. Ключ не в коде. OPENAI_API_KEY и OPENAI_API_BASE=https://api.aitunnel.ru/v1 — тогда api_key / base_url в конструкторе можно не дублировать. LangChain читает OPENAI_API_BASE, затем OPENAI_BASE_URL.
  4. Имена из каталога. Слаг со слешем уходит в OpenRouter.

RAG целиком

Индекс, rerank и генерация одним ключом — в руководстве по RAG.

Смотрите также