Агенты по расследованию происхождения в Neo4j и LangGraph
Агент для анализа происхождения данных в Neo4j и LangGraph, который сортирует и просматривает ребра FEEDS_INTO по каждому арендатору, проверяет гипотезы и записывает результаты аудита в MLflow.
Инциденты с данными редко начинаются с панели управления, на которой загорается красный свет. Они возникают на более ранних этапах — при вводе данных, их преобразовании и объединении, процессы которых никто не может описать в условиях стресса. Эта технологическая стек превращает цепочку операций с данными в инструмент расследования: Neo4j хранит связи типа FEEDS_INTO, LangGraph выполняет алгоритм из шести узлов (с дополнительными уточнениями), FastAPI обеспечивает доступ к данным, MLflow фиксирует результаты выполнения, а Gradio предоставляет операторам консоль управления.
Хранилище и обзор
Проект включает инфраструктуру как код, граф цепочек операций с данными, инструмент для организации расследований, HTTP-API, систему отслеживания экспериментов и простой интерфейс пользователя. Среднее время расследования составляет менее полуминуты, причем структурированные цепочки гипотез оцениваются по стандартному набору критериев для инцидентов.
Технологический стек
Terraform используется для управления облачными ресурсами, Neo4j — для отслеживания происхождения данных, LangGraph — для управления потоком выполнения, FastAPI — для создания API, MLflow — для хранения параметров, метрик и артефактов, Gradio — для улучшения пользовательского интерфейса операторов, а сеть судей — для оценки в автономном режиме.
Обзор архитектуры
Сигналы тревоги поступают на этап сортировки; алгоритмы прослеживания определяют пути предков узлов; профилирование дает общую картину состояния узлов; формируются гипотезы о причинах происходящего; выполняются проверки на безопасность; генерируются структурированные отчеты. При отсутствии идентификатора уточняются причины сбоев.
Инфраструктура как код с использованием Terraform
terraform init
terraform plan # previews 16 resources across containers, volumes, images, network
terraform apply # provisions all infrastructure
terraform destroy
Сначала разрабатывается план, затем он реализуется; результаты операций — URL-адреса графов, имена бакетов, секреты webhook-сервисов — встраиваются в конфигурацию выполнения, а не копируются из консоли в ноутбуки.
Модель данных
Клиенты, наборы данных, задания и таблицы становятся узлами; ребра FEEDS_INTO отражают направление передачи данных. Метки многоклиентской архитектуры предотвращают проникновение данных одного клиента в данные другого.
Создание графа происхождения в Neo4j
Поиск предков для определения зоны поражения:
MATCH path = (ancestor)-[:FEEDS_INTO*1..10]->(target {name: $name})
RETURN
ancestor.name AS name,
labels(ancestor)[0] AS node_type,
ancestor.layer AS layer,
ancestor.client_id AS client_id,
length(path) AS depth
ORDER BY depth ASC
Проход через граф с использованием фильтров клиентов:
MATCH path = (upstream {client_id: $client_id})-[:FEEDS_INTO*2..]->(downstream {client_id: $client_id})
MERGE (upstream)-[:UPSTREAM_OF]->(downstream)
Агент расследования — шесть узлов плюс инструменты для уточнения
TRIAGE
Классифицирует степень серьезности и выбирает узел в графе на основе данных тревоги.
TRAVERSE
Расширяет поиск вверх и вниз в пределах установленного числа шагов, соблюдая фильтры клиентов.
PROFILE
Присваивает кандидатским узлам информацию о свежести данных, объеме и характеристиках ошибок.
HYPOTHESIZE
Структурированные гипотезы с рангами:
class Hypothesis(TypedDict):
rank: int
hypothesis: str
confidence: float
verified: bool
evidence_query: str | None
class AgentState(TypedDict, total=False):
# Webhook input
run_id: str
dag_id: str
client_id: str
failed_task_id: str
exception_message: str
# TRIAGE output
error_type: str
severity: str # P1 / P2 / P3
# TRAVERSE output
lineage_chain: list[dict[str, Any]]
affected_models: list[str]
# PROFILE output
run_history: list[dict[str, Any]]
dbt_failures: list[dict[str, Any]]
# HYPOTHESIZE output
hypotheses: list[Hypothesis]
# VERIFY output
verified_cause: str
fix_suggestion: str
# REPORT output
incident_id: int | None
mlflow_run_id: str | None
# CLARIFY branch
needs_clarification: bool
clarification_msg: str
Инструменты для анализа шаблонов ошибок:
_ERROR_PATTERNS: list[tuple[re.Pattern, str]] = [
(re.compile(r"schema|column.*(not found|missing|mismatch)", re.I), "schema_change"),
(re.compile(r"not.null|null.*check|null.*value", re.I), "null_check"),
(re.compile(r"fresh|stale|sla|last.*loaded", re.I), "freshness"),
(re.compile(r"timeout|timed out|exceed.*limit|pool.*exhaust", re.I), "timeout"),
(re.compile(r"upstream.*fail|dependent.*not.*material|cannot execute", re.I), "dependency"),
]
_MART_TASKS = {"run_mart_daily_revenue", "run_mart_inventory_health"}
_INT_TASKS = {"run_int_order_fulfillment"}
def triage_node(state: AgentState) -> AgentState:
exception_msg = state.get("exception_message", "")
failed_task_id = state.get("failed_task_id", "")
error_type = _classify_error(exception_msg)
severity = _assign_severity(error_type, failed_task_id)
return {**state, "error_type": error_type, "severity": severity}
Логика узлов гипотез:
def hypothesize_node(state: AgentState) -> AgentState:
run_history = state.get("run_history", [])
total_runs = len(run_history)
failed_runs = sum(1 for r in run_history if r.get("status") == "failed")
failure_rate = failed_runs / total_runs if total_runs else 0.0
prompt = _USER_TEMPLATE.format(
max_hypotheses=settings.agent_max_hypotheses,
dag_id=state.get("dag_id", ""),
client_id=state.get("client_id", ""),
failed_task_id=state.get("failed_task_id", ""),
error_type=state.get("error_type", "unknown"),
severity=state.get("severity", "P3"),
exception_message=state.get("exception_message", ""),
lineage_chain=json.dumps(state.get("lineage_chain", []), indent=2),
affected_models=json.dumps(state.get("affected_models", []), indent=2),
dbt_failures=json.dumps(state.get("dbt_failures", [])[:10], indent=2),
total_runs=total_runs,
failed_runs=failed_runs,
failure_rate=failure_rate,
)
message = _client.messages.create(
model=settings.anthropic_model,
max_tokens=1024,
system=_SYSTEM_PROMPT,
messages=[{"role": "user", "content": prompt}],
)
raw = message.content[0].text.strip()
# Strip markdown code fences if Claude wrapped the JSON
if raw.startswith("```"):
raw = raw.split("```", 2)[1]
if raw.startswith("json"):
raw = raw[4:]
raw = raw.strip()
hypotheses: list[Hypothesis] = json.loads(raw)
for h in hypotheses:
h.setdefault("verified", False)
h.setdefault("evidence_query", None)
return {**state, "hypotheses": hypotheses}
VERIFY
Только безопасные форматы данных для чтения:
_SELECT_ONLY = re.compile(r"^\s*SELECT\b", re.I)
_CONFIDENCE_THRESHOLD = 0.55
def _is_safe_query(query: str) -> bool:
return bool(_SELECT_ONLY.match(query.strip()))
def verify_node(state: AgentState) -> AgentState:
hypotheses: list[Hypothesis] = state.get("hypotheses", [])
updated: list[Hypothesis] = []
with Session(_sync_engine) as session:
for h in hypotheses:
query = h.get("evidence_query")
if query:
evidence = _run_evidence_query(query, session)
h = dict(h)
h["verified"] = bool(evidence and "error" not in evidence)
updated.append(h)
verified_cause, confidence = _pick_verified_cause(updated)
needs_clarification = confidence < _CONFIDENCE_THRESHOLD
fix_suggestion = _build_fix_suggestion(verified_cause, state)
return {
**state,
"hypotheses": updated,
"verified_cause": verified_cause,
"fix_suggestion": fix_suggestion,
"needs_clarification": needs_clarification,
}
Маршрутизация после проверки:
def _route_after_verify(state: AgentState) -> str:
if state.get("needs_clarification", False):
return "clarify"
return "report"
def build_investigation_graph() -> StateGraph:
graph = StateGraph(AgentState)
graph.add_node("triage", triage_node)
graph.add_node("traverse", traverse_node)
graph.add_node("profile", profile_node)
graph.add_node("hypothesize", hypothesize_node)
graph.add_node("verify", verify_node_with_mlflow)
graph.add_node("report", report_node)
graph.add_node("clarify", clarify_node)
graph.add_edge(START, "triage")
graph.add_edge("triage", "traverse")
graph.add_edge("traverse", "profile")
graph.add_edge("profile", "hypothesize")
graph.add_edge("hypothesize", "verify")
graph.add_conditional_edges(
"verify",
_route_after_verify,
{"report": "report", "clarify": "clarify"},
)
graph.add_edge("report", END)
graph.add_edge("clarify", END)
return graph.compile()
investigation_graph = build_investigation_graph()
Отчет
Собирает описательную информацию и данные в формате, понятном машинам, для людей и тикетов.
Уточнение
Прерывает работу, если идентификатор клиента или актива неоднозначен — лучше приостановиться, чем обработать данные неверного пользователя.
Сборка графа
Построение цепочки операций: START → триаж → обработка → анализ профиля → формулировка гипотезы → проверка → (цикл или отчет) → END, причем операция уточнения выполняется в качестве условного отклонения. Используется контрольный указатель для того, чтобы длительные исследования сохранялись при перезапуске процесса.
Бэкенд FastAPI
Реализуются концовки для запуска, возобновления и получения статуса, соответствующие методам invoke / Command(resume=…). Осуществляется аутентификация операторов; критические учетные данные никогда не передаются браузеру в необработанном виде.
Наблюдаемость с помощью MLflow
Записывайте параметры сортировки логов в начале процесса; отслеживайте показатели количества пройденных этапов, счёт гипотез, результаты проверок на успех/неудачу и время выполнения; сохраняйте материалы для отчёта в формате Markdown, JSON с гипотезами и транскрипции данных в формате Cypher.
Панель управления Gradio
Разделите окна на зоны для приёма сигналов тревоги, отображения текущего состояния и вывода окончательного отчёта. Виджеты для возобновления работы должны возвращать ответы в тот же идентификатор потока.
Webhooks
def _fire_webhook(context: dict) -> None:
ti = context["task_instance"]
payload = {
"dag_id": context["dag"].dag_id,
"run_id": context["run_id"],
"client_id": context["dag"].dag_id.split("__")[0],
"task_id": ti.task_id,
"execution_date": context["execution_date"].isoformat(),
"exception": str(context.get("exception", "")),
"log_url": ti.log_url,
}
try:
resp = requests.post(
f"{BACKEND_URL}/webhook/airflow",
json=payload,
headers={"X-API-Key": API_KEY},
timeout=10,
)
resp.raise_for_status()
log.info("Webhook fired successfully: %s", resp.json())
except requests.RequestException as exc:
log.error("Failed to fire investigation webhook: %s", exc)
Активируйте webhook при завершении формирования отчёта для передачи его в систему управления тикетами, не блокируя путь возврата данных графа; повторные попытки должны выполняться в рабочем процессе webhook, а не на основном узле.
Сам по себе граф без процедуры расследования — это просто визуальная схема. Процедура без графа — это лишь догадки. Вместе с инфраструктурой, настроенной с использованием Terraform, безопасными способами обработки данных, проверками с использованием только оператора SELECT и аудитом в формате MLflow они превращаются в функциональный инструмент для решения инцидентов, а не в простую демонстрационную записку.
Записывайте имена ответственных за принятие решений рядом с узлами и целями webhook.
В циклах с ненадежным кодом предпочитайте использовать только запросы SELECT для проверки.
Создавайте снимки критических инцидентов перед изменением параметров сортировки.
Уведомляйте о циклах с неудачной проверкой так же, как сервисы уведомляют о кодах ошибок 5xx.
С самого начала разделяйте клиентских абонентов с помощью меток в графе.
Документируйте результаты работы Terraform, которые использует фоновый процесс агента.
Указывайте ответственных за принятие решений рядом с узлами и целями webhook.
В циклах с ненадежным кодом предпочитайте использовать только запросы SELECT для проверки.
Создавайте снимки критических инцидентов перед изменением параметров сортировки.
Уведомляйте о циклах с неудачной проверкой так же, как сервисы уведомляют о кодах ошибок 5xx.
С самого начала разделяйте клиентских абонентов с помощью меток в графе.
Документируйте результаты работы Terraform, которые использует фоновый процесс агента.
Указывайте ответственных за принятие решений рядом с узлами и целями webhook.
В циклах с ненадежным кодом предпочитайте использовать только запросы SELECT для проверки.
Сделайте снимок критических инцидентов до изменения параметров триажа.
Уведомляйте при циклах с ошибками проверки так же, как сервисы уведомляют при кодах ошибок 5xx.
С самого начала разделяйте клиентских арендаторов с помощью меток в графе.
Задокументируйте результаты работы Terraform, которые использует фоновый процесс агента.
Укажите ответственных за принятие решений рядом с узлами и целями webhook-сообщений.
В ненадежных циклах предпочитайте запросы проверки, содержащие только оператор SELECT.
Сделайте снимок критических инцидентов до изменения параметров триажа.
Уведомляйте при циклах с ошибками проверки так же, как сервисы уведомляют при кодах ошибок 5xx.
С самого начала разделяйте клиентских арендаторов с помощью меток в графе.
Задокументируйте результаты работы Terraform, которые использует фоновый процесс агента.
Укажите ответственных за принятие решений рядом с узлами и целями webhook-сообщений.
В ненадежных циклах предпочитайте запросы проверки, содержащие только оператор SELECT.
Сделайте снимок критических инцидентов до изменения параметров триажа.
Сигнализируйте о циклах с неудачной верификацией так же, как сервисы сигнализируют о кодах ошибок 5xx.
С самого начала разделяйте клиентских абонентов с помощью меток в графе.
Документируйте результаты работы Terraform, которые использует движок агента.
Указывайте ответственных за принятие решений рядом с узлами и целями webhook-сообщений.
В ненадежных циклах предпочитайте запросы верификации, содержащие только оператор SELECT.
Создавайте снимки критических инцидентов перед изменением параметров сортировки.
Сигнализируйте о циклах с неудачной верификацией так же, как сервисы сигнализируют о кодах ошибок 5xx.
С самого начала разделяйте клиентских абонентов с помощью меток в графе.
Документируйте результаты работы Terraform, которые использует движок агента.
Указывайте ответственных за принятие решений рядом с узлами и целями webhook-сообщений.
В ненадежных циклах предпочитайте запросы верификации, содержащие только оператор SELECT.
Создавайте снимки критических инцидентов перед изменением параметров сортировки.
Сигнализируйте о циклах с неудачной верификацией так же, как сервисы сигнализируют о кодах ошибок 5xx.
С самого начала разделяйте клиентских арендаторов с помощью меток графа.
Документируйте результаты работы Terraform, которые использует движок агента.
Указывайте ответственных за принятие решений рядом с узлами и целями webhook-сообщений.
В ненадежных циклах предпочитайте запросы для проверки, содержащие только оператор SELECT.
Создавайте снимки состояния при критических инцидентах перед изменением параметров сортировки.
Уведомляйте о циклах с ошибками проверки так же, как сервисы уведомляют о кодах ошибок 5xx.
С самого начала разделяйте клиентских арендаторов с помощью меток графа.
Документируйте результаты работы Terraform, которые использует движок агента.
Рядом с каждым изменением в графе или агенте указывайте ответственных, необходимые настройки и примечания по откату, чтобы демонстрации не опережали уровень работоспособности.
Рядом с каждым изменением в графе или агенте указывайте ответственных, необходимые настройки и примечания по откату, чтобы демонстрации не опережали уровень работоспособности.
Рядом с каждым изменением в графе или агенте указывайте ответственных, необходимые настройки и примечания по откату, чтобы демонстрации не опережали уровень работоспособности.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, настройках и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, конфигурациях и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, конфигурациях и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.
Храните информацию об ответственных лицах, конфигурациях и записях о возврате к предыдущему состоянию рядом с каждой диаграммой или изменением агента, чтобы демонстрации не превосходили возможности системы.