

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Memori jangka panjang semantik untuk LangGraph agen
<a name="ddb-langgraph-memory"></a>

LangGraph memisahkan dua jenis status agen. Short-term state adalah utas percakapan itu sendiri, yang dipertahankan checkpointer sehingga utas dapat melanjutkan, memutar ulang, dan memulihkan (lihat[Menggunakan DynamoDB sebagai penyimpanan pos pemeriksaan untuk agen LangGraph](ddb-langgraph-checkpoint.md)). Long-term memori adalah apa yang diketahui agen di seluruh utas, dan LangGraph memodelkannya sebagai penyimpanan: permukaan nilai kunci dengan spasi nama yang ditulis agen dengan sengaja dan dibaca kembali nanti.

Kel `DynamoDBStore` as, dalam [ paket ](https://pypi.org/project/langgraph-checkpoint-aws/) langgraph-checkpoint-aws, adalah implementasi DynamoDB dari penyimpanan itu. Ini menangani sisi nilai kunci dengan ruang nama hierarkis, Time to Live untuk memori basi yang kedaluwarsa, dan pemfilteran dasar. Dengan indeks vektor yang dikonfigurasi (lihat[Menggunakan indeks vektor di DynamoDB](VectorSearch.md)), `search()` metodenya melakukan pencarian semantik: memori disematkan pada penulisan, diindeks secara asinkron, dan diingat berdasarkan makna, diberi peringkat berdasarkan kesamaan, dari tabel yang sama yang menahannya. Tidak ada database vektor terpisah untuk disediakan dan tidak ada saluran menyalin data ke dalamnya.

## Prasyarat
<a name="langgraph-memory-prerequisites"></a>
+  Akun AWS Dengan izin untuk membuat tabel DynamoDB dan memanggil model Amazon Bedrock
+ Akses ke model embeddings di Amazon Bedrock di Wilayah Anda. Contoh-contoh ini menggunakan Amazon Titan Text Embeddings V2
+ Python 3.10 atau yang lebih baru, dengan `langgraph-checkpoint-aws` 1.2.2 atau yang lebih baru dan `boto3` 1.43.64 atau lebih baru (`boto3`versi sebelumnya tidak memiliki operasi) `SearchVectors`

Instal pustaka menggunakan pip:

```
pip install langgraph langgraph-checkpoint-aws langchain-aws
```

## Siapkan toko
<a name="langgraph-memory-setup"></a>

Konfigurasikan toko dengan `index` blok dan panggil`setup()`:

```
from langchain_aws import BedrockEmbeddings
from langgraph_checkpoint_aws import DynamoDBStore

store = DynamoDBStore(
    table_name="support-agent-memory",
    region_name="us-east-1",
    index={
        "embed": BedrockEmbeddings(model_id="amazon.titan-embed-text-v2:0"),
        "dims": 1024,
        "fields": ["text"],
        "distance_function": "COSINE",
    },
)

store.setup()
```

Empat pengaturan di `index` blok patut dipahami:
+ `embed`mengambil objek LangChain embeddings apa pun, atau callable biasa yang memetakan daftar string ke daftar vektor.
+ `dims`harus sesuai dengan ukuran output model Anda. Titan Text Embeddings V2 mengembalikan 1.024 dimensi secara default. Jika ini tidak setuju, toko menimbulkan kesalahan ketidakcocokan dimensi yang menamai kedua angka pada penulisan pertama, daripada menulis vektor yang tidak dapat digunakan indeks.
+ `fields`memilih bagian mana dari nilai yang disematkan. Di sini hanya `text` bidang yang tertanam. Default,`["$"]`, membuat serial seluruh nilai ke JSON dan menyematkannya, yang nyaman tetapi juga menyematkan atribut pembukuan Anda.
+ `distance_function`default ke`COSINE`, dan juga menerima `EUCLIDEAN` dan`DOT_PRODUCT`.

`setup()`membuat tabel jika tidak ada, melampirkan indeks vektor, dan mengaktifkan Time to Live jika Anda mengonfigurasinya. Pada tabel yang ada, itu hanya menambahkan apa yang hilang, sehingga penerapan yang ada `DynamoDBStore` dapat mengadopsi pencarian semantik tanpa membuat ulang tabel atau memigrasikan item. Perlu diingat bahwa `setup()` tidak kembali sampai indeks melaporkan `ACTIVE` dan tidak lagi diisi ulang: indeks yang melaporkan `ACTIVE` sementara masih mengisi ulang menolak `SearchVectors` panggilan. Di meja kosong baru penantiannya singkat. Pemasangan ulang ke meja dengan barang-barang yang ada membutuhkan waktu selama pengisian ulang.

## Tulis kenangan
<a name="langgraph-memory-write"></a>

Menulis adalah hal yang biasa`put()`. Penyematan terjadi untuk Anda:

```
namespace = ("memories", "acme-corp", "user-8812")

store.put(namespace, "mem-1", {
    "text": "Account runs a proxy that closes idle sockets after 60 seconds",
    "source": "ticket-4471",
})
store.put(namespace, "mem-2", {
    "text": "Customer prefers email, asked not to be called by phone",
    "source": "ticket-4471",
})
store.put(namespace, "mem-3", {
    "text": "Uses a custom build of the SDK pinned to version 2.14",
    "source": "ticket-4502",
})
```

## Ingat dengan makna
<a name="langgraph-memory-recall"></a>

Pelanggan membuka percakapan baru dan mengatakan koneksi mereka terus putus setelah sekitar satu menit:

```
results = store.search(
    namespace,
    query="connection drops after a minute of inactivity",
    limit=3,
)

for item in results:
    print(round(item.score, 3), item.value["text"])
```

Output:

```
0.324 Account runs a proxy that closes idle sockets after 60 seconds
0.039 Customer prefers email, asked not to be called by phone
0.031 Uses a custom build of the SDK pinned to version 2.14
```

Memori yang relevan menempati urutan pertama, dan tidak ada kunci dalam kueri yang cocok dengan apa pun. `SearchItem.score`mengikuti LangGraph konvensi di mana yang lebih tinggi lebih relevan. DynamoDB mengembalikan jarak, di mana yang lebih rendah lebih dekat, sehingga toko mengonversi: untuk `COSINE` skor adalah`1 - distance`, karena `EUCLIDEAN` itu`1 / (1 + distance)`, dan `DOT_PRODUCT` skor melewati tidak berubah. Jika Anda memasukkan skor absolut untuk memutuskan apakah memori cukup relevan untuk disuntikkan ke dalam prompt, kalibrasi ambang batas itu terhadap data Anda sendiri dan fungsi jarak yang Anda pilih.

## Memori lingkup dengan skema pencarian
<a name="langgraph-memory-scoping"></a>

Ketika `DynamoDBStore` membuat indeks vektor, ia mendeklarasikan kunci partisi tabel sebagai `HASH` elemen dalam skema pencarian indeks. Karena elemen itu ada, setiap pencarian harus menyediakan kondisi untuknya, dan toko menyediakan namespace: tuple namespace bergabung untuk membentuk nilai kunci partisi, sehingga setiap pencarian semantik disematkan tepat ke satu namespace. Tiga konsekuensi berikut:
+ **Isolasi bersifat struktural, bukan filter yang Anda ingat untuk menulis. ** Pencarian tidak dapat mencapai memori di namespace yang berbeda, sehingga toko yang melayani banyak penyewa tidak memiliki bentuk kueri yang mengembalikan memori penyewa lain. Ini adalah pelingkupan kueri daripada otorisasi: kepala sekolah dengan `dynamodb:SearchVectors` izin di tabel dapat mencari nilai namespace apa pun secara langsung, jadi memutuskan ruang nama mana yang dapat dibaca pemanggil masih milik IAM dan lapisan otorisasi aplikasi Anda.
+ **Biaya mengingat melacak memori satu pengguna, bukan seluruh tabel Anda. ** Pekerjaan pencarian dibatasi oleh seberapa banyak yang dimiliki satu namespace, bukan oleh berapa banyak memori yang dimiliki seluruh produk Anda, yang membuat latensi dan biaya pencarian vektor tetap kecil dan stabil saat Anda tumbuh.
+ **Pencarian semantik adalah namespace yang tepat, bukan awalan. ** Pencarian mencapai persis namespace yang Anda lewati dan tidak ada di bawahnya. Pencarian `("memories", "acme-corp")` tidak mencapai`("memories", "acme-corp", "user-8812")`, karena itu adalah nilai kunci partisi yang berbeda. Namespace Anda adalah cakupan penarikan Anda, jadi pilihlah agar sesuai dengan cakupan yang Anda ingin melihat satu pencarian.

Tabel berikut merangkum cara memilih bentuk namespace.


| Bentuk namespace | Satu `search()` mencapai | Pilihlah kapan | 
| --- | --- | --- | 
| `("memories", user_id)` | Kenangan pengguna itu | Single-tenant produk dengan penarikan per pengguna | 
| `("memories", tenant_id, user_id)` | Pengguna itu, di penyewa itu | Multi-tenant, kasus umum | 
| `("memories", tenant_id, user_id, agent_name)` | Catatan satu agen tentang pengguna itu | Beberapa agen khusus yang seharusnya tidak membaca catatan satu sama lain | 
| `("account_facts", tenant_id)` | Tenant-wide pengetahuan | Fakta yang berlaku untuk setiap pengguna di akun | 

Hindari menempatkan setiap memori dalam satu namespace dan memfilter metadata: filter diterapkan setelah DynamoDB telah memilih kecocokan terdekat di seluruh namespace, dan satu pencarian mengembalikan paling banyak 100 kecocokan teratas, jadi setelah satu penyewa sibuk mengisi 100 teratas untuk kueri umum, pencarian penyewa yang lebih tenang mengembalikan hasil yang lebih sedikit daripada yang diminta meskipun memori mereka ada. Lebih suka pelingkupan namespace daripada filter untuk apa pun yang menentukan kebenaran. Lebih baik daripada batas ingatan Anda juga merupakan desain yang sah: agen yang membutuhkan konteks khusus pengguna dan seluruh akun mencari ruang nama dan menggabungkan hasilnya.

## Pertimbangan-pertimbangan
<a name="langgraph-memory-considerations"></a>
+ Indeks akhirnya konsisten, model yang sama dengan indeks sekunder global. A yang `search()` dikeluarkan segera setelah a `put()` mungkin belum menyertakan memori baru. Untuk agen yang menulis memori dan kemudian mengingatnya dalam giliran yang sama, bacalah kembali dengan kunci sebagai gantinya.
+ Satu pencarian mengembalikan paling banyak 100 pertandingan teratas. Permintaan yang nil `limit` ainya `offset` melebihi itu ditolak dengan kesalahan yang jelas daripada diam-diam tidak mengembalikan apa pun di luar batas.
+ Jika Anda menggunakan Time to Live untuk mengakhiri memori basi dan mengaktifkan penyegaran saat dibaca, memori yang sebenarnya diingat agen akan mengalami kedaluwarsa didorong keluar, sehingga memori yang digunakan secara aktif bukanlah yang menghilang secara diam-diam.
+ Kegagalan pencarian vektor meningkat sehingga aplikasi Anda dapat bereaksi. Throttle, masalah izin, dan hasil yang benar-benar kosong akan terlihat identik jika toko mengembalikan daftar kosong saat gagal.
+ Operasi vektor menagih dalam unitnya sendiri, diukur secara terpisah dari unit permintaan baca dan tulis tabel dasar, dan keduanya menskalakan dengan jumlah dimensi. Dimensi embedding yang lebih kecil lebih murah pada setiap penulisan dan setiap pencarian, jadi gunakan dimensi terkecil yang mempertahankan kualitas ingatan Anda.
+ Memori yang ditulis tanpa teks dalam konfigurasi `fields` disimpan tanpa penyematan dan tidak akan muncul dalam hasil semantik. Toko mencatat peringatan ketika ini terjadi.

## Sumber daya tambahan
<a name="langgraph-memory-resources"></a>
+ [Dokumentasi DynamoDBStore pada GitHub ](https://github.com/langchain-ai/langchain-aws/blob/main/libs/langgraph-checkpoint-aws/langgraph_checkpoint_aws/store/dynamodb/DynamoDBStore.md)
+ [langgraph-checkpoint-aws di PyPI ](https://pypi.org/project/langgraph-checkpoint-aws/)
+ [Dokumentasi LangGraph](https://langchain-ai.github.io/langgraph/)