Langsung ke konten
Tutorial

Sunting PII dari log agen AI sebelum masuk ke database Anda

| 7 min read

Agen Anda mencatat setiap panggilan cepat dan alat. Satu SSN yang terlewat dalam transkrip berubah menjadi pengungkapan GDPR. Middleware tiga baris memperbaikinya sebelum baris ditulis.

Padlock representing PII redaction and data protection in AI agent logs
Photo by FLY:D on Unsplash

Agen AI Anda mencatat perintah tersebut. Input panggilan alat. Hasil alatnya. Tanggapan terakhir. Itu dulunya adalah tambang emas dalam proses debug data. Saat ini, pengungkapan GDPR menunggu tiket dukungan untuk membawa SSN melewati validasi Anda.

Anda tidak dapat menghentikan pengguna untuk menempelkan data sensitif. Anda dapat menghentikan teks mentah mencapai penyimpanan log Anda, vendor observasi Anda, dan ekspor evaluasi mingguan Anda. Sebuah middleware kecil melakukannya dalam satu hop.

Kebocoran yang sudah dimiliki sebagian besar pengaturan agen

// before: every raw prompt, tool call, and tool result lands in the log row
logger.info({
  event: 'agent.turn',
  prompt: userInput,
  tool_calls: toolCalls,
  tool_results: toolResults,
});

// one support ticket later: "My SSN is 123-45-6789 and card 4111 1111 1111 1111"
// sits in the logs, the observability vendor, and the weekly eval export.

Setiap baris sekarang membawa nomor kartu. Toko kayu menyimpannya selama 30 hari. SDK observabilitas mengirimkannya ke pihak ketiga. Ekspor eval mengambil string yang sama dua hari kemudian. Lima salinan dari satu kartu; semuanya berada di luar cakupan kebijakan enkripsi saat tidak aktif Anda.

Deteksi PII dengan satu panggilan

Botoi /v1/pii/detect titik akhir memindai teks untuk email, nomor telepon, SSN, kartu kredit (divalidasi Luhn), alamat IP, dan tanggal lahir. Ia mengembalikan setiap temuan dengan offset awal, offset akhir, dan nilai bertopeng yang dapat Anda letakkan di tempatnya.

Meminta

curl -X POST https://api.botoi.com/v1/pii/detect \\
  -H "Content-Type: application/json" \\
  -d '{"text": "Reach me at alice@example.com or 555-123-4567. Card: 4111 1111 1111 1111."}'

Tanggapan

{
  "found": true,
  "count": 3,
  "findings": [
    { "type": "email",       "value": "alice@example.com",      "start": 12, "end": 29, "masked": "al***@example.com" },
    { "type": "phone",       "value": "555-123-4567",           "start": 33, "end": 45, "masked": "***-***-4567" },
    { "type": "credit_card", "value": "4111 1111 1111 1111",    "start": 53, "end": 72, "masked": "************1111" }
  ]
}

Tiga korek api, tiga pengganti bertopeng, posisi yang dapat Anda sambung dengan rapi. Tidak ada perpustakaan regex yang harus dipelihara, tidak ada tabel awalan SSN yang harus diperbarui, tidak ada pass Luhn untuk ditulis sendiri.

Middleware log yang disunting sebelum ditulis

Tempat yang tepat untuk ini adalah lompatan terakhir sebelum baris meninggalkan proses Anda. Setiap komponen upstream masih melihat teks mentah yang dibutuhkannya; salinan yang ada akan dibersihkan.

// log-redact.ts
import type { LogRecord } from './types';

const PII_FIELDS = ['prompt', 'tool_calls', 'tool_results', 'output'] as const;

export async function redactPii(record: LogRecord): Promise<LogRecord> {
  const clone = structuredClone(record);
  for (const field of PII_FIELDS) {
    const value = clone[field];
    if (!value) continue;
    clone[field] = await scrub(JSON.stringify(value));
  }
  return clone;
}

async function scrub(text: string): Promise<string> {
  const res = await fetch('https://api.botoi.com/v1/pii/detect', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: \`Bearer \${process.env.BOTOI_API_KEY}\`,
    },
    body: JSON.stringify({ text }),
  });
  const data = await res.json();
  if (!data.found) return text;

  // Replace from the end of the string so offsets stay valid.
  const sorted = [...data.findings].sort((a, b) => b.start - a.start);
  let scrubbed = text;
  for (const f of sorted) {
    scrubbed = scrubbed.slice(0, f.start) + f.masked + scrubbed.slice(f.end);
  }
  return scrubbed;
}

Tiga detail penting dalam cuplikan itu. Pertama, ia menelusuri bidang-bidang yang banyak mengandung PII daripada seluruh catatan; Anda tidak perlu menghapus ID permintaan. Kedua, membuat serial setiap bidang menjadi satu string sebelum dikirim ke API, sehingga satu panggilan mencakup seluruh hasil alat. Ketiga, ia menyambung pengganti dari ujung senar sehingga offset tidak bergeser ke bawahnya.

Masukkan ke dalam logger

// logger.ts
import { redactPii } from './log-redact';

export async function logTurn(raw: LogRecord) {
  const safe = await redactPii(raw);
  await logStore.write(safe);
}

// anywhere in your agent loop:
await logTurn({
  event: 'agent.turn',
  prompt: userInput,
  tool_calls: toolCalls,
  tool_results: toolResults,
});

Panggilan logTurn menggantikan keberadaanmu saat ini logger.info pada batas belokan. Segala sesuatu di hulu tetap sama.

Gagal ditutup, bukan gagal diam

Titik akhir deteksi biasanya menjawab dalam waktu kurang dari 20 md. Ketika waktu habis, Anda masih mempunyai pilihan: mencatat baris secara mentah (risiko kebocoran) atau menghapus bidang sensitif dan mencatat penanda. Penghapusan adalah default yang lebih aman untuk beban kerja yang sensitif terhadap kepatuhan.

async function redactPiiSafe(record: LogRecord): Promise<LogRecord> {
  try {
    return await Promise.race([
      redactPii(record),
      new Promise<LogRecord>((_, reject) =>
        setTimeout(() => reject(new Error('pii-detect timeout')), 250)
      ),
    ]);
  } catch (err) {
    // Fail closed: drop the sensitive fields rather than logging them raw.
    return { ...record, prompt: '[REDACT_FAILED]', tool_calls: [], tool_results: [] };
  }
}

Atur batas waktu menjadi sesuatu yang kecil. 250 ms sudah cukup untuk mengatasi pelambatan regional tanpa menghalangi jalur permintaan yang sehat.

versi piton

# log_redact.py
import os, json, httpx

PII_FIELDS = ('prompt', 'tool_calls', 'tool_results', 'output')
API = 'https://api.botoi.com/v1/pii/detect'

async def scrub(text: str) -> str:
    async with httpx.AsyncClient(timeout=0.25) as client:
        r = await client.post(
            API,
            headers={'Authorization': f"Bearer {os.environ['BOTOI_API_KEY']}"},
            json={'text': text},
        )
    data = r.json()
    if not data.get('found'):
        return text
    out = text
    for f in sorted(data['findings'], key=lambda x: x['start'], reverse=True):
        out = out[:f['start']] + f['masked'] + out[f['end']:]
    return out

Menjatuhkan scrub ke dalam log hook kerangka agen Anda. Middleware FastAPI, callback LangChain, dan eksportir rentang OpenInference semuanya menerima fungsi asinkron.

Apa yang tidak dilakukan oleh middleware ini

  • Itu tidak menangkap nama, alamat, atau nomor akun yang sepertinya bukan jenis yang didukung. Hal tersebut memerlukan model entitas bernama dan keputusan kebijakan (menutupkan? menghapus? menyunting keseluruhannya?).
  • Itu tidak melindungi vendor model Anda dari melihat prompt mentah. Untuk itu, jalankan panggilan deteksi yang sama pada klien sebelum Anda mengirim ke model.
  • Kebijakan ini tidak menggantikan kebijakan penyimpanan data. Persingkat log TTL saja.

Dua tempat yang menjadi miliknya

Lapisan Melindungi Waktu panggilan
Sebelum permintaan model Vendor model, data pelatihan, kebocoran evaluasi Memblokir, latensi yang terlihat oleh pengguna
Sebelum log tulis Penyimpanan kayu, vendor observasi, ekspor Out-of-band, tidak terlihat oleh pengguna

Kirimkan middleware penulisan log terlebih dahulu. Ini berjalan di luar jalur panas dan memblokir pola kebocoran yang paling umum. Tambahkan versi pra-model setelah sisi log tertutup.

Dapatkan kunci API dan mulai

Akses anonim memberi Anda 5 permintaan per menit, cukup untuk mencoba titik akhir terhadap log sampel. Untuk middleware produksi, ambil kunci gratis di botoi.com/api/signup. Tingkat gratis mencakup 1.000 panggilan scrub per hari tanpa kartu kredit.

Lihat referensi titik akhir selengkapnya di Halaman API Deteksi PII atau jelajahi api.botoi.com/docs untuk 149 titik akhir lainnya.

FAQ

Mengapa log agen AI membocorkan lebih banyak PII dibandingkan log server normal?
Agen mencatat seluruh perintah, setiap masukan panggilan alat, dan setiap keluaran alat. Transkrip dukungan yang dulu berada di balik tanda "jangan log" kini muncul di lima tempat: orkestrator, server alat, vendor observabilitas, penyedia model, dan set evaluasi pelatihan.
Di manakah langkah redaksi harus dijalankan?
Jalankan di batas penulis log, tepat sebelum baris dikirim ke penyimpanan log Anda. Dengan begitu, setiap komponen upstream (orchestrator, alat, SDK observabilitas) melihat teks mentah yang dibutuhkannya, dan hanya salinan tersimpan yang dibersihkan.
Apakah redaktur regex menangkap semuanya?
Tidak. Regex roll-your-own melewatkan nomor kartu kredit dengan spasi yang tidak biasa, SSN yang terlihat seperti nomor 9 digit lainnya, dan nama orang. API seperti /v1/pii/detect menjalankan Luhn pada kartu, memfilter awalan SSN, dan mengembalikan posisi sehingga Anda hanya dapat menghapus kecocokan, bukan seluruh baris.
Latensi apa yang ditambahkan oleh Botoi PII Detect API?
Titik akhir berjalan di edge dan kembali dalam waktu kurang dari 20 md untuk muatan 500 token. Anda dapat memanggilnya secara sinkron di middleware log tanpa memengaruhi waktu respons yang terlihat oleh pengguna; logging terjadi setelah respons dikirim.
Bisakah saya menyunting klien sebelum mengirimkannya ke model?
Ya, dan ini adalah lapisan kedua yang bagus. Penyuntingan di middleware server melindungi penyimpanan log Anda; penyuntingan di klien melindungi vendor model Anda agar tidak melihat PII mentah. Keduanya merupakan pengaturan yang ramah GDPR.

Mulai membangun dengan botoi

150+ endpoint API untuk pencarian, pemrosesan teks, pembuatan gambar, dan utilitas developer. Paket gratis, tanpa kartu kredit.