Devs World
Стоимость - это тоже non-functional requirement. Мы привыкли проектировать системы вокруг привычных SLO: Availability: 99.95% P99 latency: 200 ms Throughput: 10k RPS Но рядом почти никогда нет еще одной строки: Cost: $0.00012/request А зря. Архитектура…
Overprovisioning дает запас, но сжигает compute. Autoscaling экономит деньги, но может плохо переживать резкие пики. Karpenter помогает эффективнее использовать Kubernetes capacity. Reserved capacity выгодна для стабильной нагрузки. Spot сильно снижает цену, если workload умеет переживать eviction.
То же самое с данными. Read replica снижает latency, но увеличивает постоянную стоимость. Queue сглаживает пики и позволяет уменьшить compute. Cache убирает дорогие DB calls, но добавляет стоимость и consistency complexity.
Есть и расходы, которые легко не заметить.
Cross-AZ traffic. Логи, которые никто не читает. High-cardinality metrics. Traces для каждого запроса. Данные, годами лежащие в дорогом storage tier.
А теперь к этому добавились AI workloads.
Здесь архитектурной метрикой становится не только cost per request, но и cost per inference, cost per token, cost per customer, cost per transaction. Выбор модели, размер context window, prompt caching и количество agent iterations становятся такими же архитектурными решениями, как выбор базы данных.
Поэтому мне близка эволюция FinOps от идеи "сократить счет AWS" к unit economics и business value. Cloud bill сам по себе почти ничего не говорит. Если инфраструктура стоит миллион и приносит сто миллионов - это одна архитектура. Если она стоит миллион и обслуживает продукт с выручкой в полтора - совсем другая.
Поэтому в architecture review я бы добавил обязательный вопрос:
"Сколько стоит одна полезная единица работы этой системы?"
Когда инженер проектирует не только latency и availability, но и unit economics, архитектура начинает напрямую влиять на P&L.
#заметкиархитектора
То же самое с данными. Read replica снижает latency, но увеличивает постоянную стоимость. Queue сглаживает пики и позволяет уменьшить compute. Cache убирает дорогие DB calls, но добавляет стоимость и consistency complexity.
Есть и расходы, которые легко не заметить.
Cross-AZ traffic. Логи, которые никто не читает. High-cardinality metrics. Traces для каждого запроса. Данные, годами лежащие в дорогом storage tier.
А теперь к этому добавились AI workloads.
Здесь архитектурной метрикой становится не только cost per request, но и cost per inference, cost per token, cost per customer, cost per transaction. Выбор модели, размер context window, prompt caching и количество agent iterations становятся такими же архитектурными решениями, как выбор базы данных.
Поэтому мне близка эволюция FinOps от идеи "сократить счет AWS" к unit economics и business value. Cloud bill сам по себе почти ничего не говорит. Если инфраструктура стоит миллион и приносит сто миллионов - это одна архитектура. Если она стоит миллион и обслуживает продукт с выручкой в полтора - совсем другая.
Поэтому в architecture review я бы добавил обязательный вопрос:
"Сколько стоит одна полезная единица работы этой системы?"
Когда инженер проектирует не только latency и availability, но и unit economics, архитектура начинает напрямую влиять на P&L.
#заметкиархитектора
👍2
В истории S3 есть момент, который архитекторы иногда пересказывают как "AWS придумала новый consensus algorithm". Я бы формулировал точнее: AWS не раскрывала публично новый алгоритм уровня Raft или Paxos, но в 2020 S3 получил strong read-after-write consistency для GET, PUT и LIST без заявленного ухудшения performance и без глобальной координации. И вот инженерно это намного интереснее самого названия алгоритма. ([Amazon Web Services, Inc.][1])
Представим наивную distributed storage. Есть 3 replica, запись подтверждаем после W=2, чтение делаем с R=2. Тогда:
W + R > N
2 + 2 > 3
Кворумы обязательно пересекаются хотя бы в одной replica, поэтому можно определить актуальную версию. Но за consistency платим coordination latency: если RTT до replica 1, 3 и 12 мс, запись зависит уже не от быстрейшей машины, а минимум от второй успевшей подтвердить.
Представим наивную distributed storage. Есть 3 replica, запись подтверждаем после W=2, чтение делаем с R=2. Тогда:
W + R > N
2 + 2 > 3
Кворумы обязательно пересекаются хотя бы в одной replica, поэтому можно определить актуальную версию. Но за consistency платим coordination latency: если RTT до replica 1, 3 и 12 мс, запись зависит уже не от быстрейшей машины, а минимум от второй успевшей подтвердить.
Devs World
В истории S3 есть момент, который архитекторы иногда пересказывают как "AWS придумала новый consensus algorithm". Я бы формулировал точнее: AWS не раскрывала публично новый алгоритм уровня Raft или Paxos, но в 2020 S3 получил strong read-after-write consistency…
На масштабе S3 проблема становится жестче. Нельзя просто посадить миллиарды ключей на один consensus group - leader превратится в bottleneck. Значит, coordination domain надо дробить, маршрутизацию делать локальной, а metadata и версии объектов обновлять так, чтобы независимые ключи практически не мешали друг другу.
Именно здесь архитектура выигрывает у "более быстрого алгоритма". Если миллион независимых ключей распределить между 10000 coordination groups, средняя область конкуренции уменьшается примерно:
1 000 000 / 10 000 = 100 ключей на group.
Теперь consensus остается локальным, а throughput масштабируется горизонтально.
В итоге S3 получил сильную консистентность при сохранении региональной изоляции, а приложениям больше не понадобились отдельные слои вроде S3Guard только ради согласованного представления данных. Позже conditional writes позволили еще и переносить optimistic concurrency control непосредственно в S3 вместо внешних lock-сервисов. ([Amazon Web Services, Inc.][1])
Для меня это хороший пример зрелой distributed architecture: настоящий прорыв часто не в том, чтобы придумать "Raft быстрее Raft", а в том, чтобы уменьшить область, внутри которой consensus вообще необходим.
[1]: https://aws.amazon.com/blogs/aws/amazon-s3-update-strong-read-after-write-consistency/?utm_source=chatgpt.com "Amazon S3 Update – Strong Read-After-Write Consistency | AWS News Blog"
#заметкиархитектора #история
Именно здесь архитектура выигрывает у "более быстрого алгоритма". Если миллион независимых ключей распределить между 10000 coordination groups, средняя область конкуренции уменьшается примерно:
1 000 000 / 10 000 = 100 ключей на group.
Теперь consensus остается локальным, а throughput масштабируется горизонтально.
В итоге S3 получил сильную консистентность при сохранении региональной изоляции, а приложениям больше не понадобились отдельные слои вроде S3Guard только ради согласованного представления данных. Позже conditional writes позволили еще и переносить optimistic concurrency control непосредственно в S3 вместо внешних lock-сервисов. ([Amazon Web Services, Inc.][1])
Для меня это хороший пример зрелой distributed architecture: настоящий прорыв часто не в том, чтобы придумать "Raft быстрее Raft", а в том, чтобы уменьшить область, внутри которой consensus вообще необходим.
[1]: https://aws.amazon.com/blogs/aws/amazon-s3-update-strong-read-after-write-consistency/?utm_source=chatgpt.com "Amazon S3 Update – Strong Read-After-Write Consistency | AWS News Blog"
#заметкиархитектора #история
Amazon
Amazon S3 Update – Strong Read-After-Write Consistency | Amazon Web Services
When we launched S3 back in 2006, I discussed its virtually unlimited capacity (“…easily store any number of blocks…”), the fact that it was designed to provide 99.99% availability, and that it offered durable storage, with data transparently stored in multiple…
👍1🔥1
Security начинается не с pentest и не с security review перед релизом. Она начинается еще до первой строки business logic.
Identity, Authorization, Service boundary, Data boundary, Audit, Observability. Если эти границы не определены архитектурой, security-команда потом будет бесконечно латать последствия. Особенно это заметно сейчас, когда в инфраструктуре появляются AI agents.
Представим простую задачу: агенту говорят "fix production" и выдают AWS credentials.
Для человека это уже слишком широкие права. Для AI-агента ситуация еще опаснее. Он может интерпретировать контекст неправильно, выполнить неожиданную последовательность действий или попасть под prompt injection через данные, которые сам же читает.
Поэтому агенту нельзя выдавать "доступ в AWS". Ему нужно выдавать конкретные capabilities. Например: прочитать логи одного сервиса, перезапустить deployment, изменить один параметр autoscaling. На ограниченное время. С полным audit trail.
Identity, Authorization, Service boundary, Data boundary, Audit, Observability. Если эти границы не определены архитектурой, security-команда потом будет бесконечно латать последствия. Особенно это заметно сейчас, когда в инфраструктуре появляются AI agents.
Представим простую задачу: агенту говорят "fix production" и выдают AWS credentials.
Для человека это уже слишком широкие права. Для AI-агента ситуация еще опаснее. Он может интерпретировать контекст неправильно, выполнить неожиданную последовательность действий или попасть под prompt injection через данные, которые сам же читает.
Поэтому агенту нельзя выдавать "доступ в AWS". Ему нужно выдавать конкретные capabilities. Например: прочитать логи одного сервиса, перезапустить deployment, изменить один параметр autoscaling. На ограниченное время. С полным audit trail.
👍2🔥1
Devs World
Security начинается не с pentest и не с security review перед релизом. Она начинается еще до первой строки business logic. Identity, Authorization, Service boundary, Data boundary, Audit, Observability. Если эти границы не определены архитектурой, security…
Именно здесь важны ephemeral credentials, workload identity и least privilege. Долгоживущие secrets постепенно должны исчезать из архитектуры. Сервис получает identity среды, а права выдаются конкретному workload. AI agent получает временные credentials только на необходимую операцию.
Но IAM - лишь один слой.
Service boundary определяет, кто вообще может обращаться к компоненту. Data boundary - какие данные он имеет право видеть. Network policies ограничивают маршруты. Audit позволяет восстановить цепочку действий. Observability должна показывать не только ошибки, но и необычные security-sensitive операции.
Есть еще software supply chain. Можно идеально настроить IAM и проиграть атаку через dependency. Поэтому SBOM, проверка provenance, подпись artifacts, scanning dependencies и контроль build pipeline становятся частью архитектуры, а не набором дополнительных security tools.
И здесь снова появляется AI. Если агент способен устанавливать package, менять pipeline, создавать cloud resources или выполнять shell commands, его tool permissions фактически становятся новой системой авторизации.
Prompt injection в таком мире - это уже не проблема чат-бота. Это потенциальный путь к инфраструктуре. Поэтому главный вопрос при проектировании AI-enabled системы для меня звучит не "что агент умеет делать?" А "какой минимальный набор действий ему действительно необходимо разрешить?"
Security зрелой системы определяется не количеством security-продуктов. Она определяется тем, насколько сложно одному ошибочному действию превратиться в компрометацию всей системы. Именно поэтому cloud security, secure architecture и AI security сегодня начинают сходиться в одну дисциплину.
Это уже не задача отдельной security-команды. Это ответственность архитектуры.
#заметкиархитектора
Но IAM - лишь один слой.
Service boundary определяет, кто вообще может обращаться к компоненту. Data boundary - какие данные он имеет право видеть. Network policies ограничивают маршруты. Audit позволяет восстановить цепочку действий. Observability должна показывать не только ошибки, но и необычные security-sensitive операции.
Есть еще software supply chain. Можно идеально настроить IAM и проиграть атаку через dependency. Поэтому SBOM, проверка provenance, подпись artifacts, scanning dependencies и контроль build pipeline становятся частью архитектуры, а не набором дополнительных security tools.
И здесь снова появляется AI. Если агент способен устанавливать package, менять pipeline, создавать cloud resources или выполнять shell commands, его tool permissions фактически становятся новой системой авторизации.
Prompt injection в таком мире - это уже не проблема чат-бота. Это потенциальный путь к инфраструктуре. Поэтому главный вопрос при проектировании AI-enabled системы для меня звучит не "что агент умеет делать?" А "какой минимальный набор действий ему действительно необходимо разрешить?"
Security зрелой системы определяется не количеством security-продуктов. Она определяется тем, насколько сложно одному ошибочному действию превратиться в компрометацию всей системы. Именно поэтому cloud security, secure architecture и AI security сегодня начинают сходиться в одну дисциплину.
Это уже не задача отдельной security-команды. Это ответственность архитектуры.
#заметкиархитектора
❤3
Когда я впервые увидел FAIR, мне понравилась одна вещь: он убирает из risk management слова вроде "высокий риск" и заставляет переводить разговор в деньги, частоты и вероятности.
В упрощенном виде FAIR раскладывает риск так:
Risk = Loss Event Frequency * Loss Magnitude
То есть нам нужны два вопроса: как часто событие реально может случаться и сколько мы потеряем, если оно случится.
Допустим, у нас есть публичный API. Мы оцениваем, что попытки серьезной атаки происходят 12 раз в год, а вероятность успешного инцидента при одной попытке около 5%.
Тогда ожидаемая частота потерь:
12 * 0.05 = 0.6 инцидента в год.
Теперь считаем ущерб. Прямые потери - 40 000 долларов на incident response и восстановление. Еще 60 000 - возможный простой, компенсации клиентам и потерянные сделки.
Средний ущерб:
40 000 + 60 000 = 100 000 долларов.
Получаем:
0.6 * 100 000 = 60 000 долларов ожидаемых потерь в год.
В упрощенном виде FAIR раскладывает риск так:
Risk = Loss Event Frequency * Loss Magnitude
То есть нам нужны два вопроса: как часто событие реально может случаться и сколько мы потеряем, если оно случится.
Допустим, у нас есть публичный API. Мы оцениваем, что попытки серьезной атаки происходят 12 раз в год, а вероятность успешного инцидента при одной попытке около 5%.
Тогда ожидаемая частота потерь:
12 * 0.05 = 0.6 инцидента в год.
Теперь считаем ущерб. Прямые потери - 40 000 долларов на incident response и восстановление. Еще 60 000 - возможный простой, компенсации клиентам и потерянные сделки.
Средний ущерб:
40 000 + 60 000 = 100 000 долларов.
Получаем:
0.6 * 100 000 = 60 000 долларов ожидаемых потерь в год.
👍1
Devs World
Когда я впервые увидел FAIR, мне понравилась одна вещь: он убирает из risk management слова вроде "высокий риск" и заставляет переводить разговор в деньги, частоты и вероятности. В упрощенном виде FAIR раскладывает риск так: Risk = Loss Event Frequency *…
И вот здесь начинается настоящая сила FAIR. Если команда предлагает security-проект за 25 000 долларов в год, который снижает вероятность успешной атаки с 5% до 1%, новая оценка:
12 * 0.01 * 100 000 = 12 000 долларов.
Risk reduction:
60 000 - 12 000 = 48 000 долларов.
Мы тратим 25 000 и математически уменьшаем ожидаемые потери на 48 000.
В этот момент security перестает быть "страшилкой для бизнеса". Архитектор уже может обсуждать защиту на языке ROI, а бизнес - сравнивать ее с любыми другими инвестициями.
Именно поэтому FAIR мне нравится: он не обещает предсказать будущее. Он делает неопределенность измеримой.
#заметкиархитектора #история
12 * 0.01 * 100 000 = 12 000 долларов.
Risk reduction:
60 000 - 12 000 = 48 000 долларов.
Мы тратим 25 000 и математически уменьшаем ожидаемые потери на 48 000.
В этот момент security перестает быть "страшилкой для бизнеса". Архитектор уже может обсуждать защиту на языке ROI, а бизнес - сравнивать ее с любыми другими инвестициями.
Именно поэтому FAIR мне нравится: он не обещает предсказать будущее. Он делает неопределенность измеримой.
#заметкиархитектора #история
💯2
Я софтвер архітектор, девелопер і менеджер. Але вдома все навпаки: 14 котів ставлять задачі, контролюють дедлайни і регулярно вимагають перегляд зарплати кормом.
#жартипроандрія
#жартипроандрія
👍5🥰4😁1
В холодильнику просто мерехтіло світло.
Через три години: дошка з формулами, квантова гравітація, причинність, детермінізм і питання про природу часу.
#жартипроандрія
Через три години: дошка з формулами, квантова гравітація, причинність, детермінізм і питання про природу часу.
#жартипроандрія
❤1😁1
Forwarded from Machine Learning World (Andrey Nikishaev)
Хочете поржати? Ось це пропонується як докторська робота))
Якщо що я це робив ще років 8 тому, а до мене ще люди роки 3-5, а принцип відомий років 40 мабудь.
Це дно бляха. повне.
Ось лінк на це нечто:
https://scc.knu.ua/zdobuvach-phd?id=336484&fbclid=IwY2xjawUTbfFwZG9mBWV4dG4DYWVtAjEwAGJyaWQRMTIyWVR5S0JkUjRVcmd1ZFNzcnRjBmFwcF9pZBAyMjIwMzkxNzg4MjAwODkyAAEe2Y5vDaU_L6rxEU5DENgfQSmZLMTp4gmL72eBvGpYdl4l_cWk9Ey5cck0gCQ_aem_Y9S9hVtCYjmGu2H5JRThTg
сама робота:
https://scc.knu.ua/components/com_chronoforms7/chronoforms/uploads/336484/Kubytskyi_Panchenko_phd_dissertation_2026_final_pdfa.pdf
Якщо що я це робив ще років 8 тому, а до мене ще люди роки 3-5, а принцип відомий років 40 мабудь.
Це дно бляха. повне.
Ось лінк на це нечто:
https://scc.knu.ua/zdobuvach-phd?id=336484&fbclid=IwY2xjawUTbfFwZG9mBWV4dG4DYWVtAjEwAGJyaWQRMTIyWVR5S0JkUjRVcmd1ZFNzcnRjBmFwcF9pZBAyMjIwMzkxNzg4MjAwODkyAAEe2Y5vDaU_L6rxEU5DENgfQSmZLMTp4gmL72eBvGpYdl4l_cWk9Ey5cck0gCQ_aem_Y9S9hVtCYjmGu2H5JRThTg
сама робота:
https://scc.knu.ua/components/com_chronoforms7/chronoforms/uploads/336484/Kubytskyi_Panchenko_phd_dissertation_2026_final_pdfa.pdf
😁1
Большинство распределенных систем падают не потому, что один сервис умер. Они падают потому, что живые сервисы начинают слишком активно "спасать" ситуацию.
Типичный сценарий выглядит невинно. Один downstream-сервис начинает отвечать не за 50 мс, а за 2 секунды. Причина может быть любой: медленная база, исчерпанный connection pool, GC pause, перегретый shard.
Upstream продолжает принимать трафик. Запросы теперь живут дольше, значит одновременно открытых запросов становится больше. Растут очереди, количество goroutine, threads, sockets, memory usage. Это backpressure, которую система почему-то решила проигнорировать.
А дальше появляется retry.
Первый запрос не дождался ответа за 1 секунду и отправился повторно. Но оригинальный запрос вполне может все еще выполняться. Теперь перегруженный сервис получает не меньше работы, а больше.
Типичный сценарий выглядит невинно. Один downstream-сервис начинает отвечать не за 50 мс, а за 2 секунды. Причина может быть любой: медленная база, исчерпанный connection pool, GC pause, перегретый shard.
Upstream продолжает принимать трафик. Запросы теперь живут дольше, значит одновременно открытых запросов становится больше. Растут очереди, количество goroutine, threads, sockets, memory usage. Это backpressure, которую система почему-то решила проигнорировать.
А дальше появляется retry.
Первый запрос не дождался ответа за 1 секунду и отправился повторно. Но оригинальный запрос вполне может все еще выполняться. Теперь перегруженный сервис получает не меньше работы, а больше.
Devs World
Большинство распределенных систем падают не потому, что один сервис умер. Они падают потому, что живые сервисы начинают слишком активно "спасать" ситуацию. Типичный сценарий выглядит невинно. Один downstream-сервис начинает отвечать не за 50 мс, а за 2 секунды.…
Если 20 процентов запросов начинают ретраиться дважды, нагрузка легко превращается из 100 RPS в 140. Latency растет еще сильнее, таймаутов становится больше, retries запускаются чаще.
Получается положительная обратная связь.
Latency -> timeout -> retry -> дополнительная нагрузка -> еще большая latency.
На этом этапе система уже может быть технически "здоровой". Все pods running, CPU еще не 100 процентов, health checks зеленые. Но очередь растет быстрее, чем сервис способен ее разгребать.
Потом начинается каскад.
Upstream исчерпывает connection pool. Его запросы начинают зависать. Сервисы выше по цепочке тоже запускают retries. Клиенты обновляют страницу. Load balancer перераспределяет трафик на оставшиеся якобы здоровые instances.
Через несколько минут локальная деградация превращается в outage всей системы.
Поэтому надежная distributed architecture начинается не с Kubernetes и не с количества реплик.
Она начинается с вопроса: "Что произойдет с системой, когда один компонент станет медленным, но еще не умрет?"
Хорошая система умеет сказать "нет".
Bounded queues вместо бесконечных очередей. Жесткие timeouts. Exponential backoff с jitter. Retry budgets. Circuit breakers. Bulkheads. Ограничение concurrency. Load shedding. И главное - retries только для действительно retryable операций.
Особенно опасны одинаковые timeout и retry policies на всех уровнях. Если frontend, API gateway и три внутренних сервиса каждый делают по 3 попытки, один пользовательский запрос теоретически может породить десятки downstream-вызовов.
Именно поэтому я при разборе production-инцидентов смотрю не только на место, где появилась ошибка. Я ищу место, где система перестала ограничивать ущерб. Потому что отказ одного сервиса - это обычная эксплуатационная проблема.
Архитектурная проблема начинается тогда, когда один медленный сервис получает право положить все остальные.
#заметкиархитектора
Получается положительная обратная связь.
Latency -> timeout -> retry -> дополнительная нагрузка -> еще большая latency.
На этом этапе система уже может быть технически "здоровой". Все pods running, CPU еще не 100 процентов, health checks зеленые. Но очередь растет быстрее, чем сервис способен ее разгребать.
Потом начинается каскад.
Upstream исчерпывает connection pool. Его запросы начинают зависать. Сервисы выше по цепочке тоже запускают retries. Клиенты обновляют страницу. Load balancer перераспределяет трафик на оставшиеся якобы здоровые instances.
Через несколько минут локальная деградация превращается в outage всей системы.
Поэтому надежная distributed architecture начинается не с Kubernetes и не с количества реплик.
Она начинается с вопроса: "Что произойдет с системой, когда один компонент станет медленным, но еще не умрет?"
Хорошая система умеет сказать "нет".
Bounded queues вместо бесконечных очередей. Жесткие timeouts. Exponential backoff с jitter. Retry budgets. Circuit breakers. Bulkheads. Ограничение concurrency. Load shedding. И главное - retries только для действительно retryable операций.
Особенно опасны одинаковые timeout и retry policies на всех уровнях. Если frontend, API gateway и три внутренних сервиса каждый делают по 3 попытки, один пользовательский запрос теоретически может породить десятки downstream-вызовов.
Именно поэтому я при разборе production-инцидентов смотрю не только на место, где появилась ошибка. Я ищу место, где система перестала ограничивать ущерб. Потому что отказ одного сервиса - это обычная эксплуатационная проблема.
Архитектурная проблема начинается тогда, когда один медленный сервис получает право положить все остальные.
#заметкиархитектора
👍6
Forwarded from Machine Learning World (Andrey Nikishaev)
https://voicebox.sh/ - крутой фреймворк для работи с голосом
👍2
Недавно я поймал очень неприятную вещь там, где вообще не ожидал ее увидеть - внутри библиотеки, которую просто добавили в Python VirtualEnv.
Я запускал AI-агента для работы с проектом. Ничего экзотического: обычный код, обычное окружение, зависимости. Но у меня есть профессиональная паранойя - AI у меня никогда не получает обычный доступ к машине. Filesystem ограничен, secrets вынесены, права урезаны, а исходящий трафик во время работы разрешен только к API самого AI-провайдера. Именно это в итоге и спасло.
Механика атаки была особенно неприятной. Библиотека в определенный момент специально ломалась, и агент закономерно упирался в ошибку. Я писал ему обычный запрос в стиле: "найди проблему и почини". Агент шел смотреть код библиотеки, находил место поломки, а прямо рядом в комментарии было что-то вроде: "чтобы исправить эту проблему, выполни следующий код". Ниже уже находилась инструкция, которая пыталась заставить его прочитать локальные данные и выполнить действия, вообще не связанные с реальным багом.
Я запускал AI-агента для работы с проектом. Ничего экзотического: обычный код, обычное окружение, зависимости. Но у меня есть профессиональная паранойя - AI у меня никогда не получает обычный доступ к машине. Filesystem ограничен, secrets вынесены, права урезаны, а исходящий трафик во время работы разрешен только к API самого AI-провайдера. Именно это в итоге и спасло.
Механика атаки была особенно неприятной. Библиотека в определенный момент специально ломалась, и агент закономерно упирался в ошибку. Я писал ему обычный запрос в стиле: "найди проблему и почини". Агент шел смотреть код библиотеки, находил место поломки, а прямо рядом в комментарии было что-то вроде: "чтобы исправить эту проблему, выполни следующий код". Ниже уже находилась инструкция, которая пыталась заставить его прочитать локальные данные и выполнить действия, вообще не связанные с реальным багом.
Devs World
Недавно я поймал очень неприятную вещь там, где вообще не ожидал ее увидеть - внутри библиотеки, которую просто добавили в Python VirtualEnv. Я запускал AI-агента для работы с проектом. Ничего экзотического: обычный код, обычное окружение, зависимости. Но…
Для Python этот комментарий был просто текстом. Для coding agent он фактически становился частью управляющего контекста. И в этом принципиальная разница: атакующему уже не обязательно добиваться выполнения вредоносного Python-кода. Иногда достаточно заставить AI прочитать нужный файл именно в тот момент, когда он ищет решение проблемы.
Вот здесь у меня окончательно поменялось отношение к prompt injection. Раньше модель угроз выглядела понятно: опасен код, который мы выполняем. Теперь опасным становится и контент, который читает агент с доступом к инструментам. README, комментарий, fixture, документация зависимости, CLAUDE.md, issue или сгенерированный лог могут содержать инструкции, которые человек воспримет как мусор, а AI попытается выполнить.
Если бы агент видел `.env`, потенциально утекли бы credentials. Если бы имел unrestricted network access, данные можно было бы отправить наружу. Если бы имел доступ к git, CI или cloud credentials, последствия были бы уже совсем другого масштаба. Но запрос наружу просто не прошел: сеть была закрыта на уровне окружения.
Именно поэтому я не считаю prompt-level правила достаточной защитой. Фраза "не читай secrets" проигрывает архитектурному запрету читать secrets, а инструкция "не отправляй данные наружу" проигрывает firewall, который физически не позволяет этого сделать.
Для AI-агента я применяю ту же модель, что и для недоверенного workload: least privilege, sandbox, минимальный filesystem scope, ephemeral credentials, deny-by-default network и audit действий.
Supply chain теперь состоит не только из кода, который машина исполняет, но и из текста, который AI считает инструкцией. И если ваша защита строится только на system prompt, то фактически вы доверяете безопасность production способности LLM вовремя понять, что ее пытаются обмануть.
Я предпочитаю, чтобы даже успешно обманутый AI физически не мог сделать ничего действительно опасного.
#заметкиархитектора
Вот здесь у меня окончательно поменялось отношение к prompt injection. Раньше модель угроз выглядела понятно: опасен код, который мы выполняем. Теперь опасным становится и контент, который читает агент с доступом к инструментам. README, комментарий, fixture, документация зависимости, CLAUDE.md, issue или сгенерированный лог могут содержать инструкции, которые человек воспримет как мусор, а AI попытается выполнить.
Если бы агент видел `.env`, потенциально утекли бы credentials. Если бы имел unrestricted network access, данные можно было бы отправить наружу. Если бы имел доступ к git, CI или cloud credentials, последствия были бы уже совсем другого масштаба. Но запрос наружу просто не прошел: сеть была закрыта на уровне окружения.
Именно поэтому я не считаю prompt-level правила достаточной защитой. Фраза "не читай secrets" проигрывает архитектурному запрету читать secrets, а инструкция "не отправляй данные наружу" проигрывает firewall, который физически не позволяет этого сделать.
Для AI-агента я применяю ту же модель, что и для недоверенного workload: least privilege, sandbox, минимальный filesystem scope, ephemeral credentials, deny-by-default network и audit действий.
Supply chain теперь состоит не только из кода, который машина исполняет, но и из текста, который AI считает инструкцией. И если ваша защита строится только на system prompt, то фактически вы доверяете безопасность production способности LLM вовремя понять, что ее пытаются обмануть.
Я предпочитаю, чтобы даже успешно обманутый AI физически не мог сделать ничего действительно опасного.
#заметкиархитектора
🤯3❤1💯1
T-Digest становится особенно полезным, когда среднее время ответа выглядит хорошо, а пользователи уже жалуются.
Допустим, 99.9% запросов занимают 80 мс, а остальные 0.1% - 3 секунды. Среднее получится всего 82.92 мс. На миллионе запросов за этой красивой цифрой скрываются 1000 долгих ожиданий.
Чтобы видеть такие проблемы, нужны percentiles. Например, p99 - время, в которое укладываются 99% запросов.
Точный расчет по произвольному потоку требует сохранять много информации. Только 100 млн значений по 8 байт - уже 800 MB без накладных расходов.
T-Digest сжимает поток в группы - centroid-ы. Для каждой хранит среднее mean и число измерений weight.
Как это работает?
В варианте с буфером новые измерения накапливаются, затем сортируются вместе с существующими centroid-ами. Алгоритм проходит по ним и объединяет соседние группы, пока позволяет ограничение размера.
При объединении:
weight = w1 + w2
mean = (m1 * w1 + m2 * w2) / (w1 + w2)
Допустим, 99.9% запросов занимают 80 мс, а остальные 0.1% - 3 секунды. Среднее получится всего 82.92 мс. На миллионе запросов за этой красивой цифрой скрываются 1000 долгих ожиданий.
Чтобы видеть такие проблемы, нужны percentiles. Например, p99 - время, в которое укладываются 99% запросов.
Точный расчет по произвольному потоку требует сохранять много информации. Только 100 млн значений по 8 байт - уже 800 MB без накладных расходов.
T-Digest сжимает поток в группы - centroid-ы. Для каждой хранит среднее mean и число измерений weight.
Как это работает?
В варианте с буфером новые измерения накапливаются, затем сортируются вместе с существующими centroid-ами. Алгоритм проходит по ним и объединяет соседние группы, пока позволяет ограничение размера.
При объединении:
weight = w1 + w2
mean = (m1 * w1 + m2 * w2) / (w1 + w2)
Devs World
T-Digest становится особенно полезным, когда среднее время ответа выглядит хорошо, а пользователи уже жалуются. Допустим, 99.9% запросов занимают 80 мс, а остальные 0.1% - 3 секунды. Среднее получится всего 82.92 мс. На миллионе запросов за этой красивой…
Исходные значения после этого не нужны. Но восстановить их уже нельзя: мы сознательно теряем часть информации.
Главная хитрость - допустимый размер группы зависит от ее позиции в распределении. Специальная scale function разрешает крупные группы около медианы и требует маленькие возле обоих хвостов. Параметр compression регулирует компромисс между памятью и точностью.
Почему маленькие группы помогают?
Представим миллион измерений. Группа из 10 000 значений занимает 1% распределения. Если нужный percentile попал внутрь нее, одного среднего недостаточно, чтобы понять, где именно находится искомое значение.
Группа из 10 измерений занимает уже 0.001%. В ней скрыто гораздо меньше позиций. А группа из одного измерения сохраняет само значение точно.
Это особенно важно возле p99.9: выше него остается всего 1000 измерений из миллиона. Группа на 10 000 значений слишком грубо описывала бы этот участок.
При запросе p99 алгоритм накапливает веса centroid-ов, находит область около позиции 0.99 * N и оценивает значение интерполяцией между соседними центрами.
Меньшие группы дают более подробную картину хвоста. Но это не гарантия ошибки в пределах 1 мс: если соседние значения резко отличаются, ошибка в миллисекундах все равно может быть заметной.
Вместо 800 MB исходных измерений можно хранить тысячи centroid-ов. Например, 1000 пар из двух 8-байтовых чисел - около 16 KB без накладных расходов.
И это удобно распределять: каждый shard строит свой digest, затем centroid-ы объединяются и снова сжимаются. Пересылать все события не нужно. Усреднять p99 отдельных shard-ов тоже нельзя.
Для highload это сильная идея: хранить достаточно информации для нужной точности ответа.
#заметкиархитектора #история
Главная хитрость - допустимый размер группы зависит от ее позиции в распределении. Специальная scale function разрешает крупные группы около медианы и требует маленькие возле обоих хвостов. Параметр compression регулирует компромисс между памятью и точностью.
Почему маленькие группы помогают?
Представим миллион измерений. Группа из 10 000 значений занимает 1% распределения. Если нужный percentile попал внутрь нее, одного среднего недостаточно, чтобы понять, где именно находится искомое значение.
Группа из 10 измерений занимает уже 0.001%. В ней скрыто гораздо меньше позиций. А группа из одного измерения сохраняет само значение точно.
Это особенно важно возле p99.9: выше него остается всего 1000 измерений из миллиона. Группа на 10 000 значений слишком грубо описывала бы этот участок.
При запросе p99 алгоритм накапливает веса centroid-ов, находит область около позиции 0.99 * N и оценивает значение интерполяцией между соседними центрами.
Меньшие группы дают более подробную картину хвоста. Но это не гарантия ошибки в пределах 1 мс: если соседние значения резко отличаются, ошибка в миллисекундах все равно может быть заметной.
Вместо 800 MB исходных измерений можно хранить тысячи centroid-ов. Например, 1000 пар из двух 8-байтовых чисел - около 16 KB без накладных расходов.
И это удобно распределять: каждый shard строит свой digest, затем centroid-ы объединяются и снова сжимаются. Пересылать все события не нужно. Усреднять p99 отдельных shard-ов тоже нельзя.
Для highload это сильная идея: хранить достаточно информации для нужной точности ответа.
#заметкиархитектора #история
Нормальні люди о 2 ночі сплять. Я о 2 ночі думаю: а якщо часу насправді не існує, то, може, технічно я не недосипаю?
#жартипроандрія
#жартипроандрія
🤣5❤1
Мій work-life balance простий. Work: код. Life: коти. Balance: 12 гривень на картці, а до зарплати ще 11 днів.
#жартипроандрія
#жартипроандрія
❤1👍1😱1