Gerbang Persetujuan dengan Keterlibatan Manusia
Pola jeda–minta–setujui untuk tindakan agen yang berisiko tinggi.
Gerbang Persetujuan dengan Keterlibatan Manusia adalah pelajaran AI Agents gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Agents, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Agents mencakup 4 pelajaran total.
Saat Agen Memerlukan Persetujuan Manusia
Untuk tindakan berisiko tinggi — mengirim kontrak, menghapus data produksi, membelanjakan anggaran, atau mengirim pengumuman publik — agen sebaiknya tidak bertindak secara otonom. Agen harus berhenti sejenak dan meminta persetujuan manusia sebelum melanjutkan.
Ini adalah pola manusia dalam proses (HITL).
Menentukan Tindakan Berisiko Tinggi
Tentukan fungsi klasifikasi yang mengidentifikasi tindakan mana yang memerlukan persetujuan manusia. Ambang batasnya dapat disesuaikan untuk setiap penerapan berdasarkan toleransi risiko.
HIGH_STAKES_ACTIONS = {
'send_email',
'delete_records',
'publish_content',
'transfer_funds',
'modify_production_config',
'export_all_data',
'send_push_notification_to_all'
}
HIGH_STAKES_THRESHOLDS = {
'transfer_funds': 1000, # USD — require approval above this
'delete_records': 10, # rows
'send_email': 50, # recipients
'push_notification': 1000 # users
}
def requires_approval(action: str, parameters: dict) -> bool:
if action not in HIGH_STAKES_ACTIONS:
return False
threshold = HIGH_STAKES_THRESHOLDS.get(action)
if threshold is None:
return True # all instances require approval
# Check parameter against threshold
amount = parameters.get('amount') or parameters.get('count') or 0
return float(amount) >= threshold
if __name__ == '__main__':
print('Small transfer:', requires_approval('transfer_funds', {'amount': 200}))
print('Large transfer:', requires_approval('transfer_funds', {'amount': 5000}))
print('Publish content:', requires_approval('publish_content', {}))
Membuat Permintaan Persetujuan
Saat persetujuan diperlukan, agen membuat catatan permintaan persetujuan dan menangguhkan eksekusi. Permintaan tersebut mencakup deskripsi tentang tindakan yang akan dilakukan, parameternya, dan tenggat waktu.
import uuid, time
approval_requests: dict[str, dict] = {} # approval_id -> request
def create_approval_request(agent_id: str, user_id: str, action: str,
parameters: dict, timeout_minutes: int = 30) -> str:
approval_id = str(uuid.uuid4())
approval_requests[approval_id] = {
'approval_id': approval_id,
'agent_id': agent_id,
'user_id': user_id,
'action': action,
'parameters': parameters,
'status': 'pending', # pending / approved / rejected / timed_out
'created_at': time.time(),
'expires_at': time.time() + timeout_minutes * 60,
'decided_by': None,
'decided_at': None
}
return approval_id
if __name__ == '__main__':
approval_id = create_approval_request(
'agent-1', 'user-42', 'delete_records', {'count': 50}
)
print('Created approval request:', approval_id)
print('Status:', approval_requests[approval_id]['status'])
Mengirim Notifikasi melalui Slack
Kirim permintaan persetujuan kepada pemberi persetujuan melalui Slack. Sertakan ringkasan tentang tindakan yang ingin dilakukan agen, tautan untuk menyetujui atau menolak, serta tenggat waktu.
import requests
SLACK_WEBHOOK = 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'
APPROVAL_BASE_URL = 'https://your-agent-dashboard.com/approvals'
def notify_approver_slack(approval_id: str, approver_slack_id: str):
req = approval_requests[approval_id]
import time as t
from datetime import datetime
expires = datetime.fromtimestamp(req['expires_at']).strftime('%H:%M UTC')
payload = {
'text': f'<@{approver_slack_id}> Agent approval required',
'attachments': [{
'color': '#ff9900',
'fields': [
{'title': 'Action', 'value': req['action'], 'short': True},
{'title': 'Requested by','value': req['user_id'], 'short': True},
{'title': 'Parameters', 'value': str(req['parameters'])[:200]},
{'title': 'Expires', 'value': expires, 'short': True}
],
'actions': [
{'type': 'button', 'text': 'Approve',
'url': f'{APPROVAL_BASE_URL}/{approval_id}/approve'},
{'type': 'button', 'text': 'Reject',
'url': f'{APPROVAL_BASE_URL}/{approval_id}/reject'}
]
}]
}
requests.post(SLACK_WEBHOOK, json=payload)Mengirim Notifikasi melalui Surel
Sebagai kanal cadangan (atau kanal utama bagi organisasi yang tidak menggunakan Slack), kirim permintaan persetujuan melalui surel dengan tautan yang jelas untuk menyetujui atau menolak.
import smtplib
from email.mime.text import MIMEText
SMTP_HOST = 'smtp.yourcompany.com'
SMTP_PORT = 587
SMTP_USER = 'agent-noreply@yourcompany.com'
SMTP_PASS = 'YOUR_SMTP_PASSWORD'
def notify_approver_email(approval_id: str, approver_email: str):
req = approval_requests[approval_id]
body = (
f'An AI agent is requesting approval for:\n\n'
f'Action: {req["action"]}\n'
f'Parameters: {req["parameters"]}\n\n'
f'Approve: {APPROVAL_BASE_URL}/{approval_id}/approve\n'
f'Reject: {APPROVAL_BASE_URL}/{approval_id}/reject\n\n'
f'This request expires in 30 minutes.'
)
msg = MIMEText(body)
msg['Subject'] = f'Agent Approval Required: {req["action"]}'
msg['From'] = SMTP_USER
msg['To'] = approver_email
with smtplib.SMTP(SMTP_HOST, SMTP_PORT) as server:
server.starttls()
server.login(SMTP_USER, SMTP_PASS)
server.send_message(msg)Memeriksa Keputusan Persetujuan Secara Berkala
Setelah mengirim notifikasi, agen menunggu keputusan. Gunakan perulangan pemeriksaan berkala dengan interval jeda singkat. Hentikan pemeriksaan ketika status berubah dari 'menunggu' atau ketika tenggat waktu terlewati.
import time
def wait_for_approval(approval_id: str, poll_interval: float = 5.0) -> dict:
while True:
req = approval_requests.get(approval_id)
if not req:
return {'decision': 'error', 'reason': 'Approval request not found'}
if req['status'] == 'approved':
return {'decision': 'approved', 'decided_by': req['decided_by']}
if req['status'] == 'rejected':
return {'decision': 'rejected', 'decided_by': req['decided_by']}
if time.time() > req['expires_at']:
req['status'] = 'timed_out'
return {'decision': 'timed_out', 'reason': 'No decision within deadline'}
time.sleep(poll_interval)Mencatat Keputusan Persetujuan
Saat pemberi persetujuan mengeklik Setujui atau Tolak, catat siapa yang mengambil keputusan dan kapan keputusan itu diambil. Dengan demikian, terbentuk jejak audit persetujuan yang lengkap: diminta → diberi tahu → diputuskan → dijalankan (atau dibatalkan).
def record_decision(approval_id: str, decision: str,
decided_by: str) -> dict:
req = approval_requests.get(approval_id)
if not req:
return {'error': 'Approval request not found'}
if req['status'] != 'pending':
return {'error': f'Request already in state: {req["status"]}'}
if time.time() > req['expires_at']:
req['status'] = 'timed_out'
return {'error': 'Request has expired'}
req['status'] = decision # 'approved' or 'rejected'
req['decided_by'] = decided_by
req['decided_at'] = time.time()
return {'ok': True, 'decision': decision}Penanganan Batas Waktu: Pembatalan Otomatis
Jika tidak ada keputusan dalam jangka waktu yang ditentukan, agen secara otomatis membatalkan tindakan tersebut dan memberi tahu pemohon awal. Hal ini mencegah tindakan terblokir secara permanen karena pemberi persetujuan tidak merespons.
def handle_timeout(approval_id: str, agent_session: dict) -> str:
req = approval_requests.get(approval_id, {})
action = req.get('action', 'unknown')
user_id = req.get('user_id', 'unknown')
# Log the timeout
import logging
logging.warning(
'Approval timeout: action=%s user=%s approval_id=%s',
action, user_id, approval_id
)
# Tell the user
timeout_message = (
f'The "{action}" action was automatically cancelled because '
f'no approver responded within the 30-minute window. '
f'Please request again or contact your administrator.'
)
return timeout_messageOrkestrasi Gerbang Persetujuan Lengkap
Gabungkan semua langkah: periksa apakah persetujuan diperlukan, buat permintaan, kirim notifikasi, tunggu, lalu lanjutkan atau batalkan berdasarkan keputusan.
def execute_with_approval_gate(agent_id: str, user_id: str, action: str,
parameters: dict, approver_email: str,
execute_fn) -> dict:
# Step 1: Check if approval needed
if not requires_approval(action, parameters):
result = execute_fn(action, parameters)
return {'approved': True, 'auto': True, 'result': result}
# Step 2: Create approval request
approval_id = create_approval_request(agent_id, user_id, action, parameters)
# Step 3: Notify approver
notify_approver_email(approval_id, approver_email)
print(f'Approval requested: {approval_id}. Waiting...')
# Step 4: Wait for decision
decision = wait_for_approval(approval_id)
# Step 5: Act on decision
if decision['decision'] == 'approved':
result = execute_fn(action, parameters)
return {'approved': True, 'decided_by': decision['decided_by'], 'result': result}
elif decision['decision'] == 'rejected':
return {'approved': False, 'reason': 'Rejected by approver'}
else:
msg = handle_timeout(approval_id, {})
return {'approved': False, 'reason': msg}Jejak Audit Persetujuan
Setiap peristiwa dalam siklus hidup persetujuan harus dicatat dalam catatan audit: permintaan dibuat, notifikasi dikirim, keputusan diambil, serta tindakan dijalankan atau dibatalkan. Jejak ini diperlukan untuk kepatuhan SOC 2.
import logging, json, time
approval_logger = logging.getLogger('agent.approvals')
def audit_approval_event(event: str, approval_id: str, details: dict):
entry = {
'timestamp': time.time(),
'event': event,
'approval_id': approval_id,
**details
}
approval_logger.info(json.dumps(entry))
# Usage flow:
# audit_approval_event('request_created', approval_id, {'action': 'delete_records', 'user': 'u123'})
# audit_approval_event('notification_sent', approval_id, {'channel': 'email', 'approver': 'admin@co.com'})
# audit_approval_event('decision_received', approval_id, {'decision': 'approved', 'by': 'admin@co.com'})
# audit_approval_event('action_executed', approval_id, {'result': 'success'})
if __name__ == '__main__':
import sys
approval_logger.setLevel(logging.INFO)
approval_logger.addHandler(logging.StreamHandler(sys.stdout))
audit_approval_event('request_created', 'appr-1', {'action': 'delete_records', 'user': 'u123'})
Eskalasi Saat Pemberi Persetujuan Utama Tidak Tersedia
Jika pemberi persetujuan utama tidak merespons dalam separuh jangka waktu yang ditentukan, teruskan permintaan kepada pemberi persetujuan sekunder. Hal ini mencegah semua persetujuan terhambat karena satu orang sedang tidak berada di tempat.
def escalate_if_needed(approval_id: str, secondary_email: str,
escalation_at_pct: float = 0.5):
req = approval_requests.get(approval_id)
if not req or req['status'] != 'pending':
return
total_window = req['expires_at'] - req['created_at']
elapsed = time.time() - req['created_at']
escalation_at = req['created_at'] + total_window * escalation_at_pct
if time.time() >= escalation_at and not req.get('escalated'):
req['escalated'] = True
notify_approver_email(approval_id, secondary_email)
print(f'Escalated approval {approval_id} to {secondary_email}')Apa yang terjadi pada permintaan persetujuan yang masih menunggu ketika batas waktu berakhir?
Perilaku penanganan batas waktu merupakan bagian penting dari desain HITL. Pemilihan pengaturan bawaan yang keliru dapat menimbulkan konsekuensi berbeda terhadap keamanan dan kemudahan penggunaan.
Rangkuman Gerbang Persetujuan dengan Manusia dalam Proses
Gerbang persetujuan HITL bekerja dengan cara: mengklasifikasikan tindakan berisiko tinggi, membuat permintaan persetujuan yang ditangguhkan, memberi tahu pemberi persetujuan melalui Slack/surel, memeriksa keputusan secara berkala, membatalkan secara otomatis saat batas waktu terlewati, dan mencatat setiap peristiwa dalam siklus hidup pada jejak audit.
Eskalasi kepada pemberi persetujuan sekunder mencegah kebuntuan persetujuan akibat ketidaktersediaan.
Belajar AI Agents dengan tutor AI — gratis
Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.
- Kursus
- 60
- Pelajaran
- 239
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Gerbang Persetujuan dengan Keterlibatan Manusia” gratis?
Ya — teks lengkap “Gerbang Persetujuan dengan Keterlibatan Manusia” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Agents, upgrade ke CoddyKit PRO. Kursus AI Agents mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Gerbang Persetujuan dengan Keterlibatan Manusia”?
Pola jeda–minta–setujui untuk tindakan agen yang berisiko tinggi. Kamu berlatih AI Agents dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai AI Agents?
Tidak diperlukan pengalaman sebelumnya. AI Agents di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.
Berapa lama pelajaran “Gerbang Persetujuan dengan Keterlibatan Manusia” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Agents ini?
Ya. Setiap pelajaran AI Agents menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Pencatatan Tindakan Agen yang Tidak Dapat Diubah
- Penegakan Kebijakan untuk Tindakan Agen
- Kepatuhan Regulasi: GDPR dan SOC2
- Gerbang Persetujuan dengan Keterlibatan Manusia