Strona główna / Artykuły / Uwagi praktyczne: Architektury agentowe — Artykuł 12: Czy jesteśmy gotowi na

Uwagi praktyczne: Architektury agentowe — Artykuł 12: Czy jesteśmy gotowi na

Praktyczne wskazówki: Architektury agentowe — Artykuł 12: Czy jesteśmy gotowi na umowy, sprawdzania oraz miejsca na kod do wklejenia dla zespołów implementujących ten wzorzec.

2821 słów

Poniższe notatki przedstawiają praktyczny plan działania dotyczący tematu „Architektury agentowe — Artykuł 12: Czy jesteśmy gotowi na system pamięci typu agent-native?”. Nacisk kładziony jest na umowy, sprawdzania oraz miejsca zastępcze dla kodu, a nie na motywacyjne aspekty. Podczas przechodzenia przez etap przeglądu najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno prawidłowy przebieg działania, jak i ścieżkę naprawczą. Próby ponowne, kontrola przez człowieka oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później.

Co tutaj znajdziesz

Etap „To, co znajdziesz” funkcjonuje najlepiej, gdy traktowany jest jako mierzalna powierzchnia. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwanie kontynuacji po przerwach.

Problem pamięci agenta, sformułowany dokładnie

Etap Problemu Pamięci Agenta funkcjonuje najlepiej, gdy traktowany jest jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę o cofnięciu działań, zanim rozszerzysz zakres. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Utrzymuj stan grafu w prostej formie i określonej typowości. Wkładki nawiasowe ukrywają informację o tym, który węzeł zapisał dane w danym polu, co powoduje przerwanie kontynuacji po przerwach.

+------------------------+-----------------------------+-------------------------+
| Human Memory Type      | Article 7 Implementation    | How It Is Accessed      |
+------------------------+-----------------------------+-------------------------+
| Working memory         | LangGraph state             | Always present in ctx   |
| (active context)       | MemorySaver checkpoints     |                         |
+------------------------+-----------------------------+-------------------------+
| Episodic memory        | DynamoDB + embeddings       | Semantic similarity     |
| (what happened before) | TTL 90 days                 | query at run start      |
+------------------------+-----------------------------+-------------------------+
| Semantic memory        | Bedrock Knowledge Base      | Vector search query     |
| (domain knowledge)     | S3-backed JSONL             | at run start            |
+------------------------+-----------------------------+-------------------------+
| Procedural memory      | DynamoDB validated table    | Task type lookup        |
| (how to do things)     | Success rate tracking       | at run start            |
+------------------------+-----------------------------+-------------------------+

Luka 1: Świadomość czasowa

Faza Gap 1 Temporal Awareness funkcjonuje najlepiej, gdy jest traktowana jako mierzalna powierzchnia. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Zapisuj czasy wykonywania operacji oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z wersji demonstracyjnej do środowisk współdzielonych. Utrzymuj stan grafu w formie prostych, spójnych struktur. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane w danym polu, i powodują przerwę w kontynuacji działania po zakłóceniach. Faza Gap 1 Temporal Awareness funkcjonuje najlepiej, gdy jest traktowana jako mierzalna powierzchnia. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Dokumentuj zarówno pomyślną ścieżkę działania, jak i ścieżkę przywracania do normalnego stanu. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później.

+----------------------------------+------------------------------------------+
| Temporal Property                | What It Enables                          |
+----------------------------------+------------------------------------------+
| Creation timestamp               | Basic recency weighting in retrieval     |
+----------------------------------+------------------------------------------+
| Last confirmed timestamp         | Distinguish stale from fresh knowledge   |
+----------------------------------+------------------------------------------+
| Confidence decay function        | Facts become less certain over time      |
|                                  | without confirmation                     |
+----------------------------------+------------------------------------------+
| Version history                  | Track how understanding of a topic       |
|                                  | has evolved across runs                  |
+----------------------------------+------------------------------------------+
| Temporal context at retrieval    | "What did I know about X on this date?"  |
|                                  | not just "What do I know about X now?"   |
+----------------------------------+------------------------------------------+
# harness/memory/temporal.py
import time
from typing import List
def apply_temporal_weighting(
    retrieved_facts: List[dict],
    recency_half_life_days: float = 30.0,
) -> List[dict]:
    """
    Weights retrieved facts by recency using exponential decay.
    Facts confirmed recently score higher than stale ones with
    the same semantic similarity.
    """
    now = time.time()
    half_life_seconds = recency_half_life_days * 86400
    for fact in retrieved_facts:
        base_score = fact.get("similarity_score", 0.8)
        last_confirmed = fact.get("last_confirmed_at", fact.get("created_at", now))
        age_seconds = now - last_confirmed
        # Exponential decay: score halves every half_life_days
        import math
        decay_factor = math.exp(-0.693 * age_seconds / half_life_seconds)
        fact["temporal_weighted_score"] = base_score * decay_factor
    return sorted(retrieved_facts, key=lambda f: f["temporal_weighted_score"], reverse=True)

Gap 2: Asocjacyjne wyszukiwanie

W fazie asocjatywnego wyszukiwania Gap 2 należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, łatwe do przetestowania jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, powód awarii powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Należy podawać fragmenty tekstu, które faktycznie stanowią podstawę odpowiedzi. Bez tych odniesień operatorzy nie będą w stanie odróżnić halucynacji od luki w indeksowaniu.

# harness/memory/associative.py
import boto3
from typing import List, Optional
class AssociativeMemoryIndex:
    """
    Maintains an association graph between memory entities.
    Complements vector search with relationship-based retrieval.
    This is a simplified implementation. Production would use
    Amazon Neptune or a graph database for complex traversals.
    """
    def __init__(
        self,
        table_name: str = "agent-memory-associations",
        region: str = "us-east-1",
    ):
        dynamodb = boto3.resource("dynamodb", region_name=region)
        self.table = dynamodb.Table(table_name)
    def record_association(
        self,
        entity_a: str,
        entity_b: str,
        relationship: str,
        strength: float = 1.0,
        run_id: str = None,
    ):
        """
        Records that two memory entities are related.
        entity_a, entity_b: fact_ids, episode_ids, or concept labels
        relationship: "co-occurred", "caused", "contradicts", "supports"
        strength: 0.0 to 1.0, increases with repeated co-occurrence
        """
        import time
        self.table.update_item(
            Key={"entity_a": entity_a, "entity_b": entity_b},
            UpdateExpression=(
                "SET relationship = :r, "
                "strength = if_not_exists(strength, :z) + :s, "
                "occurrence_count = if_not_exists(occurrence_count, :z) + :one, "
                "last_seen = :now"
            ),
            ExpressionAttributeValues={
                ":r": relationship,
                ":z": 0,
                ":s": strength,
                ":one": 1,
                ":now": int(time.time()),
            }
        )
    def get_associated_entities(
        self,
        entity: str,
        min_strength: float = 0.5,
        max_results: int = 10,
    ) -> List[dict]:
        """Retrieves entities associated with the given entity."""
        response = self.table.query(
            KeyConditionExpression="entity_a = :e",
            FilterExpression="strength >= :s",
            ExpressionAttributeValues={":e": entity, ":s": min_strength},
        )
        items = sorted(
            response.get("Items", []),
            key=lambda x: x.get("strength", 0),
            reverse=True
        )
        return items[:max_results]

Gap 3: Inteligencja ścieżki zapisu

W fazie Gap 3 Write-Path Intelligence należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć przypadkowe, częściowe ukończenie zadań. Konieczna jest ludzka akceptacja w przypadkach, gdy dochodzi do wydawania pieniędzy lub modyfikacji danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się pełnej kompletności procesu biznesowego.

# harness/memory/annotation.py
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_aws import ChatBedrock
import boto3
import json

MEMORY_ANNOTATION_PROMPT = """
You have just completed a reasoning step. Before continuing, consider:
1. Did you discover something that would be useful in future runs on similar tasks?
2. Did you encounter a pattern you had not seen before?
3. Did something fail that you want to remember to avoid next time?
If yes to any of these, describe what you want to remember in one or two sentences.
If no, respond with null.
Respond with JSON:
{"worth_remembering": true | false, "annotation": "description or null"}
"""

class InlineMemoryAnnotator:
    """
    Runs between agent reasoning steps and asks the agent to flag
    anything worth remembering before the run ends.
    This is experimental. The risk is that the agent annotates
    incorrect conclusions. Pair with the validation gate from Article 7.
    """
    def __init__(self, region: str = "us-east-1"):
        bedrock = boto3.client("bedrock-runtime", region_name=region)
        self.model = ChatBedrock(
            client=bedrock,
            model_id="anthropic.claude-haiku-4-5",
            model_kwargs={"temperature": 0, "max_tokens": 256},
        )
        self._annotations: list = []
    def maybe_annotate(self, last_reasoning_step: str) -> bool:
        """
        Called after each significant reasoning step.
        Returns True if an annotation was recorded.
        """
        response = self.model.invoke([
            SystemMessage(content=MEMORY_ANNOTATION_PROMPT),
            HumanMessage(content=f"Recent reasoning:\n{last_reasoning_step[:1000]}")
        ])
        try:
            result = json.loads(response.content)
            if result.get("worth_remembering") and result.get("annotation"):
                self._annotations.append(result["annotation"])
                return True
        except json.JSONDecodeError:
            pass
        return False
    def get_annotations(self) -> list:
        return list(self._annotations)

Gap 4: Pamięć między agentami z izolacją

Dla etapu Pamięci Międzyagentowej w ramach Gap 4 należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Zapisuj czas trwania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Wprowadź zatwierdzenie przez człowieka dla operacji, które generują wydatki lub zmieniają dane produkcyjne. Połączenia realizowane w czasie kompilacji nie równają się pełnej kompletności rozwiązania biznesowego. Dla etapu Pamięci Międzyagentowej w ramach Gap 4 należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później.

# harness/memory/shared_memory.py
import boto3
from typing import List, Optional

class SharedMemoryPolicy:
    """
    Controls which agent types can read and write which memory namespaces.
    Sharing is opt-in. Default is isolated per agent_id.
    """
    def __init__(self, policies: dict):
        """
        policies example:
        {
          "security_findings": {
            "readers": ["supervisor", "security_reviewer", "code_analyst"],
            "writers": ["security_reviewer"],
          },
          "code_patterns": {
            "readers": ["supervisor", "code_analyst"],
            "writers": ["code_analyst"],
          }
        }
        """
        self.policies = policies
    def can_read(self, agent_id: str, namespace: str) -> bool:
        policy = self.policies.get(namespace, {})
        return agent_id in policy.get("readers", [])
    def can_write(self, agent_id: str, namespace: str) -> bool:
        policy = self.policies.get(namespace, {})
        return agent_id in policy.get("writers", [])
    def filter_retrievable(
        self,
        agent_id: str,
        records: List[dict],
    ) -> List[dict]:
        """
        Filters a list of memory records to only those the agent can read.
        """
        return [
            r for r in records
            if self.can_read(agent_id, r.get("namespace", "private"))
            or r.get("agent_id") == agent_id  # always read own memories
        ]

Luka 5: Zapominanie jako operacja pierwszej klasy

Gdy przechodzisz przez etap „Zapominanie” w ramach Luki 5, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Ustalaj punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.

# harness/memory/intelligent_forgetting.py
import boto3
import time
from typing import List

class IntelligentForgettingManager:
    """
    Manages memory removal based on content-aware signals,
    not just age. Complements the TTL-based decay from Article 7.
    """
    def __init__(
        self,
        episodic_table: str = "agent-episodic-memory",
        semantic_kb_id: str = None,
        region: str = "us-east-1",
    ):
        dynamodb = boto3.resource("dynamodb", region_name=region)
        self.episodic_table = dynamodb.Table(episodic_table)
        self.kb_id = semantic_kb_id
        self.region = region
    def mark_contradicted(
        self,
        fact_id: str,
        contradicting_run_id: str,
        contradiction_description: str,
    ):
        """
        Marks a semantic fact as contradicted by newer evidence.
        Does not delete immediately: flags for review first.
        """
        self.episodic_table.update_item(
            Key={"fact_id": fact_id},
            UpdateExpression=(
                "SET contradicted = :t, "
                "contradicted_by = :run, "
                "contradiction_note = :note, "
                "needs_review = :t"
            ),
            ExpressionAttributeValues={
                ":t": True,
                ":run": contradicting_run_id,
                ":note": contradiction_description,
            }
        )
    def detect_contradictions(
        self,
        new_fact_content: str,
        existing_facts: List[dict],
        detector_model,
    ) -> List[str]:
        """
        Checks whether a new fact contradicts existing ones.
        Returns list of fact_ids that are contradicted.
        """
        if not existing_facts:
            return []
        from langchain_core.messages import SystemMessage, HumanMessage
        import json
        facts_text = "\n".join([
            f"[{f.get('fact_id', 'unknown')}]: {f.get('content', '')}"
            for f in existing_facts
        ])
        response = detector_model.invoke([
            SystemMessage(content="""
You are checking for contradictions between a new fact and existing facts.
A contradiction means the new fact and an existing fact cannot both be true.
Return JSON:
{"contradicted_ids": ["fact_id_1", ...]}
Return empty list if no contradictions found.
"""),
            HumanMessage(content=f"""
New fact: {new_fact_content}
Existing facts:
{facts_text}
""")
        ])
        try:
            result = json.loads(response.content)
            return result.get("contradicted_ids", [])
        except json.JSONDecodeError:
            return []

To, co buduje ekosystem

Gdy przechodzisz przez etap „Co to jest ekosystem”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć możliwość cichego, częściowego ukończenia zadania. Ustaw punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą próbę wywołania LLM, gdy operator ponawia działanie w późniejszym etapie.

Co to oznacza dla Twojej dzisiejszej pracy nad projektem

Gdy przechodzisz przez etap „Co to oznacza”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zapisz czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z wersji demonstracyjnej do środowisk współdzielonych. Ustal punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł. Gdy przechodzisz przez etap „Co to oznacza”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych wywołań, mechanizmy ludzkiej kontroli oraz obsługa wiadomości błędowych są częścią produktu, a nie elementem dodatkowej optymalizacji.

Kontrola rzeczywistości w produkcji

Etap weryfikacji rzeczywistości produkcyjnej działa najlepiej, gdy traktowany jest jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wtórne struktury ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwanie kontynuacji po przerwach.

Architektura referencyjna

Etap architektury referencyjnej funkcjonuje najlepiej, gdy traktowany jest jako mierzalna struktura. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Utrzymuj stan grafu w prostej formie i określonej strukturze typów. Wplecione elementy ukrywają informacje o tym, który węzeł zapisał dane w danym polu, co utrudnia kontynuację pracy po przerwach.

  Current State (Article 7)          Future Agent-Native System
  -----------------------            --------------------------
  Run starts                         Run starts
      |                                  |
  Retrieve episodes   <-- embedding      Query temporal memory
  Retrieve KB facts   <-- vector         Traverse association graph
  Retrieve procedures <-- exact key      Agent-selected retrieval
      |                                  |
  Agent runs                         Agent runs
      |                                  |
  End-of-run extractor               Inline annotation (agent)
  stores artifacts                   + end-of-run consolidation
      |                                  |
  DynamoDB episodes                  Temporal-aware store
  KB facts (S3/vector)               Association index
  DynamoDB procedures                Policy-gated sharing
                                     Contradiction detection
                                     Intelligent forgetting

Lista kontrolna operacyjna

W ramach etapu listy kontrolnej operacyjnej zdefiniuj dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia pracy przed dokonaniem zmian w kodzie. Operatorzy powinni móc ponownie wykonać dany krok na podstawie znanej punktacji kontrolnej, bez konieczności zgadywania ukrytego stanu systemu.

Utrzymuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny poufnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności przeglądania całego grafu.

Należy uzyskać zatwierdzenie człowieka dla procesów, które wydają pieniądze lub zmieniają dane produkcyjne. Połączenia skompilowane w czasie kompilacji nie gwarantują kompletności rozwiązania biznesowego.

Napisz krótki przewodnik: jak rotować klucze, jak opróżniać kolejki zadań, jak cofnąć ostatnią operację importu.

Zdokumentuj zarówno standardowy przebieg działania, jak i ścieżkę przywracania do stanu poprzedniego. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później.

Należy uzyskać zatwierdzenie człowieka dla procesów, które wydają pieniądze lub zmieniają dane produkcyjne. Połączenia skompilowane w czasie kompilacji nie gwarantują kompletności rozwiązania biznesowego.

Zanim wdrożysz całą architekturę, zamroź wersje oprogramowania, utwórz dokumentację stanu idealnego dla kluczowych procesów oraz potwierdź kroki konieczne do cofnięcia zmian. Środowiska współdzielone wymagają ograniczeń szybkości działania, weryfikacji uprawnień użytkowników oraz wyraźnego odpowiedzialnego za rotację kluczy. Wolisz nudną niezawodność od pomysłowych, jednorazowych demonstracji.

Uwaga dotycząca partii 8969a47a89be: unikaj przechowywania kluczy dostawcy w repozytorium, ustaw ograniczenie liczby tokenów na sesję oraz przechowuj transkrypcje obok narzędzi do oceny, aby późniejsze zmiany modeli pozostały porównywalne.

Dla etapu 0 uwagi dotyczących wzmocnienia bezpieczeństwa zdefiniuj dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Zapisuj czas trwania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom przy przechodzeniu z środowiska demonstracyjnego do współdzielonych środowisk.

Szczegóły wzmocnienia bezpieczeństwa 0/837: zmierz czas wykonywania, klasę błędu oraz zużycie tokenów dla tej uwagi, a następnie zdecyduj, czy zachować zmianę na podstawie ustalonego zestawu pytań, a nie jedynie informacji anegdotycznych.

Gdy przechodzisz przez pierwszy etap notatki dotyczącej wzmocnienia bezpieczeństwa, najpierw zapisz warunki umowy: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę przywracania stanu. Próby ponowne, kontrola przez ludzi oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później.

Szczegół 1/837 dotyczący wzmocnienia bezpieczeństwa: zmierz czas wykonywania operacji, klasę błędu oraz zużycie tokenów dla tej notatki, a następnie zdecyduj, czy zachować zmianę na podstawie ustalonego zestawu pytań, a nie opisów przypadków.

Literatura pokrewna

  • Praktyczne notatki: Architektury agencyjne — Artykuł 15: Model dojrzałości — Szczegółowy przewodnik po Praktycznych notatkach: Architektury agencyjne — Artykuł 15: Model dojrzałości: umowy, sprawdzenia oraz gotowe elementy kodu dostępne dla zespołów wdrażających ten wzorzec.