sepdek July 14, 2025
Illustration of heritage evidence history and expert review behind a stone architectural fragment.

An assistant can produce a fluent explanation of a sensor reading without knowing whether that reading is new, whether the same situation occurred last winter, or whether a proposed intervention was actually carried out. For conservation work, those omissions are not details. They are part of the decision.

A useful agent therefore needs an evidence history that can be inspected independently of the text it generates.

Research context

My paper Agentic AI for Cultural Heritage: Embedding Risk Memory in Semantic Digital Twins was published in Computers 14(7), 266, on 7 July 2025. It connects semantic digital twins, risk trajectories and policy-aware decision support. The official ARGUS account describes its relationship to the ICCROM/CCI ABC framework and explicitly identifies simulated preservation scenarios. The ledger below is a separate teaching example; it neither implements an ABC assessment nor demonstrates a deployed autonomous conservation agent.

Store events before writing a narrative

Consider four fictional records: an environmental excursion, a proposed inspection, approval of the inspection, and an inspection report. A sentence saying “the issue was addressed” collapses these into an outcome that the record may not support.

Event What it establishes What it does not establish
Observation recorded A value or event was captured Its cause or material consequence
Inspection proposed Someone recommended an action Approval or execution
Inspection approved The action was authorized That it happened
Inspection completed An inspection report exists That deterioration was prevented

The distinction lets an agent answer a narrower, better question: “Which approved actions still lack an execution record?” That question can be answered from structured data without asking a language model to infer missing history.

A minimal event record

Each record should have a stable identity, a timestamp, an asset reference, an event type and links to its evidence. If an assessment changes, add the revised assessment and its provenance. Do not erase the original observation merely because a later explanation is preferred.

events = [
    {"id": "e1", "kind": "observation", "asset": "wall-1"},
    {"id": "e2", "kind": "proposal", "action": "inspect-1",
     "evidence": ["e1"]},
    {"id": "e3", "kind": "approval", "action": "inspect-1",
     "evidence": ["e2"]}
]
approved = {e["action"] for e in events if e["kind"] == "approval"}
completed = {e["action"] for e in events if e["kind"] == "completion"}
print(sorted(approved - completed))  # ['inspect-1']

This code is intentionally small. A production record would also identify the actor, event time versus entry time, authorization scope and applicable policy. Those fields should not be replaced by an unstructured conversation transcript.

Risk memory is not a list of alarming numbers

A preservation risk combines assumptions about a mechanism, exposure, consequences and the value affected. Two assessments with the same final score may arise from different assumptions. Retaining the underlying evidence and model version makes their difference explainable.

For that reason, the example does not add arbitrary “frequency,” “damage” and “extent” percentages and call the result an ABC magnitude. A real implementation must follow the definitions and scales of the chosen method and preserve their interpretation. A dashboard number is not meaningful merely because it is easy to plot.

Give the language model a bounded role

A language model can help summarize records or explain why an action is pending. Its output should link to the records supporting the explanation. The authority to approve an intervention belongs in a separate workflow, with explicit roles and an execution record.

For a question such as “Why was this inspection requested?”, the system should retrieve the proposal and its evidence, identify gaps, and produce a traceable explanation. If the evidence says only that humidity was elevated, the explanation should not introduce a crack, a diagnosis or a completed treatment.

Test the failure cases

Before testing eloquence, I would test whether the system keeps a proposal distinct from an approval, recognizes conflicting assessments, handles a missing observation, and distinguishes a simulated policy scenario from a documented field result. I would also test whether a corrected record is reflected in later summaries.

The companion example checks that an approved but incomplete action remains pending and that adding a completion record resolves only that action. These are small workflow guarantees. They are a useful foundation for more ambitious reasoning because they can be checked without trusting a generated narrative.

Complete reproducible example

This standalone example uses fictional data or prescribed mathematical objects; it is not a reproduction of the source paper’s experiments.

"""Fictional workflow, not an ABC score or conservation recommendation."""
import json

events=[
 {"id":"e1","kind":"observation","asset":"wall-1"},
 {"id":"e2","kind":"proposal","action":"inspect-1","evidence":["e1"]},
 {"id":"e3","kind":"approval","action":"inspect-1","evidence":["e2"]}
]
def pending(records):
    approved={e["action"] for e in records if e["kind"]=="approval"}
    completed={e["action"] for e in records if e["kind"]=="completion"}
    return sorted(approved-completed)
assert pending(events)==["inspect-1"]
events.append({"id":"e4","kind":"completion","action":"inspect-1","evidence":["e3"]})
assert pending(events)==[]
ids={e["id"] for e in events}
assert all(ref in ids for e in events for ref in e.get("evidence",[]))
print(json.dumps({"events":events,"pending_after_completion":pending(events)},indent=2))

Discussion

comments