Галоўная / Артыкулы / Практычныя прытамулі: Агентныя цыклы і шаблоны дзеяння

Практычныя прытамулі: Агентныя цыклы і шаблоны дзеяння

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

1942 слоў

Наступныя прытамлівкі паказваюць практычны шлях разбору тэмы «Агентныя ціклы і шаблоны дизайна». Акцэнт ставіцца на кантракты, пераконтроўваннія і месца для коду, які можна легка адразу вставіць, а не на мотывацыйныя аспекты. Калі працуеце на стадзіі агледжэння, спачатку запісайце кантракт: неабяжныя вхідныя даны, сігнал успеху і тое, што выканаецца у разы частковага невялікога браку. Такі чарт дапамагае залишыцца адкрытым пад час пазнейшых змян у кодзе. Запісвайце час выканання і вартасць токеноў або запытак пад функцыйнальнымі рэзултатамі. Відразувыя даны пра вартасці запобегаюць неспакоўным рахункам, калі процес пераходзіць з дэмаверсіі ў спяльныя среды.

1. Цікл планавання–дзеяння–пераконтроўвання

Этап пераканальцавання акта плану 1 працюе наяўней, калі яго спрыяваць як вимерную паверхню. Зафіксавайце адна ідеальная транскрыпцыя, адзін прыклад неудачы і запіс пра вярнэнне да поперадньага стану пры розшырэнні масштаба. Зберагайце настройкі пазырочна ад коду прыемліка. Файлы сераўнавальнага сяродовішча, хранілішчы секрэтных данных і флагі функцый должны знаходзіцца ў аднам месцы, куда аператары можуць аудытаваць іх без неабяжнага чытання всіх дадзеных. Зберагайце стан графа ў простам і типаваным формате. Вкладныя блокі маскуюць інфармацыю пра тое, який вузел запісаў які поле, і спакоююць продажчэй работу пасля перерываў.

// Pseudo-code: Node/TypeScript orchestrating Claude as an agent

async function planActVerifyLoop(ticket) {
  let iteration = 0;
  const maxIterations = 5;

  while (iteration < maxIterations) {
    iteration++;

    // 1. PLAN: ask Claude for the next step
    const plan = await claude.chat({
      model: "claude-3-opus",
      messages: [
        {
          role: "user",
          content: `You are a coding agent working on ticket ${ticket.id}.
Goal: Make tests pass for this ticket without changing public APIs.

Current context:
${ticket.description}
${ticket.latestFailureLog}

What is the single most useful next action?`
        }
      ]
    });

    // 2. ACT: execute the suggested action if it's in the allowed action space
    const action = parseAction(plan);
    const result = await executeAction(action); // run tests, edit file, etc.

    // 3. VERIFY: use tests as verification
    const verification = await runTests(ticket.testSuite);

    if (verification.allPassing) {
      return { status: "done", iterations: iteration };
    }

    // Attach the failure output back into ticket context
    ticket.latestFailureLog = verification.failureOutput;
  }

  return { status: "budget_exhausted" };
}

Цыкл ReAct (Прычына + Дзеянне)

Этап «Разумнае дзеянне» цыклу ReAct працюе наўзяй калі яго розглядаць як вимерную паверхню. Зафіксавайце адна ідеальная транскрыпцыю, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Дакументавайце як шлях успеху, так і шлях вярнэння. Перапрыбуткі, людзкія контрольныя пункты і обработка некоректных паведамленняў є частью продукту, а не наступным этапам дорабкі. Храніце стан графа у простаму і типаванаму формате. Вкладзеныя блокі маскуюць інфармацыю пра тое, який вузел запісаў канкрэтны поле, і спакоююць працу пасля перарываў.

# Pseudo-code: Python coordinator orchestrating Claude tool calls

def react_loop(incident):
    iteration = 0
    max_iterations = 6

    while iteration < max_iterations:
        iteration += 1

        # REASON: Claude decides what to inspect next
        reasoning = claude.chat(
            model="claude-3-opus",
            messages=[
                {
                    "role": "user",
                    "content": f"""
You are an SRE assistant triaging a payment incident.

Incident summary:
{incident.summary}

Recent metrics:
{incident.latest_metrics}

Logs snippet:
{incident.logs_snippet}

Decide one next diagnostic action from:
- CHECK_METRICS
- CHECK_LOGS
- CHECK_DB_HEALTH
- SUMMARIZE_FINDINGS_AND_RECOMMEND_ACTION

Explain your reasoning briefly and output JSON with 'action' and 'target'.
"""
                }
            ]
        )

        action = parse_json(reasoning)
        if action["action"] == "SUMMARIZE_FINDINGS_AND_RECOMMEND_ACTION":
            return claude.chat(... )  # final summary + recommended steps

        # ACT: run the selected diagnostic
        observation = run_diagnostic(action, incident)

        # Update incident state for the next reasoning step
        incident.update_with_observation(observation)

3. Цыкл «Размышленне–Перасмотраць»

Этап цыклу «3 Reflect Revise» працюе найэфектывней, калі яго спрыяваць як меравальную плошчу. Зберагачыце адны ідеальны прыклад роботы, адзін кейс неудачы і прыметкі па адвярненню перад расшырэнням масштаба. Валіце маленькія, тэставаныя элементы замест большых скрыптов. Калі якісь крок не выйшае, прычына неудачы павінна вказываць на адную адпаведальнасць, а не на заплутаны ланцюг задач. Рэгулюйце стан графа, ўтримваючы яго у простай форме з чыста вказанымі типамі дадзеных. Вярнутыя структуры дадзеных маскуюць інфармацыю пра тое, каней вузел запісаў канкрэтны поле, і спакойваюць працу пасля перарываў. Этап цыклу «3 Reflect Revise» працюе найэфектывней, калі яго спрыяваць як меравальную плошчу. Зберагачыце адны ідеальны прыклад роботы, адзін кейс неудачы і прыметкі па адвярненню перад расшырэнням масштаба. Запісвайце часы виконання і косты токеноў або запытак праза функцыйнае рэзультат. Відкрытая інфармацыя пра косты запобегае неспакойным расчыткам, калі процес пераходзіць з дэмаверсіі ў спяльныя среды.

async function reflectReviseLoop(draftInput: string) {
  // 1. GENERATE
  const draft = await claude.chat({
    model: "claude-3-opus",
    messages: [
      {
        role: "user",
        content: `
Write a customer-facing email explaining a declined payment due to suspected fraud.
Constraints:
- empathetic but clear
- no admission of fault
- no promises about future approvals

Context:
${draftInput}
`
      }
    ]
  });

  // 2. CRITIQUE (using a cheaper model as checker)
  const critique = await claude.chat({
    model: "claude-3-haiku",
    messages: [
      {
        role: "user",
        content: `
You are a compliance checker.

Review the following email for:
- policy violations
- misleading statements
- over-commitments

Output a JSON with:
- issues: list of strings
- safe: boolean

Email:
${draft.content}
`
      }
    ]
  });

  const review = JSON.parse(critique.content);

  if (review.safe) {
    return draft.content;
  }

  // 3. REVISE
  const revised = await claude.chat({
    model: "claude-3-opus",
    messages: [
      {
        role: "user",
        content: `
You wrote this email:
${draft.content}

Compliance issues:
${review.issues.join("\n")}

Rewrite the email to resolve all issues while preserving intent.
`
      }
    ]
  });

  return revised.content;
}

Цыкл «Праект–Тэст–Выправленне»

Для стадіі цыклу «Draft Test Fix» неабяжна ўзначыць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння пры змены коду. Аперацыйныя працавнікі павінны магчымае перазапускаць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Конфігурацыю трэба залічыць паза кодам прыкладнення. Файлы сераўіса, хранільнікі секрэтных данных і флагі функцыйяў павінны знаходзіцца ў адном месцы, якое працавнікі можуць пераглядаць, не чытаючы весь структураны код. Прызначыць людскія апраўдкі для тых вароў, якія выкарыстоўваюць грошы або зміняюць даны ў працоўным режыме. Підключэння пад час компіляцыі не ўзначае повнасці бізнес-функцыйяў.

async function draftTestFixLoop(issue: Issue) {
  const maxIterations = 4;
  let iteration = 0;

  while (iteration < maxIterations) {
    iteration++;

    // DRAFT: Claude proposes code changes
    const patch = await claude.chat({
      model: "claude-3-opus",
      messages: [
        {
          role: "user",
          content: `
You are an autonomous coding agent.

Ticket:
${issue.title}
${issue.body}

Current failing tests:
${issue.failingTests}

Propose a minimal patch as a diff that makes tests pass
without changing public APIs.`
        }
      ]
    });

    applyPatchToGitRepo(patch.content);

    // TEST: run CI locally or via API
    const testResult = await runCi(issue.branchName);

    if (testResult.success) {
      // FIX_DONE: open a PR with the diff
      await openPullRequest(issue, patch.content);
      return { status: "done" };
    }

    // FEEDBACK: update failingTests for next iteration
    issue.failingTests = testResult.failureSummary;
  }

  return { status: "needs_human_review" };
}

Цыкл Крітыка–Стваральніка (творцы–пераканалювачы)

Для стадіі перагледу прыстрою Critic Builder неабяжна прадзефінаваць вхідныя даны, адпраўніка крока і крэтыры завершэння перад змянай коду. Аперацыяныя працавнікі павінны магчымае перапрацаваць крок з вядомай точкі контролю, не падозрываючы схованы стан. Неабяжна задокументаваць як шлях успеху, так і шлях вярнення да нормальнага стану. Перапрыбуткі, людзкія перагледы і обробка некоректных паведамленняў є часткай продукту, а не яго пазнейшай дапрацоўкі. Пры кроках, які выкалічваюць грошы або зменяюць даны праўлення, неабяжна выкарыстоўваць людзкія затверджэння. Працэс складання коду не є адпаведнікам повнай бізнес-готовасці.

Цыкл перапрыбуткаў з запам’ятованнем

Для стадіі цыклу «Прабава з памяцю» неабходна перад змінайом коду адзначэнне вхідных дадзеных, адпаведальнага за крок і крэтарыў выходу. Аператары должны магчымае перайсці на выкананне кроку з вядомага пункта контролю, не спрабоўваючы здагадвацца пра схованы стан. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выканаецца, прычына неудачы должна вказываць на адзін конкрэтны элемент, а не на заплутаны ланцужок задач. Неабходна людская апраўда для тых крокаў, якія выкарыстоўваюць грошы або зменяюць данні ў працэсе. Компіляцыйныя налашчанні не ўзроўнаўцуюцься з пачатковым станом бізнес-процэсаў. Для стадіі цыклу «Прабава з памяцю» неабходна перад змінайом коду адзначэнне вхідных дадзеных, адпаведальнага за крок і крэтарыў выходу. Аператары должны магчымае перайсці на выкананне кроку з вядомага пункта контролю, не спрабоўваючы здагадвацца пра схованы стан. Рэгіструйце час выканання, а таксу токенаў аб запытоў разам з функцыйнальнымі рэзультатамі. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі процес пераходзіць з дэмовай среды ў спяльную.

.

def retry_with_memory_loop(task, max_attempts=3):
    failures = []

    for attempt in range(1, max_attempts + 1):
        # Ask Claude to consider past failures before deciding the next move
        decision = claude.chat(
            model="claude-3-opus",
            messages=[
                {
                    "role": "user",
                    "content": f"""
You are handling a task with a flaky external API.

Task:
{task.description}

Past failures:
{failures}

Decide whether to:
- RETRY_API
- FALLBACK_TO_CACHE
- ESCALATE_TO_HUMAN

Explain briefly and output JSON: {{ "choice": "...", "reason": "..." }}
"""
                }
            ]
        )

        choice = parse_json(decision)

        if choice["choice"] == "RETRY_API":
            result = call_api(task)
        elif choice["choice"] == "FALLBACK_TO_CACHE":
            result = use_cache(task)
        else:
            return {"status": "escalated", "failures": failures}

        if result.success:
            return {"status": "success", "attempts": attempt}

        failures.append(result.error_summary)

    return {"status": "max_attempts_exhausted", "failures": failures}

Эскаліяцыя з участю чалавека

Калі працуеце на стадзіі эскаліяцыі з участю чалавека, спачатку запісайце умовы контракту: неабяжлівыя даны, сигнал успеху і тое, што выканаецца у разы частковага нявыполнення. Такі список пераканальвае ў тым, каб пазнейшыя змены коду былі чыстымі. Зберагаюце настройкі паза кодам прыемліка. Файлы сераўнавання, хранільнікі секрэтных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаюць адбавіць аудыт без неабяжлівага чытання всей структуры. Ставяйце контрольныя пункты пасля дорогіх крокаў. Програма не должна занова ставіць плата за той самы вызов LLM, калі аператар перапрыяўляе роботу да наступнага элемента.

async function triageLoop(ticket: Ticket) {
  const autoActions = ["LABEL", "ROUTE_TO_QUEUE", "REQUEST_MORE_INFO"];

  const decision = await claude.chat({
    model: "claude-3-opus",
    messages: [
      {
        role: "user",
        content: `
You are a support triage agent in a payments company.

Ticket:
${ticket.body}

Decide one of:
- LABEL (low risk)
- ROUTE_TO_QUEUE (medium risk)
- ESCALATE_TO_HUMAN (high risk / unclear)

Return JSON with:
- choice
- risk_level
- rationale
`
      }
    ]
  });

  const choice = JSON.parse(decision.content);

  if (choice.choice === "ESCALATE_TO_HUMAN") {
    await createHumanTask(ticket, choice.rationale);
    return { status: "escalated" };
  }

  // LABEL or ROUTE_TO_QUEUE are automated but bounded
  await applyAutomatedTriage(ticket, choice);
  return { status: "auto_treated" };
}

Як выбіраць шаблоны на практыцы

Калі працюеце над этапам «Як выбраць шаблон», спачатку запісайце угоду: неабяжлівыя даны, сигнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список пераконтроўкаў дапамагае заліцвачваць пазнейшыя змены ў кодзе. Документавайце як шлях успеху, так і шлях вяснавання. Перапрыбуткі, людзкія контралі і обработка некоректных паведамленняў ёсць часткай продукту, а не пазнейшым дапрацоўкам. Зробіце пераконтроль пасля дорогіх крокаў. Система вярнення не павинна знову ставіць плату за той самы вызов LLM, калі аператар перапрыбуе пазнейшы вузел.

Чек-ліст для эксплуатацыі

Для этапу чек-ліста для эксплуатацыі, перш чым зменяць код, задаце даны, адпаведальнага за крок і критэрыя завершэння. Аператары павінны магчымаць перзапуск кроку з вядомага пункта пераконтроўкаў, не здогадваючыся пра схованы стан.

Спрыяйце цэму этапу як угодзе між вхіднымі данымі і перакананымі выходнымі рэзультатамі. Назвайце артыфакты, задаце пераконтроўкі успеху і адмовіцеся ад тыхнай частковай завершэння без паведамлення.

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

Напісце кароткі посібнік: як роцыяваць кантрольныя клучы, як спрачыслаць чергу, як анулюваць пярэдніе змены.

Зазначайце час выканання аперацый, а таксу токенаў чы запытаў праза функцыйнае рэзультат. Відкрытая інформацыя пра вартасці запобегае неспакою, калі працэс пераходзіць з дамовай версіі ў спакульнаныя сераўсы.

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

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

Запіскі для пакета 54c3b06154e6: не класты ключі прадаўцоў у репазітарыю, задаць максымальны тэрмін дзейнасці токена на кожную сесію, а таксама зберагчы транскрыпціі празаўсюды з фікстурамі для ацэнкі, каб пазнейшыя замены моделей заставаліся порównанымі.