← Artifacts / artifacts / concepts
Рекомендации по использованию Artifacts
Artifacts работает наиболее эффективно, когда вы изолируете задачи, ограничиваете доступ узкими рамками, храните метаданные отдельно и осознанно разделяете хранилище.
Используйте эти шаблоны, чтобы структурировать репозитории для агентов, автоматизации и общих систем.
Организуйте репозитории для изоляции
Создание репозитория для каждого агента, сессии или приложения
Создавайте отдельный репозиторий для каждой автономной единицы работы. Если у вас есть 10,000 агентов, создайте 10,000 репозиториев.
Это разделяет изменения, сбои и жизненный цикл очистки каждого агента. Это также не дает одному общему репозиторию превратиться в точку конфликтов, больших diff и случайных перезаписей.
Используйте этот шаблон, если вам нужно:
- изолировать работу одного агента от работы другого агента
- передать репозиторий отдельной сессии или пользовательскому приложению
- проверять, объединять, архивировать или удалять работу независимо друг от друга
Используйте ветки только тогда, когда участники работают в рамках одного жизненного цикла и должны работать с одним и тем же репозиторием. Не используйте один общий репозиторий как очередь для множества автономных агентов.
Используйте уникальные имена
Имена репозиториев уникальны в пределах пространства имён. Если нескольким агентам нужны изолированные копии одного базового репозитория в одном пространстве имён, не используйте повторно короткое общее имя, например docs-site.
Включайте в имя репозитория стабильные идентификаторы, такие как имя агента, ID сессии, ID пользователя или ID workflow. Имя вида ${agentName}-${sessionId}-${repoName} безопаснее, чем ${repoName} так как это позволяет избежать коллизий и упрощает очистку.
В этом примере перед созданием репозитория генерируется уникальное имя.
async function createRepoCopy(env, agentName, sessionId, repoName) {
const uniqueRepoName = `${agentName}-${sessionId}-${repoName}`;
return env.ARTIFACTS.create(uniqueRepoName);
}interface Env {
ARTIFACTS: Artifacts;
}
async function createRepoCopy(
env: Env,
agentName: string,
sessionId: string,
repoName: string,
) {
const uniqueRepoName = `${agentName}-${sessionId}-${repoName}`;
return env.ARTIFACTS.create(uniqueRepoName);
}Создать форк от стабильного базового репозитория
Создавайте новые репозитории на основе проверенной базовой версии, если агентам нужны одинаковые стартовые файлы, промпты или структура приложения. Форк проверенного репозитория безопаснее, чем вручную копировать файлы в каждый новый репозиторий.
Это делает начальную точку неизменной и облегчает проверку последующих diff. Это также позволяет слить обратно только нужные результаты.
В этом примере проверенный базовый репозиторий форкается в репозиторий, привязанный к сессии.
async function forkFromBaseline(env, sessionId) {
const baseline = await env.ARTIFACTS.get("starter-repo");
const forked = await baseline.fork(`starter-repo-${sessionId}`, {
description: `Fork for session ${sessionId}`,
defaultBranchOnly: true,
readOnly: false,
});
return {
name: forked.name,
remote: forked.remote,
};
}interface Env {
ARTIFACTS: Artifacts;
}
async function forkFromBaseline(env: Env, sessionId: string) {
const baseline = await env.ARTIFACTS.get("starter-repo");
const forked = await baseline.fork(`starter-repo-${sessionId}`, {
description: `Fork for session ${sessionId}`,
defaultBranchOnly: true,
readOnly: false,
});
return {
name: forked.name,
remote: forked.remote,
};
}Ограничивайте область доступа
Создавайте токены репозиториев с минимальными привилегиями
Токены Artifacts привязаны к конкретному репозиторию. Предпочтительно используйте read токены для клонирования, индексирования, проверки и получения.
Используйте write токены только для агента или системы, которым нужно отправлять изменения. Выдавайте токены с коротким сроком действия и выпускайте новый токен для каждой сессии агента.
В этом примере используется привязка Workers чтобы выпустить кратковременный токен на чтение для репозитория.
Считайте, что вызывающая сторона уже прошла аутентификацию и авторизацию до того, как этот маршрут вернёт токен.
export default {
async fetch(request, env) {
const url = new URL(request.url);
const repoName = url.searchParams.get("repo") ?? "starter-repo";
const repo = await env.ARTIFACTS.get(repoName);
const token = await repo.createToken("read", 900);
return Response.json({
repo: repoName,
scope: token.scope,
expiresAt: token.expiresAt,
token: token.plaintext,
});
},
};interface Env {
ARTIFACTS: Artifacts;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
const repoName = url.searchParams.get("repo") ?? "starter-repo";
const repo = await env.ARTIFACTS.get(repoName);
const token = await repo.createToken("read", 900);
return Response.json({
repo: repoName,
scope: token.scope,
expiresAt: token.expiresAt,
token: token.plaintext,
});
},
} satisfies ExportedHandler<Env>;Используйте тот же паттерн для write токены только после того, как ваш Worker авторизует сессию, которой нужно отправлять изменения.
Не выдавайте один долгоживущий токен на запись каждому агенту. Выпускайте токен с максимально узкой областью действия и на максимально короткий срок.
Храните метаданные harness отдельно
Используйте git notes для запросов и вывода модели
Используйте git notes ↗ чтобы прикреплять к commit промпты, вывод модели, run ID и другие метаданные harness, не изменяя сам объект commit или рабочее дерево.
Это позволяет использовать Artifacts одновременно как версионированную файловую систему для работы агента и как источник достоверных данных для вашего agent harness. Файлы остаются посвящены самому результату работы, а заметки коммитов хранят контекст выполнения.
В этом примере запрос пользователя и сводка ассистента сохраняются в текущем коммите, после чего заметка считывается обратно.
git notes add -m 'user: Add a best-practices section for unique repo names.' HEAD
git notes append -m 'assistant: Added naming guidance and a code example.' HEAD
git notes show HEADПри синхронизации репозиториев между системами учитывайте, что заметки хранятся в отдельных ссылках. Выполняйте push и fetch refs/notes/* вместе с остальными данными репозитория, когда нужно, чтобы эти метаданные передавались вместе с репозиторием.
Разделяйте пространства имён осознанно
Разделяйте окружения, команды и высоконагруженные рабочие нагрузки
Используйте пространства имен для разделения операционных границ. Разделение репозиториев изолирует единицы работы, а разделение пространств имен изолирует владение, окружения и характер трафика.
Не держите все репозитории в одном пространстве имён по умолчанию по мере роста использования. Разделяйте пространства имён, когда вам нужно более чёткое разграничение владения или больше запаса для масштабирования в рамках ограничения частоты запросов для каждого пространства имён.
| Сценарий использования | Примеры пространств имён | Почему |
|---|---|---|
| Окружения | staging, prod |
Разделяйте тестовый трафик и трафик продакшена. |
| Границы команд | sales, finance, devtools |
Разделяйте политики владения, доступа и очистки. |
| Изоляция трафика | agents-batch, agents-realtime |
Не позволяйте одной рабочей нагрузке исчерпывать лимиты другой рабочей нагрузки. |
Когда одно пространство имён начинает испытывать повышенную нагрузку, распределяйте новые репозитории по дополнительным пространствам имён, а не продолжайте расширять единое общее пространство имён.