Pull to refresh
8K+
4
Сергей Блехер@blurman

User

20,1
Rating
3
Subscribers
Send message

temperature=0 убирает сэмплирование, но не превращает модель в context -> code компилятор.

Остаются batching, погрешности параллельных вычислений на GPU, изменения на стороне провайдера и обвязка инструмента.

У нулевой температуры есть и свой минус: она жёстко выбирает самое вероятное продолжение. Если модель в начале неверно поняла задачу, она может дальше уверенно тащить эту ошибку за собой.

Фабл сам говорит, что у него нет запрета скрывать свой системный промпт. А у Опуса был такой запрет. Спросите у него сами, если не верите. Я это случайно обнаружил, когда он вдруг признался, что его зовут Claude Fable 5. Стал распрашивать его, чем его промпт от опуса отличается - он все и выложил

Недетерминизм вывода опознали верно — это и правда корень, и убрать его нельзя, это природа модели. Но вывод из этого не «инструмент плохой», а «надо строить контур, который ловит мусор без чтения глазами». Про тесты соглашусь — сгенерённые заодно с кодом часто ничего не проверяют. Но жёсткие типы и контракты (про что выше Dhwtj), статические анализаторы, линтеры, плюс тесты, написанные до кода под инвариант, — всё это ворота, а не ещё один артефакт на ревью. Контур ловит локальный мусор. Архитектурный дрейф, мёртвый код, тихо переписанные «заодно» классы он не поймает — это остаётся на человеке. Но именно это и есть нормальная граница: машина пишет по контракту, границы держишь ты.

То, что Вы нашли, в физических движках называется warm-start: ближайшего соседа ищут не с нуля, а стартуя от прошлого найденного — потому что для соседней точки запроса ответ обычно рядом. В collision detection: GJK хранит прошлый симплекс, sweep-and-prune переиспользует порядок с прошлого кадра. У вас ту же роль играет порядок точек контура. Вы пишете, что аналога не нашли — похоже, в литературе по Хаусдорфу его и нет, а в gamedev он давно известен.

Программирование на флагах - это когда одно логическое состояние размазано по нескольким независимым булам. Как в статье: error и succeeded по смыслу взаимоисключающие, но как два bool дают 4 комбинации при 2 валидных. Ни одно поле не «владеет» ответом - единого источника правды нет, инвариант держится на дисциплине, а не на типе.

И тут важный момент: инициализация полей структуру не спасает. Допустим, починили память:

struct Response {
  bool error = false;
  bool succeeded = false;
  std::string data;
};

Языковой UB из статьи ушёл - мусора в памяти больше нет. Но {error:true, succeeded:true} по-прежнему может быть получено вручную в коде. Это уже не неопределённое поведение в смысле стандарта, а логический UB: тип разрешает состояние, которого по смыслу быть не может, и программа однажды в него попадёт. Инициализация лечит симптом, а не причину.

Лечится тем, что за исход отвечает одно поле:

enum class Outcome { Success, Failure };

struct Response {
  Outcome outcome = Outcome::Failure;
  std::string data;
};

Теперь ответственность за состояние лежит на одном outcome, невозможных комбинаций физически нет, а новый код не сможет случайно выставить «и успех, и ошибку». UB в статье просто подсветил проблему программирования на флагах - корень в том, что взаимоисключающий выбор смоделировали через независимые флаги.

Зачем столько часов было тратить на изучение особенностей разных компиляторов? Понятно же, что поля не проинициализированы. Можно быстро исправить и потратить время на размышления о том, как плохо программировать на флагах.

Information

Rating
478-th
Registered
Activity

Specialization

Десктоп разработчик, Архитектор программного обеспечения
Ведущий
From 400,000 ₽
Git
Python
ООП
Английский язык
C#
C++
Visual Studio
Оптимизация кода
Алгоритмы и структуры данных
Математика