Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

+1 467новых вакансий за сутки·93 721вакансия открыта сейчас·Новое:Talanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Новые вакансии в TelegramРаботодателям
Talanto
Вакансии
Компании7 267
РезюмеAIПодготовкаСтатьи
BoostТарифыBoost
Войти

Не нашли подходящее?

Пусть нужная вакансия найдёт вас сама.

  1. Подборка в TelegramНовые вакансии по вашему фильтру — сразу в бота.Подключить
  2. Мэтчи по резюмеЗагрузите резюме — покажем, где вы подходите лучше всего.Загрузить
  3. Сохранить фильтрНастройте поиск один раз и возвращайтесь к новым вакансиям.Настроить
Что нового на TalantoTalanto осенью: поиск с цифрами, вакансия по шагам и каталог компаний

Для работодателей

Опубликуйте вакансию — отклики придут в ваш кабинет.

  1. Вакансиябесплатно
  2. Откликиконтакты бесплатно
  3. Наймэтапы и интервью

40 компаний публикуют вакансии напрямую · 4 401 кандидат открыт к предложениям

Разместить вакансию

Популярные направления

Все подборки
  • Python17 129
  • Облачные технологии14 088
  • QA вакансии3 457
  • Backend вакансии2 115
  • Инженер данных1 805
  • Продакт-менеджер1 262

Разработка

  • Android1 865
  • iOS1 698
  • Fullstack вакансии989
  • AI вакансии949
  • Frontend вакансии744
  • Mobile вакансии44

По стеку

  • Go8 660
  • Java6 550
  • Node.js2 020
  • .NET1 722
  • Kotlin1 619
  • Rust1 455
  • C#711
  • PHP683
  • C++572

DevOps и инфраструктура

  • Kubernetes7 769
  • DevOps вакансии6 056
  • Linux-инфраструктура5 493
  • Terraform / IaC4 266
  • CI/CD3 250
  • Мониторинг и Observability1 788
  • SRE567
  • Кибербезопасность453

Аналитика и данные

  • Data Scientist1 142
  • Бизнес-аналитик927
  • Аналитик данных854
  • Системный аналитик153

Другие направления

  • Проджект-менеджер616
  • UI/UX дизайн146
  • Ручное тестирование14

По регионам

  • Вакансии в США44 281
  • Вакансии в Европе23 875
  • Вакансии в Канаде4 475
  • Работа в России3 922

По формату

  • Удалённые вакансии75 035
  • Релокация в США44 281
  • Гибридная работа12 401
  • Офисная работа7 079

По уровню

  • Senior вакансии42 679
  • Middle вакансии20 894
  • Junior вакансии6 722

Сейчас нанимают

Все компании
  • Wise190 вакансий
  • Rakuten189 вакансий
  • ASML166 вакансий
  • Grab137 вакансий
  • Celonis39 вакансий
  • Spotify37 вакансий
  • Adyen28 вакансий
  • Infobip28 вакансий
  • Monzo20 вакансий
  • Darktrace16 вакансий

Вакансии из 344 источников: карьерные страницы компаний и джоб-борды.

КомпанииО насНовостиПубличная офертаУсловия использованияПолитика конфиденциальностиПоддержка
←К теме LangGraphВсе вопросы
LangGraphJuniorКодинг

Как LangGraph представляет состояние с помощью TypedDict и как оно передаётся между узлами?

В закладки
Сначала попробуйте ответить сами30 секунд
Сравнить с ответом ↓

State в LangGraph определяется как TypedDict и передаётся между узлами как словарь. Каждый узел получает текущее состояние и возвращает словарь с изменёнными полями, которые LangGraph мёржит в общее состояние.

TypedDict как схема состояния

LangGraph использует TypedDict из модуля typing для определения структуры состояния графа. Это даёт статическую типизацию и явный контракт между узлами — каждый разработчик видит, какие поля существуют в состоянии.

from typing import TypedDict, Optional

class MyState(TypedDict):
    question: str           # Обязательное поле
    context: list[str]      # Список строк
    answer: Optional[str]   # Может быть None
    step_count: int         # Счётчик итераций

Как узлы получают и обновляют состояние

Узел — это обычная функция (или async-функция), которая принимает state: MyState и возвращает dict с полями для обновления. LangGraph делает мёрж: поля из возвращённого словаря перезаписывают соответствующие поля в текущем состоянии, остальные поля остаются неизменными.

from langgraph.graph import StateGraph, END

def step_retrieve(state: MyState) -> dict:
    # Получаем question из состояния
    question = state["question"]
    # Делаем поиск
    results = ["Document 1 about " + question, "Document 2 about " + question]
    # Возвращаем ТОЛЬКО изменённые поля
    return {"context": results}

def step_generate(state: MyState) -> dict:
    context = "\n".join(state["context"])
    question = state["question"]
    # Генерируем ответ
    answer = f"Based on context: {context[:100]}... Answer to: {question}"
    return {
        "answer": answer,
        "step_count": state["step_count"] + 1,
    }

# Узел не обязан возвращать все поля — только изменённые
def step_log(state: MyState) -> dict:
    print(f"Step {state['step_count']}: answer ready = {state['answer'] is not None}")
    return {}  # Пустой dict — состояние не меняется

Сборка графа

graph = StateGraph(MyState)

graph.add_node("retrieve", step_retrieve)
graph.add_node("generate", step_generate)
graph.add_node("log", step_log)

graph.set_entry_point("retrieve")
graph.add_edge("retrieve", "generate")
graph.add_edge("generate", "log")
graph.add_edge("log", END)

app = graph.compile()

# Запуск: передаём начальное состояние
initial_state: MyState = {
    "question": "What is LangGraph?",
    "context": [],
    "answer": None,
    "step_count": 0,
}
result = app.invoke(initial_state)
print(result["answer"])

Аккумулирующие поля через Annotated

По умолчанию каждый return перезаписывает поле. Чтобы поле накапливалось (например, список сообщений), используют Annotated с reducer-функцией:

from typing import Annotated
import operator

class ChatState(TypedDict):
    messages: Annotated[list[str], operator.add]  # Каждый return += к списку
    final_answer: str

def node_a(state: ChatState) -> dict:
    return {"messages": ["Node A processed"]}  # Добавит в конец списка

def node_b(state: ChatState) -> dict:
    return {"messages": ["Node B processed"]}  # Тоже добавит, не перезапишет

Подводные камни

  • Если узел возвращает поле с типом, несовместимым с TypedDict (например, str вместо list[str]), ошибка возникает в runtime, а не при компиляции.
  • Без Annotated[list, operator.add] каждый return полностью перезаписывает список — история сообщений будет содержать только последний элемент.
  • TypedDict не поддерживает валидацию значений — если нужна проверка типов в runtime, используйте Pydantic BaseModel вместо TypedDict.
  • Изменение схемы TypedDict (добавление/удаление поля) несовместимо с существующими checkpoints — при обновлении нужна миграция или сброс сохранённых состояний.
  • Передача изменяемых объектов (списков, словарей) без копирования между узлами может привести к неожиданным мутациям состояния.
  • Optional-поля не инициализируются автоматически — начальное состояние должно явно задавать все поля, иначе KeyError в первом узле.

Частые вопросы на собеседовании

  • Что является основной абстракцией в LangGraph — что такое nodes, edges и state?
  • Что такое LangGraph и как он расширяет LangChain для построения stateful агентских воркфлоу?
  • В каких data/AI-задачах LangGraph даёт реальный выигрыш, а где лучше выбрать другой инструмент или более простой pipeline?
  • Что такое checkpointer в LangGraph и как он обеспечивает воркфлоу с участием человека (human-in-the-loop)?

Типичные ошибки

  • Объяснять typeddict state только синтаксисом без shape, dtype, состояния или режима выполнения.
  • Игнорировать leakage, воспроизводимость, пустые входы и скрытые копии данных.
  • Не проверять production-симптомы: latency, память, ретраи, дрейф качества и несовпадение версий.

Что проверяет интервьюер

  • Может ли связать typeddict state с реальным контрактом входов и выходов.
  • Упоминает ли тесты, метрики, reproducibility и диагностику ошибок.
  • Видит ли различие между demo-кодом в ноутбуке и production-пайплайном.

Как вы знаете этот вопрос?

Проверить себя по теме LangGraph →

Источники

  • https://docs.langchain.com/oss/python/langgraph/graph-api
Следующий вопрос→Что является основной абстракцией в LangGraph — что такое nodes, edges и state?

Связанные темы

LangGraphdata-ailanggraphllm-orchestrationtool-calling