AI Engineering Academy · Pelajaran

Memori Dikongsi dan Komunikasi Antara Ejen

Laksanakan lapisan memori dikongsi menggunakan stor nilai-kunci yang dibaca dan ditulis oleh ejen, bagi membolehkan kerjasama tak segerak tanpa gandingan ketat antara ejen.

Pelajaran 4 daripada 413 langkah

Memori Dikongsi dan Komunikasi Antara Ejen ialah pelajaran AI Engineering Academy percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran AI Engineering Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus AI Engineering Academy merangkumi sejumlah 4 pelajaran.

Masalah Pengasingan Ejen

Dalam sistem berbilang ejen, setiap ejen berjalan dalam konteksnya sendiri dan tidak mengetahui perkara yang sedang atau telah dilakukan oleh ejen lain. Jika ejen penyelidik menemui fakta penting, bagaimanakah ejen penulis mengetahuinya? Bagaimanakah ejen pemantau mengetahui apabila ejen pengatur cara menghadapi ralat? Tanpa mekanisme komunikasi dikongsi, ejen menjadi silo terpencil yang tidak dapat bekerjasama dengan berkesan.

Memori Dikongsi: Model Blackboard

Penyelesaian klasik untuk komunikasi berbilang ejen ialah model blackboard: stor data dikongsi (blackboard) yang boleh dibaca atau ditulis oleh mana-mana ejen. Ejen menyiarkan penemuan mereka, membaca sumbangan ejen lain dan menyelaras secara tersirat melalui keadaan dikongsi. Model ini menyahgandingkan ejen — mereka tidak perlu mengetahui kewujudan satu sama lain, sebaliknya hanya perlu mengetahui struktur memori dikongsi.

# Simple in-memory blackboard using a dictionary
from threading import Lock

class Blackboard:
    def __init__(self):
        self._data = {}
        self._lock = Lock()  # thread-safe for parallel agents

    def write(self, key: str, value, agent_id: str):
        with self._lock:
            self._data[key] = {'value': value, 'written_by': agent_id}
            print(f'[{agent_id}] wrote: {key}')

    def read(self, key: str):
        with self._lock:
            return self._data.get(key, {}).get('value')

    def keys(self):
        with self._lock:
            return list(self._data.keys())

blackboard = Blackboard()

Memori Dikongsi Berterusan dengan Redis

Untuk sistem berbilang ejen dalam persekitaran pengeluaran yang ejen-ejennya berjalan sebagai proses atau perkhidmatan berasingan, kamus dalam memori tidak mencukupi. Redis ialah pilihan paling popular untuk memori ejen dikongsi: ia pantas, menyokong jenis data yang pelbagai (rentetan, cincangan, senarai dan set tersusun), mempunyai TTL terbina dalam untuk luput serta mengendalikan bacaan dan tulisan serentak dengan selamat menggunakan operasi atomik.

import redis
import json

class RedisSharedMemory:
    def __init__(self, prefix='agent:'):
        self.redis = redis.Redis(host='localhost', port=6379, decode_responses=True)
        self.prefix = prefix

    def set(self, key: str, value, ttl_seconds=3600):
        full_key = self.prefix + key
        self.redis.setex(full_key, ttl_seconds, json.dumps(value))

    def get(self, key: str):
        full_key = self.prefix + key
        raw = self.redis.get(full_key)
        return json.loads(raw) if raw else None

    def append_to_list(self, key: str, item):
        full_key = self.prefix + key
        self.redis.rpush(full_key, json.dumps(item))

    def get_list(self, key: str):
        full_key = self.prefix + key
        return [json.loads(x) for x in self.redis.lrange(full_key, 0, -1)]

memory = RedisSharedMemory(prefix='research_project:')

Menamakan Ruang Memori Dikongsi

Dalam sistem berbilang ejen yang kompleks, ejen menulis banyak jenis data yang berbeza dan ruang nama kunci rata dengan cepat menjadi tidak teratur. Gunakan penamaan ruang hierarki untuk menyusun memori dikongsi dengan jelas. Corak lazim ialah project_id:agent_role:data_type, contohnya proj_123:researcher:findings atau proj_123:coder:error_log. Ini memudahkan anda menyoal semua data bagi sesuatu projek atau semua output daripada ejen tertentu.

class NamespacedMemory:
    def __init__(self, project_id: str, agent_id: str, redis_client):
        self.base = f'{project_id}:{agent_id}'
        self.redis = redis_client

    def write_finding(self, topic: str, content: str):
        key = f'{self.base}:findings:{topic}'
        self.redis.set(key, content)

    def read_all_findings(self, project_id: str):
        # Read findings from ALL agents in this project
        pattern = f'{project_id}:*:findings:*'
        keys = self.redis.keys(pattern)
        return {k: self.redis.get(k) for k in keys}

# Usage
researcher_memory = NamespacedMemory('proj_123', 'researcher', redis_client)
researcher_memory.write_finding('competitors', 'OpenAI, Anthropic, Google...')

writer_memory = NamespacedMemory('proj_123', 'writer', redis_client)
all_findings = writer_memory.read_all_findings('proj_123')

Memori Berstruktur berbanding Tidak Berstruktur

Kandungan memori dikongsi boleh berupa tidak berstruktur (gumpalan teks mentah yang akan dibaca oleh LLM) atau berstruktur (objek JSON/Python dengan medan bertip). Memori berstruktur lebih baik kerana membolehkan pertanyaan terprogram, pengesahan dan penggabungan. Sentiasa tentukan skema bagi perkara yang ditulis oleh setiap ejen ke memori dikongsi, dokumentasikannya dan sahkan tulisan mengikut skema tersebut untuk mengelakkan ejen yang bermasalah daripada merosakkan stor memori.

from pydantic import BaseModel
from typing import Optional, list
from datetime import datetime

class ResearchFinding(BaseModel):
    topic: str
    summary: str
    sources: list[str]
    confidence: float  # 0.0 to 1.0
    written_by: str
    timestamp: datetime

# Validated write - bad data is caught before it enters shared memory
def write_finding(memory, finding_dict: dict):
    finding = ResearchFinding(**finding_dict)  # validates on creation
    memory.set(f'findings:{finding.topic}', finding.model_dump())
    print(f'Validated finding written for topic: {finding.topic}')

Komunikasi Dipacu Peristiwa dengan Pub/Sub

Daripada meninjau memori dikongsi secara berkala untuk menyemak kemas kini, ejen boleh menggunakan komunikasi terbitan/langganan (pub/sub) untuk memberitahu ejen lain apabila mereka selesai melaksanakan tugas. Ejen A menerbitkan peristiwa ('research_complete'), lalu Ejen B yang melanggan peristiwa tersebut diaktifkan dan mula memproses. Redis pub/sub dan baris gilir mesej seperti RabbitMQ atau Kafka menyokong corak ini.

import redis

# Publisher (researcher agent)
def researcher_agent(topic, redis_client):
    findings = do_research(topic)
    redis_client.set(f'findings:{topic}', findings)
    
    # Notify all subscribers that research is done
    redis_client.publish('agent_events', f'research_complete:{topic}')
    print(f'Research complete, published event for topic: {topic}')

# Subscriber (writer agent) - runs in separate process
def writer_agent_listener(redis_client):
    pubsub = redis_client.pubsub()
    pubsub.subscribe('agent_events')
    
    for message in pubsub.listen():
        if message['type'] == 'message':
            event = message['data']
            if event.startswith('research_complete:'):
                topic = event.split(':')[1]
                findings = redis_client.get(f'findings:{topic}')
                write_draft(findings)  # start writing immediately

Memori Dikongsi dalam LangGraph

Dalam LangGraph, memori dikongsi antara ejen ialah objek keadaan graf itu sendiri. Setiap nod membaca daripada dan menulis kepada kamus keadaan bertype yang sama. LangGraph mengendalikan penyelarasan bacaan dan tulisan secara automatik. Untuk senario yang lebih kompleks, anda juga boleh menyuntik klien memori luaran (Redis, pangkalan data) ke dalam setiap fungsi nod melalui suntikan kebergantungan.

from langgraph.graph import StateGraph
from typing import TypedDict

class SharedState(TypedDict):
    # All shared data lives here - every node can read any field
    query: str
    research_findings: str   # written by researcher, read by writer
    written_draft: str       # written by writer, read by reviewer
    review_notes: str        # written by reviewer, read by writer (loop)
    final_output: str        # written by synthesizer

# Researcher writes to 'research_findings'
def researcher(state: SharedState) -> dict:
    findings = search_and_summarize(state['query'])
    return {'research_findings': findings}  # partial state update

# Writer reads 'research_findings', writes 'written_draft'
def writer(state: SharedState) -> dict:
    draft = write_from_findings(state['research_findings'])  # reads researcher output
    return {'written_draft': draft}

Konflik dan Konsistensi Memori

Apabila berbilang ejen menulis kepada memori dikongsi secara serentak, konflik tulisan boleh berlaku. Dua ejen mungkin menindih kerja satu sama lain atau membaca data lapuk antara operasi membaca dan menulis. Tangani keadaan ini dengan: penguncian optimistik (semak versi sebelum menulis), operasi banding-dan-tukar atom dalam Redis, atau mensiri tulisan melalui ejen penyelaras yang menjadi satu-satunya penulis kepada medan memori kritikal.

# Optimistic locking with Redis
def safe_write(redis_client, key, new_value, expected_version):
    with redis_client.pipeline() as pipe:
        try:
            pipe.watch(key + ':version')  # watch for concurrent modification
            current_version = int(pipe.get(key + ':version') or 0)
            
            if current_version != expected_version:
                raise ValueError(f'Version conflict: expected {expected_version}, got {current_version}')
            
            pipe.multi()  # start transaction
            pipe.set(key, new_value)
            pipe.set(key + ':version', current_version + 1)
            pipe.execute()  # atomic commit
            print('Write successful')
        except redis.WatchError:
            print('Conflict detected, retry write')

TTL dan Pembersihan Memori

Memori ejen yang dikongsi terkumpul dari semasa ke semasa dan boleh berkembang tanpa had jika tidak diuruskan. Sentiasa tetapkan masa hidup (TTL) pada entri memori supaya entri tersebut luput secara automatik. Untuk memori berskop projek, bersihkan semua entri apabila projek selesai. Gunakan nilai TTL yang sepadan dengan tempoh jangkaan aliran kerja: TTL pendek (beberapa minit) untuk data sementara, dan TTL lebih panjang (beberapa jam hingga beberapa hari) untuk hasil yang mungkin digunakan semula.

def cleanup_project_memory(redis_client, project_id: str):
    pattern = f'{project_id}:*'
    keys = redis_client.keys(pattern)
    if keys:
        redis_client.delete(*keys)
        print(f'Cleaned up {len(keys)} memory entries for project {project_id}')

# Set TTL when writing
def write_with_ttl(redis_client, key, value, ttl_hours=2):
    redis_client.setex(
        key,
        ttl_hours * 3600,  # convert to seconds
        json.dumps(value)
    )

# Register cleanup callback when workflow completes
def on_workflow_complete(project_id):
    cleanup_project_memory(redis_client, project_id)
    print(f'Workflow {project_id} complete, memory cleaned up')

Memori sebagai Sejarah Ejen

Memori dikongsi juga boleh menyimpan sejarah tindakan ejen, bukan hanya hasilnya. Merekod ejen yang melakukan sesuatu, masa tindakan itu dilakukan dan sebabnya akan menghasilkan jejak audit yang amat berguna untuk menyahpepijat kegagalan, memahami cara hasil akhir dihasilkan dan menyambung semula aliran kerja yang terganggu. Log tindakan ini ialah padanan berasaskan memori kepada penjejakan LangSmith.

import time
from dataclasses import dataclass

@dataclass
class AgentAction:
    agent_id: str
    action_type: str     # 'research', 'write', 'review', 'tool_call'
    input_summary: str
    output_summary: str
    timestamp: float
    success: bool

def log_action(memory, action: AgentAction):
    key = f'action_log:{action.agent_id}:{action.timestamp}'
    memory.set(key, vars(action))

# Usage in an agent
def researcher_with_logging(state, memory):
    start = time.time()
    findings = do_research(state['query'])
    log_action(memory, AgentAction(
        agent_id='researcher',
        action_type='research',
        input_summary=state['query'][:100],
        output_summary=findings[:100],
        timestamp=start,
        success=True
    ))
    return findings

Memilih Seni Bina Memori

Seni bina memori dikongsi yang sesuai bergantung pada model penggunaan anda. Untuk aliran kerja LangGraph satu proses, keadaan graf sudah memadai. Untuk ejen berbilang proses atau teragih, gunakan Redis. Untuk projek berjangka panjang yang memerlukan ketahanan merentas mula semula, gunakan pangkalan data hubungan dengan pengindeksan yang betul. Untuk penyelarasan dipacu peristiwa antara perkhidmatan, tambahkan pub/sub di atas apa-apa storan yang anda pilih.

Semakan Pantas

Uji pemahaman anda tentang memori dikongsi dan komunikasi antara ejen daripada pelajaran ini.

Imbas Kembali Pelajaran

Dalam pelajaran ini, anda telah mempelajari bahawa: model papan hitam menggunakan stor data dikongsi yang membolehkan mana-mana ejen membaca dan menulis, sekali gus membolehkan penyelarasan tersirat tanpa gandingan langsung antara ejen, Redis ialah pilihan utama untuk memori dikongsi berterusan dalam sistem berbilang ejen teragih, dan pub/sub membolehkan komunikasi dipacu peristiwa supaya ejen bertindak balas serta-merta apabila kebergantungan selesai. Seterusnya, kita akan meneroka gelung pelaksanaan kod untuk tugasan ejen.

Percuma untuk bermula

Pelajari Python dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
30
Pelajaran
120

Soalan Lazim

Adakah pelajaran “Memori Dikongsi dan Komunikasi Antara Ejen” percuma?

Ya — teks penuh “Memori Dikongsi dan Komunikasi Antara Ejen” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus AI Engineering Academy, tingkat taraf kepada CoddyKit PRO. Kursus AI Engineering Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Memori Dikongsi dan Komunikasi Antara Ejen”?

Laksanakan lapisan memori dikongsi menggunakan stor nilai-kunci yang dibaca dan ditulis oleh ejen, bagi membolehkan kerjasama tak segerak tanpa gandingan ketat antara ejen. Anda berlatih AI Engineering Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan AI Engineering Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran AI Engineering Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.

Berapa lamakah pelajaran “Memori Dikongsi dan Komunikasi Antara Ejen” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran AI Engineering Academy ini?

Ya. Setiap pelajaran AI Engineering Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Mengapa Ejen Tunggal Terbatas
  2. Corak Penyusun-Ejen Sampingan
  3. Membina Saluran Paip Berbilang Ejen dengan LangGraph
  4. Memori Dikongsi dan Komunikasi Antara Ejen
← Kembali ke AI Engineering Academy