Dokümanlar menüsü
İnsan-onaylı araçlar (guard)
Bir Guard fonksiyonu riskli araç çağrılarını askıya alır (interrupt döner); operatör onayı geldikten sonra approvals ile resume edilir — para/aksiyon öncesi kapı.
Ne işe yarar / ne zaman kullanılır#
Bir agent para tahsil etmek, e‑posta göndermek veya kayıt silmek gibi geri alınamaz bir araç çağırdığında, çağrı ÇALIŞMADAN ÖNCE bir insanın onayını beklemek istersiniz. Guard , her tool çağrısından önce (exactly-once kontrolünden sonra) devreye giren genel bir politika kancasıdır: LLM'in hangi tool'ları gördüğünü kısıtlamaz, yalnızca yan etkiyi kapıya alır.
Guard require-approval döndürdüğünde gerçek tool ÇALIŞMAZ; bunun yerine bir Interrupt journal'a suspended olarak yazılır ve run durur. Operatör onayı verdikten sonra aynı runId ile resumeRun çağrılır — prompt'u yeniden vermeye gerek yoktur, girdi journal'dan okunur.
Kurulum / import#
import { runDurable, resumeRun } from '@gnldev/durable';
import type { Guard, GuardCall, GuardDecision, Interrupt } from '@gnldev/durable';Ekstra bir alt-paket gerekmez — Guard tipi ve resumeRun çekirdek @gnldev/durable export'larıdır. Journal adaptörünü (ör. @gnldev/durable/sqlite) ihtiyacınıza göre ayrıca içe aktarın.
Adım adım kullanım#
1) Bir Guard tanımlayın — tool adı ve argümanlara bakıp allow / deny / require-approval döner:
const guard: Guard = ({ toolName, args }) =>
toolName === 'chargeCard' && (args as any).amount > 1000
? { action: 'require-approval' }
: { action: 'allow' };2) runDurable'a guard'ı verin. Riskli çağrı askıya alınırsa gerçek tool hiç çalışmaz, dönen sonuçta interrupts dolu gelir:
const r1 = await runDurable({
runId: 'o1',
journal,
model: makeModel(),
tools: makeTools(counter),
guard,
prompt: 'charge 5000',
stopWhen: stepCountIs(6),
});
// counter.charges === 0 → the tool did NOT run
// r1.interrupts.length === 1 → one call is awaiting approval
console.log(r1.interrupts[0]);
// { toolCallId: 'call-c', toolName: 'chargeCard', args: { amount: 5000 }, reason: undefined }3) Operatör onayı verdikten sonra AYNI runId ile resumeRun çağırın — prompt tekrar verilmez, girdi journal'dan okunur. approvals objesinde askıdaki toolCallId'yi trueişaretleyin:
const r2 = await resumeRun('o1', {
journal,
model: makeModel(),
tools: makeTools(counter),
guard,
approvals: { 'call-c': true },
stopWhen: stepCountIs(6),
});
// counter.charges === 1 → the tool has now actually run
// r2.text.includes('Done') → the run completedAPI referansı#
Guard(call: GuardCall) => GuardDecision | Promise<GuardDecision> — her tool çağrısından önce çalışan genel politika kancası.
GuardCall{ toolName, args, toolCallId, runId } — Guard fonksiyonuna geçilen çağrı bağlamı.
GuardDecision{ action: 'allow' } | { action: 'deny'; reason? } | { action: 'require-approval'; reason? } — kararın gövdesi.
Interrupt{ toolCallId, toolName, args, reason? } — require-approval ile askıya alınmış, insan onayı bekleyen bir tool çağrısı.
SuspendSentinel{ __gnl_suspend: Interrupt } — tool execute yerine dönen suspend sinyali; loop bunu görünce stopWhen ile durur.
resumeRun(runId, { journal, model, tools, guard?, approvals?, stopWhen?, replay? }) => Promise<DurableResult> — girdiyi journal'dan okuyup runDurable'ı tekrar çağırır.
approvals['call-c'] değeri false verilirse çağrı kalıcı denied olarak journal'lanır; model bu sonucu görüp kendini düzeltebilir. Onay hiç verilmezse (alan yok) çağrı suspended kalır — resume tekrar askıya döner, sonsuz döngüye girmez.toolCallId için succeeded/denied kaydı varsa Guard tekrar sorulmaz, journal'dan aynı sonuç döner — resume çift çalıştırmaz.