GNL
Dokümanlar menüsü
Core · Ücretsiz@gnldev/durable

Güvenli-varsayılan duplicate guard

Yan-etkili bir araç, aynı çalıştırmadaki daha önceki başarılı bir çağrıyla ÖZDEŞ argümanlarla YENİDEN çalışmak üzereyken merdiven (off → warn → reflect → block → suspend) devreye girer — modeli yeniden düşünmeye yönlendirir ya da tekrarı doğrudan durdurur.

Ne işe yarar / ne zaman kullanılır#

Kafası karışmış bir model, aynı yan-etkili aracı ÖZDEŞ argümanlarla iki kez çağırabilir — çift tahsilat, çift e-posta, mükerrer sevkiyat. Duplicate guard varsayılan olarak açıktır: bir yan-etki aracının (charge, sendEmail, …) aynı runId içindeki daha önceki başarılı bir çağrıyla özdeş argümanlarla yeniden yürümek üzere olduğunu tespit eder ve yapılandırılan cevabı uygular. Çalıştırma-içi, çalıştırma-başına bir korumadır (ayrı çalıştırmalar ARASINDA dedup YAPMAZ — onun için cross-run idempotency kullanın).

Merdiven#

Cevabı limits.sideEffectDuplicates ile belirlersiniz (varsayılan warn). Seviyeler sertlik bakımından yükselir:

const'off'

Tespit yok — tekrar yürür.

const'warn'

Eskisi gibi yürür ama her oluşumda adlandırılmış, journal'lanan bir incident yazar (benimseme rampası — asla sessiz bir tekrar değil).

const'reflect'

Çalıştırmayı DURDURMAZ: modele journal'lanan TEK bir 'yeniden düşün' nudge'ı iletir ('reflected' durumlu kayıt); nudge'dan SONRAKİ özdeş tekrar block'a yükseltilir.

const'block'

Tekrarı DuplicateSideEffectError ile durdurur — bloklanan çağrı için hiçbir şey yazılmaz.

const'suspend'

Askıya alınmış bir kayıt yazar → tekrar Approvals akışına düşer (kararı bir insan verir).

Hangi tekrar hangi katmana takılır#

Tekrar tek çeşit değildir ve tek bir katman hepsini göremez. İki eksen belirler: tekrarı KİM üretti (kafası karışan model mi, aynı işi yeniden isteyen kullanıcı mı) ve tekrar AYNI konuşmada mı geldi. Dört hücrenin üçünü GNL bugün kapatıyor; dördüncüsü bilinçle açık bırakılmış bir boşluk ve burada öyle yazıyor:

constexact-hash / marker

Model tekrarı, BİREBİR aynı argümanlar, aynı çalıştırma ya da aynı konuşma → bu sayfadaki merdiven. Tamamen deterministik: skor yok, embedder yok, argüman özeti yeter.

constXID

Kullanıcı tekrarı, kimlik alanları normalize edilince EŞİT — farklı konuşma, hatta farklı kanal dahil. XID deterministik ve kaynak (kişi) kapsamlıdır: aynı iş kimliği sohbetten, batch'ten ya da cron'dan gelmiş olsun tek bir O(1) okumada görünür, ve soru bunu taşır — bu iş 1 dakika önce, sohbet üzerinden tamamlanmış. Araç semanticIdentity beyan ettiyse ve çağrıda resourceId varsa bedavaya gelir; embedder istemez.

constsemanticIdentity

Farklı yazım ya da parafraz, aynı konuşma → hash burada kördür. Devreye girebilen tek katman semantik kimliktir, ve o da yalnız ADAY bulur: kararı normalize kimlik alanları ve insan verir.

constopen gap (v2)

Parafraz + farklı konuşma → AÇIK BOŞLUK. Semantik recall'ın kapsamı thread'dir; kimlik normalize edilince eşit çıkmıyorsa XID de göremez. Bu bilinçli bir sınır: konuşmalar-arası recall ve harici vektör indeksi, veri kapılı v2'ye bırakıldı.

Üçüncü satırın ayrıntısı — çift opt-in, karar hiyerarşisi, kural merdiveni ve yargıcın sertifikası — kendi sayfasında: semantic-duplicate-gate.

Kurulum / import#

Guard @gnldev/durable içinde yaşar ve çalıştırma başına RunLimits ile yapılandırılır:

import { createGnl, DuplicateSideEffectError, type RunLimits } from '@gnldev/durable';

Adım adım kullanım#

gnl.run'a limits geçin. İşaretsiz bir araç yan-etki sayılır; aynı runId içindeki ikinci özdeş çağrı block altında DuplicateSideEffectError fırlatır:

// 'charge' is unmarked treated as a side effect (H7: sideEffect ?? idempotent !== true).
// A second identical charge in the SAME runId is caught by the ladder.
const limits: RunLimits = { sideEffectDuplicates: 'block' };

try {
  await gnl.run('pay', { runId: 'order-42', prompt: 'charge the customer', limits });
} catch (e) {
  if (e instanceof DuplicateSideEffectError) {
    // e.detail.firstToolCallId the original successful call
    console.log('duplicate blocked:', e.detail.toolName, e.detail.firstToolCallId);
  }
}

Modelin kendini toparlamasını tercih ediyorsanız reflect kullanın: tek bir nudge alır ve doğru şekilde devam edebilir; yalnızca inatçı bir özdeş tekrar o zaman bloklanır:

// 'reflect' does NOT stop the run: the model gets one journaled "reconsider" nudge
// (record status 'reflected'). An identical repeat AFTER the nudge escalates to a block.
const limits: RunLimits = { sideEffectDuplicates: 'reflect' };

Gerçekten idempotent bir aracı idempotent: true ile işaretleyin ki guard onun için hiç ateşlenmesin (salt-okuma sorguları, durum yoklamaları):

// Exempt a genuinely idempotent tool so the guard never fires for it:
const getStatus = { execute: async (a) => fetchStatus(a), idempotent: true };

API referansı#

typeRunLimits.sideEffectDuplicates

RunLimits alanı: 'off' | 'warn' | 'reflect' | 'block' | 'suspend'. Varsayılan 'warn'. Aynı çalıştırmada özdeş argümanlarla tekrarlamak üzere olan bir yan-etki aracına uygulanır.

classDuplicateSideEffectError

'block' altında (ve yok sayılan bir 'reflect' nudge'ından sonra) fırlatılır. detail: { toolName, argsHash, firstToolCallId, toolCallId }.

typeAnyTool.sideEffect / idempotent

Bir araç varsayılan olarak yan-etkilidir (H7: sideEffect ?? idempotent !== true). Guard'dan muaf tutmak için idempotent: true (veya sideEffect: false) işaretleyin.

Reflect vs block
reflect gerçek ajanlar için pragmatik varsayılan tercihtir: nudge, kafası karışmış bir modelin çalıştırmayı öldürmeden kendini düzeltmesine izin verir; özdeş tekrardan sonra block'a yükselme güvenlik garantisini korur. Nudge metni modele gider ve marka-nötrdür.
Not
Varsayılan off değil warn'dır: davranış değişmez ama her tekrar journal'lanan bir incident olarak adlandırılır — böylece bir operatör, konsol satırına buharlaşmak yerine onu sorgulayabilir.
İlgili
Bunun üzerine kurulduğu çalıştırma-başına exactly-once garantisi için exactly-once-tools, untrusted içerikte ateşlenen kardeş merdiven için taint-guard, suspend'in yönlendirdiği onay akışı için human-in-loop-approvals, ve hash'in kör kaldığı farklı-yazım vakası için semantic-duplicate-gate sayfalarına bakın.