Watch the lesson video: Menyediakan Ejen AI dengan Resit Kriptografi
(Video pelajaran dan gambar kecil akan ditambah oleh pasukan kandungan Microsoft selepas penggabungan, mengikut corak pelajaran 14 / 15.)
Pelajaran ini akan merangkumi:
Selepas menamatkan pelajaran ini, anda akan tahu cara untuk:
Bayangkan anda telah mengerahkan ejen AI untuk Contoso Travel. Ejen membaca permintaan pelanggan, memanggil API penerbangan untuk mencari pilihan, dan menempah tempat duduk bagi pihak pelanggan. Suku terakhir lalu, ejen memproses 50,000 tempahan.
Hari ini seorang juruaudit tiba. Mereka bertanya soalan mudah: “Tunjukkan apa yang ejen anda lakukan.”
Anda menyerahkan fail log anda. Juruaudit melihatnya dan bertanya soalan yang lebih sukar: “Bagaimana saya tahu log ini tidak diedit?”
Ini adalah masalah jejak audit. Kebanyakan penyebaran ejen hari ini bergantung kepada:
Tiada satu pun yang boleh menjawab soalan juruaudit tanpa memerlukan juruaudit mempercayai seseorang (anda, penyedia awan anda, vendor pangkalan data anda). Untuk penggunaan dalaman, kepercayaan tersebut biasanya boleh diterima. Untuk beban kerja terkawal (kewangan, penjagaan kesihatan, apa sahaja tertakluk kepada Akta AI EU), ia tidak boleh.
Resit kriptografi menyelesaikan ini dengan menjadikan setiap tindakan ejen boleh disahkan secara bebas. Juruaudit tidak perlu mempercayai anda. Mereka hanya perlu kunci awam anda dan resit itu sendiri.
Resit adalah objek JSON yang merekodkan apa yang ejen lakukan, ditandatangani dengan tandatangan digital.
flowchart LR
A[Ejen memanggil alat] --> B[Bina muatan resit]
B --> C[Kanunkan JSON RFC 8785]
C --> D[Hash SHA-256]
D --> E[Tandatangan Ed25519]
E --> F[Resit dengan tandatangan]
F --> G[Auditor mengesah tanpa talian]
G --> H{Tandatangan sah?}
H -- ya --> I[Bukti tahan gangguan]
H -- tidak --> J[Resit ditolak]
Resit minimum kelihatan seperti ini:
{
"type": "agent.tool_call.v1",
"agent_id": "contoso-travel-bot",
"tool_name": "lookup_flights",
"tool_args_hash": "sha256:a3f9c1...",
"result_hash": "sha256:7b2e1d...",
"policy_id": "contoso-travel-policy-v3",
"timestamp": "2026-04-25T14:30:00Z",
"sequence": 47,
"previous_receipt_hash": "sha256:9d4e6a...",
"signature": {
"alg": "EdDSA",
"sig": "c5af83...",
"public_key": "8f3b2c..."
}
}
Tiga sifat yang menjalankan kerja:
Tandatangan. Resit ditandatangani oleh pintu masuk ejen menggunakan kunci peribadi Ed25519. Sesiapa yang mempunyai kunci awam sepadan boleh mengesahkan tandatangan itu secara luar talian. Penyuntingan mana-mana medan akan membatalkan tandatangan.
Pengekodan kanonik. Sebelum menandatangani, resit diseriaknakan menggunakan Skema Kanonifikasi JSON (JCS, RFC 8785). Ini memastikan dua pelaksanaan yang menghasilkan resit logik yang sama menghasilkan output yang sama tepat. Tanpa kanonikifikasi, serializer JSON berbeza akan menghasilkan tandatangan berbeza untuk kandungan sama.
Rantai hash. Medan previous_receipt_hash menghubungkan setiap resit kepada resit sebelumnya. Mengeluarkan atau menyusun semula satu resit akan merosakkan setiap resit selepasnya. Penyuntingan menjadi jelas pada tahap rantai walaupun tandatangan individu dimintas.
Ketiga-tiga sifat ini memberikan tiga jaminan:
Anda tidak memerlukan perpustakaan khas untuk menghasilkan resit. Primitif kriptografi tersedia meluas dan logiknya hanya beberapa baris Python.
Latihan secara langsung dalam code_samples/18-signed-receipts.ipynb menerangkan alur penuh. Versi ringkasnya:
import json
import hashlib
import base64
from nacl import signing
from jcs import canonicalize # JSON kanonik RFC 8785
def b64url_nopad(data: bytes) -> str:
return base64.urlsafe_b64encode(data).decode("ascii").rstrip("=")
def sha256_canonical(obj) -> str:
"""SHA-256 of a Python object's JCS-canonical JSON form."""
return f"sha256:{hashlib.sha256(canonicalize(obj)).hexdigest()}"
# Jana atau muatkan kunci tandatangan (dalam pengeluaran, simpan dalam peti kunci)
signing_key = signing.SigningKey.generate()
verify_key = signing_key.verify_key
# Bina muatan resit (belum ada tandatangan)
tool_args = {"origin": "SYD", "destination": "LAX"}
tool_result = [{"flight": "QF11", "price": 1850, "stops": 0}]
payload = {
"type": "agent.tool_call.v1",
"agent_id": "contoso-travel-bot",
"tool_name": "lookup_flights",
"tool_args_hash": sha256_canonical(tool_args),
"result_hash": sha256_canonical(tool_result),
"policy_id": "contoso-travel-policy-v3",
"timestamp": "2026-04-25T14:30:00Z",
"sequence": 0,
"previous_receipt_hash": None,
}
# Kanonikan, hash, tandatangan.
canonical_bytes = canonicalize(payload)
message_hash = hashlib.sha256(canonical_bytes).digest()
signature_bytes = signing_key.sign(message_hash).signature
# Lampirkan objek tandatangan berstruktur.
receipt = {
**payload,
"signature": {
"alg": "EdDSA",
"sig": b64url_nopad(signature_bytes),
"public_key": b64url_nopad(bytes(verify_key)),
},
}
Itu keseluruhan laluan penandatanganan. Latihan dalam notebook menerangkan setiap langkah.
Pengesahan adalah operasi songsang:
import base64
import hashlib
from nacl import signing
from nacl.exceptions import BadSignatureError
from jcs import canonicalize
def b64url_decode(s: str) -> bytes:
padding = "=" * ((4 - len(s) % 4) % 4)
return base64.urlsafe_b64decode(s + padding)
def verify_receipt(receipt: dict) -> bool:
# Tandatangan adalah objek berstruktur: {"alg", "sig", "public_key"}.
sig_obj = receipt.get("signature")
if not sig_obj or sig_obj.get("alg") != "EdDSA":
return False
# Bangunkan semula muatan yang sebenarnya ditandatangani (semua kecuali tandatangan).
payload = {k: v for k, v in receipt.items() if k != "signature"}
canonical_bytes = canonicalize(payload)
message_hash = hashlib.sha256(canonical_bytes).digest()
try:
verify_key = signing.VerifyKey(b64url_decode(sig_obj["public_key"]))
verify_key.verify(message_hash, b64url_decode(sig_obj["sig"]))
return True
except BadSignatureError:
return False
Fungsi ini mengambil resit dan mengembalikan True jika tandatangan sah, False jika tidak. Tiada panggilan rangkaian, tiada kebergantungan perkhidmatan, tiada kepercayaan diperlukan kepada mana-mana pihak ketiga.
Untuk melihat pengesanan penyuntingan berfungsi, notebook terangkan:
tool_args_hash.Ini adalah demonstrasi praktikal bahawa resit boleh dikesan penyuntingannya: sebarang pengubahsuaian, walaupun kecil, merosakkan tandatangan.
Satu resit bertandatangan melindungi satu tindakan. Rantai resit melindungi satu urutan.
flowchart LR
R0[Resit 0<br/>asal] --> R1[Resit 1]
R1 --> R2[Resit 2]
R2 --> R3[Resit 3]
R1 -. previous_receipt_hash .-> R0
R2 -. previous_receipt_hash .-> R1
R3 -. previous_receipt_hash .-> R2
Setiap resit merekod hash resit sebelumnya. Untuk mengeluarkan resit 2 tanpa dikesan, penyerang perlu sama ada:
previous_receipt_hash resit 3 (merosakkan tandatangan resit 3), ATAUJika kunci peribadi disimpan dalam peti kunci perkakasan dan anda menerbitkan kunci awam bersama setiap resit, kedua-dua serangan tersebut tidak mungkin berlaku tanpa dikesan.
Notebook menerangkan:
previous_receipt_hash setiap resit sepadan dengan hash sebenar resit sebelumnya.Inilah cara anda menghasilkan jejak audit yang boleh disahkan juruaudit luar tanpa perlu mempercayai anda.
Ini adalah bahagian paling penting pelajaran ini. Resit sangat kuat tapi kuasanya terhad.
Resit membuktikan tiga perkara:
Resit TIDAK membuktikan:
policy_id benar-benar dinilai, atau bahawa ia akan membenarkan tindakan ini jika diperiksa. Resit merekod apa yang dituntut, bukan apa yang dikuatkuasakan.Sempadan ini penting untuk dua sebab:
Kesilapan biasa ialah menganggap “kami ada resit” bermaksud “kami diperintah.” Tidak begitu. Resit adalah asas. Tadbir urus adalah sistem yang anda bina di atasnya.
Kod Python dalam pelajaran ini sengaja minimum supaya anda boleh baca setiap baris dan faham apa yang berlaku. Dalam pengeluaran, anda ada dua pilihan:
Terus bina atas primitif kriptografi. 50 baris yang anda lihat di atas sudah cukup untuk banyak kes penggunaan. PyNaCl (Ed25519) dan pakej jcs (JSON kanonik) adalah perpustakaan yang diselenggara dan diaudit dengan baik.
Gunakan perpustakaan resit pengeluaran. Beberapa projek sumber terbuka melaksanakan corak sama dengan ciri tambahan (rotasi kunci, pengesahan berkelompok, pengedaran JWK Set, integrasi dengan enjin polisi):
draft-farley-acta-signed-receipts) yang kini dalam proses piawaian.protect-mcp (npm) dan @veritasacta/verify (npm) menyediakan pelaksanaan Node bagi penandatanganan resit dan pengesahan luar talian, bertujuan untuk membalut mana-mana pelayan MCP dengan jejak audit yang mudah dikesan penyuntingannya.Keputusan antara membina sendiri dan guna perpustakaan serupa dengan keputusan menulis perpustakaan JWT sendiri versus guna perpustakaan yang telah diuji: kedua-duanya munasabah; perpustakaan menjimatkan masa dan mengurangkan kawasan audit; cara-bina-sendiri memaksa anda faham setiap primitif. Pelajaran ini mengajar jalan cara-bina-sendiri supaya anda ada asas untuk mana-mana pilihan.
Uji kefahaman anda sebelum beralih ke latihan praktikal.
1. Resit ditandatangani menggunakan kunci peribadi Ed25519 ejen. Juruaudit hanya ada kunci awam. Boleh juruaudit mengesahkan resit secara luar talian?
2. Penyerang mengubah medan policy_id dalam resit untuk mendakwa ia dikawal oleh polisi lebih permisif. Tandatangan itu dibuat ke atas muatan asal. Apa berlaku semasa pengesahan?
3. Kenapa resit memasukkan tool_args_hash dan result_hash dan bukan hujah dan keputusan mentah?
4. Medan previous_receipt_hash menghubungkan setiap resit kepada pendahulunya. Jika penyerang memadam satu resit secara senyap dari tengah rantai, apa yang menjadi tidak sah?
5. Resit mengesahkan dengan bersih. Adakah itu membuktikan tindakan ejen betul, sah, atau patuh polisi?
Buka code_samples/18-signed-receipts.ipynb dan lengkapkan keempat-empat bahagian:
Cabaran lanjutan 1: lanjutkan skema resit dengan medan tambahan pilihan anda (contohnya, ID permintaan untuk penjejakan), kemas kini logik penandatanganan kanonik untuk memasukkannya, dan sahkan resit masih melalui pengesahan. Kemudian ubah medan selepas tandatangan dan sahkan pengesahan gagal. Ini memaksa anda faham bagaimana setiap bait pengekodan kanonik menyumbang kepada tandatangan. Cabaran regangan 2: SHA-256-hash dua resit anda bersama-sama (gabungkan bait kanonik mereka dalam susunan deterministik) dan tanamkan digest yang terhasil sebagai medan baharu pada resit ketiga sebelum menandatanganinya. Sahkan bahawa ketiga-tiga resit masih boleh diproses dua hala. Anda baru sahaja membina bukti kemasukan satu langkah: sesiapa yang memegang resit ketiga boleh membuktikan dua resit pertama wujud pada masa ia ditandatangani, tanpa perlu mendedahkan kandungannya. Ini adalah corak yang digunakan oleh resit pendedahan selektif pada skala besar (komitmen Merkle, RFC 6962).
Resit kriptografi memberikan ejen AI jejak audit yang:
Ia bukan pengganti untuk pengesahan input, penguatkuasaan dasar, atau infrastruktur identiti. Ia adalah asas bagi lapisan-lapisan tersebut. Apabila anda melancarkan ejen ke dalam beban kerja terkawal, aliran kerja pelbagai organisasi, atau mana-mana tetapan di mana juruaudit masa depan tidak boleh dianggap mempercayai anda, resit adalah cara untuk memastikan jejak audit jujur.
Pengajaran yang paling penting: resit membuktikan siapa yang berkata apa, bila. Ia tidak membuktikan bahawa apa yang dikatakan adalah benar atau tepat. Pegang perbezaan itu dengan erat. Ia adalah perbezaan antara sistem asal-usul yang jujur dan yang mengelirukan.
Apabila anda bersedia untuk melangkah dari pelajaran ini kepada pelancaran ejen yang ditandatangani resit dalam persekitaran sebenar:
https://your-org.example.com/.well-known/agent-keys.json.Sertai Microsoft Foundry Discord untuk bertemu dengan pelajar lain, menghadiri waktu pejabat, dan mendapatkan jawapan kepada soalan Ejen AI anda.
Pelajaran ini merangkumi penandatanganan resit tunggal dan urutan rantaian hash. Primitif yang sama membentuk beberapa corak lanjutan yang mungkin anda temui apabila kedudukan tadbir urus anda matang:
authorization_*) dan pasca-pelaksanaan (result_*) dengan tandatangan bebas, berguna apabila keputusan kebenaran dan hasil yang diperhatikan dihasilkan oleh pelaku berbeza atau pada masa berlainan. Ini ditambah secara selari di atas format resit yang diajar dalam pelajaran ini.result_hash. Beban dunia sebenar sering lebih kaya daripada hasil panggilan alat tunggal: pertimbangan pra-keputusan (ramalan model, pilihan yang dipertimbangkan, bukti dan kesempurnaannya, kedudukan risiko, rantai akauntabiliti, hasil pintu masuk) boleh semua hidup dalam beban, disegel oleh satu resit. Ini mengekalkan format resit minimum sambil membolehkan skema beban berkembang domain demi domain.signature.alg boleh membawa ML-DSA-65 (standard tandatangan pasca-kuantum NIST) apabila anda perlu berpindah. Rancang tempoh peralihan di mana resit ditandatangani dua kali.Menjadi Ejen Penggunaan Komputer (CUA)
(Akan ditentukan oleh penyelenggara kurikulum)
Penafian: Dokumen ini telah diterjemahkan menggunakan perkhidmatan terjemahan AI Co-op Translator. Walaupun kami berusaha untuk ketepatan, sila ambil maklum bahawa terjemahan automatik mungkin mengandungi kesilapan atau ketidaktepatan. Dokumen asal dalam bahasa asalnya harus dianggap sebagai sumber yang sahih. Untuk maklumat penting, terjemahan oleh manusia profesional adalah disyorkan. Kami tidak bertanggungjawab terhadap sebarang salah faham atau salah tafsir yang timbul daripada penggunaan terjemahan ini.