Главная / Статьи / Практические советы: Создайте свой собственный Claude Code с использованием Langchin: подробный обзор

Практические советы: Создайте свой собственный Claude Code с использованием Langchin: подробный обзор

Пошаговое руководство по практическим заметкам: создайте собственный Claude Code с использованием Langchin: подробное рассмотрение контрактов, проверок и слотов для вставки кода для команд, использующих эту схему.

3402 слов

В этом руководстве показано, как пройти путь от сырья до готовой системы для проекта Build Your Own Claude Code Using Langchin: A Deepdive Into LangChain’s Deep Agents. Основное внимание уделяется практическим шагам, четкой проверке результатов и коду, который можно просто добавить в репозиторий без необходимости угадывать его назначение. На этапе обзора необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед внесением изменений в код. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не пытаясь угадать скрытое состояние. Конфигурацию следует хранить отдельно от кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь кодовый граф.

Архитектура агента для программирования

При работе над «Архитектурой этапа» сначала запишите условия работы: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой список поможет сохранять честность при последующих изменениях кода. Документируйте одновременно успешный и восстановительный пути выполнения. Повторные попытки, проверки человеком и обработка неработоспособных сообщений являются частью продукта, а не элементами последующей доработки. Создавайте контрольные точки после дорогостоящих операций. Механизм возобновления работы не должен повторно взимать плату за один и тот же вызов большой языковой модели, когда оператор пытается выполнить следующий этап.

Часть 0: Цикл с нуля — без фреймворков, без волшебства

При работе над частью 0 «Этап цикла» сначала запишите спецификацию: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой список поможет сохранять честность при последующих изменениях кода. Предпочитайте небольшие, тестируемые модули большим скриптам. Когда какой-то шаг терпит неудачу, ошибка должна указывать на конкретную ответственность, а не на запутанную цепочку операций. Вносите контрольные точки после дорогостоящих шагов. Функция возобновления работы не должна повторно взимать плату за один и тот же вызов LLM, когда оператор пытается выполнить следующий узел заново.

def run_agent_loop(client, user_message, tools, tool_functions, max_turns=20):
    messages = [{"role": "user", "content": user_message}]
    for _ in range(max_turns):
        # 1. Ask the model what to do next.
        response = client.messages.create(
            model="claude-sonnet-4-6", max_tokens=1024, tools=tools, messages=messages
        )
        messages = [*messages, {"role": "assistant", "content": response.content}]

        # 2. Plain text and no tool request? The job is done.
        tool_uses = [b for b in response.content if b.type == "tool_use"]
        if not tool_uses:
            return "".join(b.text for b in response.content if b.type == "text")
        # 3. Run each requested tool and hand the results back. 4. Repeat.
        results = [
            {"type": "tool_result", "tool_use_id": call.id,
             "content": tool_functions[call.name](**call.input)}
            for call in tool_uses
        ]
        messages = [*messages, {"role": "user", "content": results}]
    raise RuntimeError(f"agent loop did not finish within {max_turns} turns")

Часть 1: Цикл — двигатель, приводящий в действие всё

При работе над этапом «Цикл» части 1 сначала запишите контракт: необходимые входные данные, сигнал о успехе и действия при частичной неудаче. Такой список поможет сохранять честность при последующих изменениях кода. Рассматривайте этот этап как контракт между входными данными и проверенными выходными данными. Дайте названия результатам обработки, определите критерии успеха и не допускайте безусловного частичного завершения работы. Выполняйте контрольные точки после дорогостоящих операций. Система возобновления работы не должна снова запрашивать один и тот же вызов большой языковой модели, когда оператор пытается выполнить следующий элемент. При работе над этапом «Цикл» части 1 сначала запишите контракт: необходимые входные данные, сигнал о успехе и действия при частичной неудаче. Такой список поможет сохранять честность при последующих изменениях кода. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь код.

pip install deepagents langchain-anthropic
from deepagents import create_deep_agent

def get_weather(city: str) -> str:
    """Get the weather for a given city."""
    return f"It's always sunny in {city}!"
agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[get_weather],
    system_prompt="You are a helpful assistant.",
)
result = agent.invoke(
    {"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
)

Часть 2: Инструменты — предоставление агенту возможностей

Этап «Инструменты» в части 2 работает наилучшим образом, когда его рассматривают как измеримую поверхность. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объёма работ. Документируйте одновременно успешный и восстановительный пути выполнения. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не этапом последующей доработки. Обеспечьте доступ к инструментам с узкими схемами и чёткими метками побочных эффектов. Хостам необходимо знать, какие вызовы изменяют состояние, прежде чем они автоматически одобрят их.

Почему просто не позволить модели выполнять любую команду?

Всё будет работать лучше, если рассматривать этот процесс как измеримую поверхность. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объёма работ. Лучше использовать небольшие, тестируемые единицы вместо обширных скриптов. Когда происходит сбой, он должен указывать на конкретную ответственность, а не на запутанную цепочку операций. Установите лимиты на количество токенов за ход и за сессию. Инструменты типа агентов активно расширяют объём контекста; жесткие ограничения предотвращают появление неожиданных счетов.

Создание с помощью Deep Agents

Этап «Создание с помощью Deep» работает наилучшим образом, когда его рассматривают как измеримую поверхность. Сохраните один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работ. Рассматривайте этот этап как контракт между входными данными и проверенными выходными результатами. Дайте названия создаваемым элементам, определите критерии успешного выполнения и не соглашайтесь на молчаливое частичное завершение работы. Сохраняйте структуру графа простой и типизированной. Вложенные структуры скрывают информацию о том, какой узел заполнил тот или иной поле, и мешают возобновлению работы после прерываний. Этап «Создание с помощью Deep» работает наилучшим образом, когда его рассматривают как измеримую поверхность. Сохраните один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работ. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь граф.

import subprocess
from langchain_core.tools import tool

MAX_OUTPUT_CHARS = 20_000  # roughly 5k tokens
@tool
def run_tests(path: str = ".") -> str:
    """Run the project's pytest suite and return its output.
    Output is truncated to the last 20k characters (failures appear at the
    end). The run is killed after 5 minutes.
    """
    try:
        result = subprocess.run(["pytest", path], capture_output=True,
                                text=True, check=False, timeout=300)
    except subprocess.TimeoutExpired:
        return "pytest timed out after 300s"
    output = result.stdout + result.stderr
    if len(output) > MAX_OUTPUT_CHARS:
        return ("[... output truncated to the last 20,000 characters ...]\n"
                + output[-MAX_OUTPUT_CHARS:])
    return output
agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[run_tests],            # merged in alongside the built-ins
    system_prompt="You are a coding assistant. Always run tests after editing.",
)

Часть 3: Планирование — думайте перед тем, как действовать

На этапе планирования в части 3 необходимо определить исходные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Необходимо задокументировать как успешный, так и аварийный сценарии работы. Повторные попытки, проверки человеком и обработка неработоспособных сообщений являются частью продукта, а не элементами последующей доработки. Человеческое утверждение требуется для операций, связанных с тратой денег или изменением производственных данных. Настройки во время компиляции не заменяют полноты бизнес-логики.

Часть 4: Управление контекстом — преодоление ограничений памяти

На этапе управления контекстом части 4 необходимо заранее определить входные данные, ответственного за выполнение шага и критерии завершения перед внесением изменений в код. Операторы должны иметь возможность перезапустить шаг, исходя из известной точки контроля, без необходимости угадывать скрытое состояние. Лучше использовать небольшие, тестируемые единицы кода вместо обширных скриптов. При сбое шага причина должна быть связана с конкретной функцией, а не с запутанной структурой обработки данных. Внедрять утверждение человека там, где происходят финансовые операции или изменяются данные в продакшене. Простая настройка на этапе компиляции не гарантирует полноты решения бизнес-задач.

Создание с использованием Deep Agents

На этапе создания с использованием Deep необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Рассматривайте этот этап как контракт между входными данными и проверенными результатами. Дайте названия результатам работы, определите критерии успеха и не допускайте молчаливого частичного завершения задачи. Внедряйте человеческое утверждение для операций, связанных с тратой денег или изменением производственных данных. Компиляционная настройка не заменяет полноту обработки бизнес-задач. На этапе создания с использованием Deep необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, которое операторы могут проверять, не читая весь кодовый граф.

Часть 5: Подагенты — разделяй и властвуй

При работе над этапом использования подагентов в Части 5 сначала запишите контракт: необходимые входные данные, сигнал успеха и действия при частичной неудаче. Такой список поможет сохранять честность при последующих изменениях кода. Задокументируйте одновременно успешный сценарий и сценарий восстановления. Повторные попытки, проверки человеком и обработка неработоспособных сообщений являются частью продукта, а не элементами последующей доработки. Создавайте контрольные точки после дорогостоящих операций. Механизм возобновления работы не должен повторно взимать плату за один и тот же вызов большой языковой модели, когда оператор пытается выполнить последующий узел.

code_searcher = {
    "name": "code-searcher",
    "description": "Searches the codebase to find where specific logic lives. "
                   "Use this for any open-ended 'where is X?' question.",
    # ⚠️ NOTE: the key is `system_prompt`, NOT `prompt` (see correction below).
    "system_prompt": "You are an expert at navigating codebases. Use the grep "
                     "and glob tools to locate relevant files, then report a "
                     "concise summary of what you found and where. Do not make "
                     "any edits.",
}

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[run_tests],
    system_prompt="You are a coding assistant.",
    subagents=[code_searcher],
)

Часть 6: Безопасность и участие человека — тормоза

При работе над разделом 6 «Безопасность» сначала запишите условия контракта: необходимые входные данные, сигнал успешного выполнения и действия при частичной неудаче. Такой чек-лист поможет сохранять честность при последующих изменениях кода. Предпочитайте небольшие, тестируемые модули большим скриптам. Если какой-то шаг не сработает, причина неудачи должна указывать на конкретную ответственность, а не на запутанную цепочку операций. Вносите контрольные точки после дорогостоящих шагов. Система возобновления работы не должна повторно взимать плату за один и тот же вызов LLM, когда оператор пытается выполнить более поздний элемент.

Создание с использованием Deep Agents

При работе над этапом «Создание с помощью Deep» сначала запишите контракт: необходимые входные данные, сигнал о успехе и действия при частичной неудаче. Такой список помогает сохранять честность при последующих изменениях кода. Рассматривайте этот этап как контракт между входными данными и проверенными выходными результатами. Дайте названия элементам, определите критерии успеха и не допускайте безответственного частичного выполнения задач. Выполняйте контрольные точки после дорогостоящих операций. Система возобновления работы не должна снова оплачивать один и тот же вызов большой языковой модели, когда оператор пытается выполнить следующий элемент. При работе над этапом «Создание с помощью Deep» сначала запишите контракт: необходимые входные данные, сигнал о успехе и действия при частичной неудаче. Такой список помогает сохранять честность при последующих изменениях кода. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь кодовый граф.

from deepagents import create_deep_agent
# Import path for backends can vary by version - check the current
# "Backends" page in the Deep Agents docs.
from deepagents.backends import LocalShellBackend

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    system_prompt="You are a coding assistant working inside this project.",
    backend=LocalShellBackend(),   # enables the `execute` shell tool
)
from langgraph.types import Command

result = agent.invoke({"messages": [...]}, config)
result["__interrupt__"]   # the pending action + allowed decisions — show your user

# You decide; the loop picks up exactly where it paused:
agent.invoke(Command(resume={"decisions": [{"type": "approve"}]}), config)
# ... or {"type": "reject"} — the tool is never run, and the model is told so.

Часть 7: Память и сохранение — запоминание между сессиями

Работа с памятью в рамках Части 7 будет наиболее эффективной, если рассматривать её как измеримую структуру. Сначала соберите один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию, прежде чем расширять объём исследования. Документируйте как успешный, так и восстановительный пути работы. Повторные попытки, проверки со стороны оператора и обработка некорректных сообщений являются частью продукта, а не этапом последующей доработки. Сохраняйте структуру графа простой и типизированной. Вложенные структуры данных маскируют информацию о том, какой узел заполнил тот или иной поле, что приводит к нарушению возобновления работы после перерывов.

Создание с использованием Deep Agents

Подход с использованием этапов Deep работает наилучшим образом, когда поверхность рассматривается как что-то измеримое. Соберите один пример успешного выполнения, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объёма работ. Предпочитайте небольшие, тестируемые единицы вместо обширных скриптов. Когда какой-то шаг сбивается, причина сбоя должна указывать на конкретную ответственность, а не на запутанную цепочку операций. Сохраняйте структуру графа простой и типизированной. Вложенные структуры скрывают информацию о том, какой узел заполнил тот или иной поле, и мешают возобновлению работы после прерываний.

from deepagents import create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver

agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",
    tools=[run_tests],
    system_prompt="You are a coding assistant.",
    checkpointer=InMemorySaver(),   # remembers state within a session
)
# A "thread_id" ties messages together into one ongoing conversation.
config = {"configurable": {"thread_id": "project-alpha"}}
agent.invoke(
    {"messages": [{"role": "user", "content": "Start refactoring the auth module."}]},
    config=config,
)
# Later, same thread_id - the agent remembers the earlier turn:
agent.invoke(
    {"messages": [{"role": "user", "content": "Now update the tests too."}]},
    config=config,
)

Собираем всё воедино

Этап объединения всех элементов работает наилучшим образом, когда его рассматривают как измеримую структуру. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объёма работ. Рассматривайте этот этап как контракт между входными данными и проверенными выходными результатами. Дайте названия всем элементам, определите критерии успешного выполнения и не соглашайтесь на молчаливое частичное завершение работы. Сохраняйте структуру графа простой и типизированной. Вложенные структуры скрывают информацию о том, какой узел заполнил тот или иной поле, что приводит к нарушению возобновления работы после перерывов. Этап объединения всех элементов работает наилучшим образом, когда его рассматривают как измеримую структуру. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объёма работ. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь граф.

from deepagents import create_deep_agent
from deepagents.backends import LocalShellBackend
from langchain_core.tools import tool
from langgraph.checkpoint.memory import InMemorySaver

# --- A custom tool (Part 2) — token-budgeted, see Part 2 for the full body ---
@tool
def run_tests(path: str = ".") -> str:
    """Run the project's pytest suite and return its (truncated) output."""
    import subprocess
    try:
        result = subprocess.run(["pytest", path], capture_output=True,
                                text=True, check=False, timeout=300)
    except subprocess.TimeoutExpired:
        return "pytest timed out after 300s"
    output = result.stdout + result.stderr
    return output if len(output) <= 20_000 else "[... truncated ...]\n" + output[-20_000:]

# --- A specialized subagent (Part 5) — note the `system_prompt` key ---
code_searcher = {
    "name": "code-searcher",
    "description": "Finds where specific logic lives in the codebase. "
                   "Use for open-ended 'where is X?' questions.",
    "system_prompt": "You navigate codebases using grep and glob, then report a "
                     "concise summary of what you found. You never make edits.",
}

# --- A system prompt that teaches good behavior (Parts 2 & 3) ---
SYSTEM_PROMPT = """You are a careful coding assistant.
Workflow:
1. Plan the task as a to-do list before doing anything.
2. Use your built-in read, grep, and glob tools to explore - never the raw shell
   equivalents like cat or grep.
3. Make focused edits.
4. ALWAYS run the tests after editing, and fix anything that breaks.
5. Delegate broad codebase searches to the code-searcher subagent.
"""

# --- Assemble the agent (Parts 1, 4, 6, 7 handled by the harness) ---
agent = create_deep_agent(
    model="anthropic:claude-sonnet-4-6",                  # Part 1: the loop, model-agnostic
    tools=[run_tests],                                     # Part 2: custom hands
    system_prompt=SYSTEM_PROMPT,                           # Parts 2 & 3: behavior + planning
    subagents=[code_searcher],                             # Part 5: delegation
    backend=LocalShellBackend(root_dir=".", virtual_mode=False),  # Part 6: shell access
    interrupt_on={"execute": True,                         # Part 6: the brakes —
                  "write_file": True, "edit_file": True},  #   approval before anything destructive
    checkpointer=InMemorySaver(),                          # Part 7: memory across turns
)
# Part 4 (context management) and built-in planning come on automatically.

config = {"configurable": {"thread_id": "my-project"}}
result = agent.invoke(
    {"messages": [{"role": "user", "content": "The login tests are failing. Fix them."}]},
    config=config,
)
print(result["messages"][-1].content)

Честный ответ: что просто, а что сложно

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

Заключение

На этапе завершения необходимо определить входные данные, ответственного за шаг и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Лучше использовать небольшие, тестируемые единицы вместо обширных скриптов. При сбое шага он должен указывать на конкретную причину, а не на запутанную цепочку операций. Внедрять человеческое утверждение для операций, связанных с тратой денег или изменением производственных данных. Подключение на этапе компиляции не гарантирует полноты бизнес-логики.

Чек-лист операций

Этап чек-листа операций работает наилучшим образом, когда рассматривается как измеримая основа. Соберите один эталонный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объёма работ.

Записывайте время выполнения и стоимость токенов или запросов вместе с функциональными результатами. Отслеживание затрат на раннем этапе предотвращает неожиданные расходы при переходе с демо-среды в общедоступные среды.

Сохраняйте состояние графа в виде плоской структуры с указанием типов данных. Вложенные объекты скрывают информацию о том, какой узел записал тот или иной поле, и мешают возобновлению работы после прерываний.

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

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

Сохраняйте состояние графа в виде плоской структуры с указанием типов данных. Вложенные объекты скрывают информацию о том, какой узел записал тот или иной поле, и мешают возобновлению работы после прерываний.

Перед обновлением стека заморозьте версии, сделайте копию критического пути в виде «золотого протокола» и убедитесь, что известны шаги для возврата к предыдущей версии. В совместных средах необходимы ограничения на частоту запросов, проверки принадлежности ресурсов и четко определенный ответственный за обновление секретов. Лучше добиваться простой надежности, чем создавать красивые, но единоразовые демонстрации.

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

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

Деталь усиления безопасности 0/891: измеряйте время выполнения, класс ошибки и расход токенов для этого примечания, затем решайте, следует ли сохранять изменения на основе фиксированного набора вопросов, а не на основе устных замечаний.

При работе над первым этапом записки по укреплению безопасности сначала запишите условия работы: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой чек-лист поможет сохранять честность при последующих изменениях кода. Рядом с функциональными результатами записывайте время выполнения, стоимость токенов или запросов. Очевидность затрат с самого начала предотвращает неожиданные расходы при переходе с демо-среды в общедоступные среды.

Подробности укрепления безопасности 1/891: измерьте время выполнения, класс ошибки и расход токенов для данной записки, затем решите, следует ли сохранять изменение на основе определенного набора критериев, а не на основе устных замечаний.

Второй этап записки по укреплению безопасности работает лучше всего, когда его рассматривают как измеримую область. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объема работ. Документируйте как успешный путь выполнения, так и путь восстановления. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не элементами последующей доработки.

Подробности усиления безопасности 2/891: измерьте время работы на стенде, класс ошибки и количество использованных токенов для этой записи, затем решите, следует ли сохранять изменения на основе фиксированного набора вопросов, а не на основе единичных примеров.