Главная / Статьи / Практические замечания: Создание квалифицированных агентов

Практические замечания: Создание квалифицированных агентов

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

2943 слов

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

Что же на самом деле такое навык?

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

Аналогия

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

В коде

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

skills/
└── weather-skill/
    ├── SKILL.md          # frontmatter + instructions
---
name: weather-skill
description: Get current weather for a location. Use when the user
  asks about weather, temperature, or conditions anywhere.
---

# Get weather skill

.... {other instructions here}

Давайте создадим систему управления освещением

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

from dotenv import find_dotenv, load_dotenv

from langchain.agents import create_agent
from langchain.tools import tool
from langchain_openai import ChatOpenAI

_ = load_dotenv(find_dotenv())

llm = ChatOpenAI(
    model="gpt-5.6-luna",
    use_responses_api=True,
    reasoning={"effort": "low"},  #The reasoning is medium by default so set this to l
)

@tool
def get_weather(location: str) -> str:
    """
    Get the weather for a given location
    """
    return f"The weather in {location} is sunny"

@tool
def get_exchange_rate(currency_from: str, currency_to: str) -> str:
    """
    Get the exchange rate between two currencies
    """
    return f"The exchange rate for {currency_from} to {currency_to} is 1.00"

Использование навыков для руководства использованием инструментов

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

skills/
└── weather-skill/
    ├── SKILL.md
└── forex-skill/
    ├── SKILL.md
---
name: forex-skill
description: Get live exchange rates between two currencies. Use this whenever the user asks about currency conversion, exchange rates, how much something costs in another currency, or comparisons like "is the dollar strong right now" — even if they don't use the words "forex" or "exchange rate" explicitly (e.g. "how much is 500 SGD in yen", "should I exchange money now or wait"). Always use this instead of guessing from memory, since exchange rates move constantly and Claude's training data has no visibility into current rates.
---

# Forex Skill

Fetches the live exchange rate between two currencies and reports it back in a clear, practical format.

## Instructions

1. **Identify both currencies.** Convert casual references to standard 3-letter ISO codes before calling the tool (e.g. "dollars" → ask which dollar: USD, SGD, AUD, etc.; "yen" → JPY; "pounds" → GBP).
2. **Handle ambiguous currency names.** If the user says something like "dollars" or "pounds" without specifying which country, ask them to clarify before calling the tool — don't assume USD/GBP by default.
3. **Call the `get_exchange_rate` tool**, passing both currency codes:

   ```python
   get_exchange_rate(currency_from="<code>", currency_to="<code>")
   ```

4. **If the tool call fails or returns an error**, tell the user plainly that the rate lookup failed — don't fall back to guessing a rate from memory.
5. **Call once per currency pair.** For multi-currency questions (e.g. "compare SGD to USD, EUR, and JPY"), call the tool separately for each pair.
6. **Do the math for the user.** If they gave an amount ("convert 500 SGD to JPY"), multiply it out yourself using the returned rate — don't just hand back the raw rate and leave them to calculate it.

## Output format

...

## Examples

...

Эксперимент 1: Навыки в файлах

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

from deepagents.backends import FilesystemBackend
from deepagents.middleware import FilesystemMiddleware, SkillsMiddleware

backend = FilesystemBackend(root_dir="../", virtual_mode=True)

agent = create_agent(
    model=llm,
    tools=[get_weather, get_exchange_rate],
    middleware=[
        SkillsMiddleware(backend=backend, sources=["./skills/"]),
        FilesystemMiddleware(
            backend=backend,
            tools=["read_file"],   # read_file and nothing else
            system_prompt=None,
        ),
    ],
)

Попробуйте сами

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

>>> agent.invoke({"messages": [HumanMessage("What is the weather in Singapore?")]})

Singapore is currently **sunny**. It's a good time for outdoor plans.

Эксперимент 2: Удалённые навыки

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

from urllib.request import urlopen
from deepagents.backends import StateBackend
from deepagents.backends.utils import create_file_data

backend = StateBackend()

skill_url = "https://raw.githubusercontent.com/.../langgraph-docs/SKILL.md"
with urlopen(skill_url) as response:
    skill_content = response.read().decode('utf-8')

skills_files = {
    "/skills/langgraph-docs/SKILL.md": create_file_data(skill_content),
}

agent = create_agent(
    model= llm
    middleware=[
       SkillsMiddleware(
          backend=backend,
          sources=["./skills/"]
       ),
       FilesystemMiddleware(backend=backend)
    ]
)

result = agent.invoke(
    {
        "messages": [{"role": "user", "content": "What is langgraph?"}],

        # seeded into the in-state filesystem. needed for the first run
        "files": skills_files,
    },
)

Эксперимент 3: Нулевое количество инструментов

Этап инструментов Experiment 3 Zero работает наилучшим образом, когда его рассматривают как измеримую среду. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объёма работ. Предпочитайте небольшие, тестируемые единицы вместо обширных скриптов. Когда какой-либо шаг срабатывает некорректно, причина сбоя должна указывать на конкретный элемент ответственности, а не на запутанную цепочку операций. Используйте инструменты с узкими схемами и чёткими метками побочных эффектов. У хостов должна быть возможность узнать, какие вызовы изменяют состояние, прежде чем они автоматически одобрят действия. Этап инструментов Experiment 3 Zero работает наилучшим образом, когда его рассматривают как измеримую среду. Соберите один идеальный пример работы, один случай сбоя и записку о возврате к предыдущему состоянию перед расширением объёма работ. Записывайте временные показатели, а также стоимость токенов или запросов рядом с функциональными результатами. Отображение стоимости на раннем этапе предотвращает неожиданные расходы при переходе с демо-среды в общедоступные среды.

---
name: weather-skill
description: Get current weather for a location. Use when the user asks
  about weather, temperature, or conditions anywhere.
---

# Get weather skill

To get the weather of a location, run:

```bash
python skills/weather-skill/scripts/get_weather.py "<location>"
```

Returns JSON with weather condition. Parse and present naturally.

Run this script on each location the user asked for, one at a time.
#skills/weather-skill/get_weather.py
def main():
    location = sys.argv[1] if len(sys.argv) > 1 else None
    if not location:
        print(json.dumps({"error": "location argument required"}))
        sys.exit(1)
    print(json.dumps({"location": location, "weather": "sunny"}))

if __name__ == “__main__”:
    main()
from deepagents.backend import LocalShellBackend

backend = LocalShellBackend(
    root_dir=str(Path.cwd()),
    virtual_mode=False,
    inherit_env=True,
)

middleware = [
    FilesystemMiddleware(
        backend=backend,
        tools=["read_file", "ls", "glob", "execute"],
        system_prompt=None,
    ),
    SkillsMiddleware(backend=backend, sources=["./skills/"]),
]

agent = create_agent(model=llm, middleware=middleware)   # no tools=

Подождите. Оно действительно запустилось?

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

Today's weather:
**Sydney:** Sunny
- **Melbourne:** Sunny

Решение — логирование, но не в stdout.

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

from pathlib import Path
import logging

LOG = Path(__file__).resolve().parent.parent / "skill.log"
logging.basicConfig(
    filename=LOG, level=logging.INFO,
    format="%(asctime)s [pid=%(process)d] %(message)s",
)
logging.info("invoked argv=%r cwd=%s", sys.argv, os.getcwd())
22:29:55,316 [pid=45724] invoked argv=[...get_weather.py, 'Sydney']    cwd=.../notebooks
22:29:55,316 [pid=45724] resolved location=Sydney
22:29:56,795 [pid=45725] invoked argv=[...get_weather.py, 'Melbourne'] cwd=.../notebooks
22:29:56,795 [pid=45725] resolved location=Melbourne

Ошибка, которая объяснила всю архитектуру

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

.

Что такое virtual_mode?

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

Непреднамеренный аргумент в пользу всей конструкции

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

Такой вариант, какой же стоит выбрать?

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

Но действительно ли вам нужны специальные навыки?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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