[{"data":1,"prerenderedAt":9295},["ShallowReactive",2],{"posts-list":3},[4,3538,4647,8261],{"id":5,"title":6,"body":7,"category":3522,"cover":3523,"date":3524,"description":19,"draft":3525,"extension":3526,"meta":3527,"navigation":3528,"path":3529,"seo":3530,"stem":3531,"tags":3532,"updated":3536,"__hash__":3537},"blog\u002Fblog\u002Fthe-unity-of-infinities.md","Единство бесконечностей: Как одна теорема связывает квантовую физику, JPEG и искусственный интеллект",{"type":8,"value":9,"toc":3498},"minimark",[10,20,23,28,31,122,127,130,610,614,1053,1118,1134,1136,1140,1151,1313,1320,1324,1327,1477,1673,1724,1726,1730,1736,1747,1751,1919,1930,2001,2005,2015,2030,2037,2049,2053,2060,2071,2073,2077,2083,2087,2236,2247,2606,2612,2616,2623,2932,2936,2955,2958,2969,2973,3078,3149,3151,3155,3166,3169,3171,3175,3491,3493],[11,12,13],"blockquote",{},[14,15,16],"p",{},[17,18,19],"em",{},"В геометрии и анализе существует удивительный факт: объекты, которые кажутся нам принципиально разными, с точки зрения высшей математики могут быть абсолютно тождественны. Самое мощное выражение этой идеи — фундаментальная теорема функционального анализа о структуре гильбертовых пространств.",[21,22],"hr",{},[24,25,27],"h2",{"id":26},"_1-чистая-математика-формулировка-и-суть-теоремы","1. Чистая математика: формулировка и суть теоремы",[14,29,30],{},"В основе нашего понимания бесконечномерных систем лежит следующая классическая теорема, окончательно оформленная Джоном фон Нейманом в 1929 году и Маршаллом Стоуном в 1932-м:",[11,32,33,39],{},[14,34,35],{},[36,37,38],"strong",{},"Теорема о классификации сепарабельных гильбертовых пространств.",[14,40,41,42,90,91,121],{},"Любые два бесконечномерных сепарабельных гильбертовых пространства над одним и тем же полем (",[43,44,47,71],"span",{"className":45},[46],"katex",[43,48,51],{"className":49},[50],"katex-mathml",[52,53,55],"math",{"xmlns":54},"http:\u002F\u002Fwww.w3.org\u002F1998\u002FMath\u002FMathML",[56,57,58,66],"semantics",{},[59,60,61],"mrow",{},[62,63,65],"mi",{"mathvariant":64},"double-struck","R",[67,68,70],"annotation",{"encoding":69},"application\u002Fx-tex","\\mathbb{R}",[43,72,76],{"className":73,"ariaHidden":75},[74],"katex-html","true",[43,77,80,85],{"className":78},[79],"base",[43,81],{"className":82,"style":84},[83],"strut","height:0.6889em;",[43,86,65],{"className":87},[88,89],"mord","mathbb"," или ",[43,92,94,109],{"className":93},[46],[43,95,97],{"className":96},[50],[52,98,99],{"xmlns":54},[56,100,101,106],{},[59,102,103],{},[62,104,105],{"mathvariant":64},"C",[67,107,108],{"encoding":69},"\\mathbb{C}",[43,110,112],{"className":111,"ariaHidden":75},[74],[43,113,115,118],{"className":114},[79],[43,116],{"className":117,"style":84},[83],[43,119,105],{"className":120},[88,89],") изометрически изоморфны между собой.",[123,124,126],"h3",{"id":125},"разбор-терминов","Разбор терминов",[14,128,129],{},"Чтобы почувствовать глубину формулировки, разберём её по частям:",[131,132,133,146],"table",{},[134,135,136],"thead",{},[137,138,139,143],"tr",{},[140,141,142],"th",{},"Термин",[140,144,145],{},"Суть",[147,148,149,164,267,281],"tbody",{},[137,150,151,157],{},[152,153,154],"td",{},[36,155,156],{},"Гильбертово пространство",[152,158,159,160,163],{},"Векторное пространство со скалярным произведением, порождающим норму (длину) и угол, которое является ",[36,161,162],{},"полным",": всякая последовательность Коши сходится к элементу того же пространства.",[137,165,166,171],{},[152,167,168],{},[36,169,170],{},"Бесконечномерное",[152,172,173,174,266],{},"Пространство, не имеющее конечного базиса. В сепарабельном случае его размерность в точности равна ",[43,175,177,200],{"className":176},[46],[43,178,180],{"className":179},[50],[52,181,182],{"xmlns":54},[56,183,184,197],{},[59,185,186],{},[187,188,189,193],"msub",{},[62,190,192],{"mathvariant":191},"normal","ℵ",[194,195,196],"mn",{},"0",[67,198,199],{"encoding":69},"\\aleph_0",[43,201,203],{"className":202,"ariaHidden":75},[74],[43,204,206,210],{"className":205},[79],[43,207],{"className":208,"style":209},[83],"height:0.8444em;vertical-align:-0.15em;",[43,211,213,216],{"className":212},[88],[43,214,192],{"className":215},[88],[43,217,220],{"className":218},[219],"msupsub",[43,221,225,257],{"className":222},[223,224],"vlist-t","vlist-t2",[43,226,229,252],{"className":227},[228],"vlist-r",[43,230,234],{"className":231,"style":233},[232],"vlist","height:0.3011em;",[43,235,237,242],{"style":236},"top:-2.55em;margin-left:0em;margin-right:0.05em;",[43,238],{"className":239,"style":241},[240],"pstrut","height:2.7em;",[43,243,249],{"className":244},[245,246,247,248],"sizing","reset-size6","size3","mtight",[43,250,196],{"className":251},[88,248],[43,253,256],{"className":254},[255],"vlist-s","​",[43,258,260],{"className":259},[228],[43,261,264],{"className":262,"style":263},[232],"height:0.15em;",[43,265],{}," — мощности натуральных чисел.",[137,268,269,274],{},[152,270,271],{},[36,272,273],{},"Сепарабельное",[152,275,276,277,280],{},"Существует ",[36,278,279],{},"счётное"," всюду плотное подмножество. Интуитивно: можно зафиксировать упорядоченный бесконечный «каркас» (ортонормированный базис), к элементам которого любой вектор приближается сколь угодно точно.",[137,282,283,288],{},[152,284,285],{},[36,286,287],{},"Изометрический изоморфизм",[152,289,290,291,390,391,605,606,609],{},"Взаимно однозначное линейное отображение ",[43,292,294,328],{"className":293},[46],[43,295,297],{"className":296},[50],[52,298,299],{"xmlns":54},[56,300,301,325],{},[59,302,303,306,310,314,316,319,322],{},[62,304,305],{},"T",[307,308,309],"mtext",{}," ⁣",[311,312,313],"mo",{},":",[307,315,309],{},[62,317,318],{},"A",[311,320,321],{},"→",[62,323,324],{},"B",[67,326,327],{"encoding":69},"T\\!:\\!A\\to B",[43,329,331,362,380],{"className":330,"ariaHidden":75},[74],[43,332,334,338,343,348,352,356,359],{"className":333},[79],[43,335],{"className":336,"style":337},[83],"height:0.6833em;",[43,339,305],{"className":340,"style":342},[88,341],"mathnormal","margin-right:0.1389em;",[43,344],{"className":345,"style":347},[346],"mspace","margin-right:-0.1667em;",[43,349],{"className":350,"style":351},[346],"margin-right:0.2778em;",[43,353,313],{"className":354},[355],"mrel",[43,357],{"className":358,"style":347},[346],[43,360],{"className":361,"style":351},[346],[43,363,365,368,371,374,377],{"className":364},[79],[43,366],{"className":367,"style":337},[83],[43,369,318],{"className":370},[88,341],[43,372],{"className":373,"style":351},[346],[43,375,321],{"className":376},[355],[43,378],{"className":379,"style":351},[346],[43,381,383,386],{"className":382},[79],[43,384],{"className":385,"style":337},[83],[43,387,324],{"className":388,"style":389},[88,341],"margin-right:0.0502em;",", сохраняющее скалярное произведение: ",[43,392,394,452],{"className":393},[46],[43,395,397],{"className":396},[50],[52,398,399],{"xmlns":54},[56,400,401,449],{},[59,402,403,407,409,412,415,418,420,423,430,433,435,437,439,441,443],{},[311,404,406],{"stretchy":405},"false","⟨",[62,408,305],{},[62,410,411],{},"x",[311,413,414],{"separator":75},",",[307,416,417],{}," ",[62,419,305],{},[62,421,422],{},"y",[187,424,425,428],{},[311,426,427],{"stretchy":405},"⟩",[62,429,324],{},[311,431,432],{},"=",[311,434,406],{"stretchy":405},[62,436,411],{},[311,438,414],{"separator":75},[307,440,417],{},[62,442,422],{},[187,444,445,447],{},[311,446,427],{"stretchy":405},[62,448,318],{},[67,450,451],{"encoding":69},"\\langle Tx,\\,Ty\\rangle_B = \\langle x,\\,y\\rangle_A",[43,453,455,541],{"className":454,"ariaHidden":75},[74],[43,456,458,462,466,469,472,476,480,483,486,490,532,535,538],{"className":457},[79],[43,459],{"className":460,"style":461},[83],"height:1em;vertical-align:-0.25em;",[43,463,406],{"className":464},[465],"mopen",[43,467,305],{"className":468,"style":342},[88,341],[43,470,411],{"className":471},[88,341],[43,473,414],{"className":474},[475],"mpunct",[43,477],{"className":478,"style":479},[346],"margin-right:0.1667em;",[43,481],{"className":482,"style":479},[346],[43,484,305],{"className":485,"style":342},[88,341],[43,487,422],{"className":488,"style":489},[88,341],"margin-right:0.0359em;",[43,491,494,497],{"className":492},[493],"mclose",[43,495,427],{"className":496},[493],[43,498,500],{"className":499},[219],[43,501,503,524],{"className":502},[223,224],[43,504,506,521],{"className":505},[228],[43,507,510],{"className":508,"style":509},[232],"height:0.3283em;",[43,511,512,515],{"style":236},[43,513],{"className":514,"style":241},[240],[43,516,518],{"className":517},[245,246,247,248],[43,519,324],{"className":520,"style":389},[88,341,248],[43,522,256],{"className":523},[255],[43,525,527],{"className":526},[228],[43,528,530],{"className":529,"style":263},[232],[43,531],{},[43,533],{"className":534,"style":351},[346],[43,536,432],{"className":537},[355],[43,539],{"className":540,"style":351},[346],[43,542,544,547,550,553,556,559,562,565],{"className":543},[79],[43,545],{"className":546,"style":461},[83],[43,548,406],{"className":549},[465],[43,551,411],{"className":552},[88,341],[43,554,414],{"className":555},[475],[43,557],{"className":558,"style":479},[346],[43,560],{"className":561,"style":479},[346],[43,563,422],{"className":564,"style":489},[88,341],[43,566,568,571],{"className":567},[493],[43,569,427],{"className":570},[493],[43,572,574],{"className":573},[219],[43,575,577,597],{"className":576},[223,224],[43,578,580,594],{"className":579},[228],[43,581,583],{"className":582,"style":509},[232],[43,584,585,588],{"style":236},[43,586],{"className":587,"style":241},[240],[43,589,591],{"className":590},[245,246,247,248],[43,592,318],{"className":593},[88,341,248],[43,595,256],{"className":596},[255],[43,598,600],{"className":599},[228],[43,601,603],{"className":602,"style":263},[232],[43,604],{},". Как следствие — сохраняются ",[36,607,608],{},"все"," расстояния, углы и геометрические свойства.",[123,611,613],{"id":612},"главный-вывод","Главный вывод",[14,615,276,616,619,620,684,685,898,899,1052],{},[36,617,618],{},"ровно одно"," (с точностью до изоморфизма) бесконечномерное сепарабельное гильбертово пространство. Канонический представитель этого единственного класса — пространство ",[43,621,623,644],{"className":622},[46],[43,624,626],{"className":625},[50],[52,627,628],{"xmlns":54},[56,629,630,641],{},[59,631,632],{},[633,634,635,638],"msup",{},[62,636,637],{"mathvariant":191},"ℓ",[194,639,640],{},"2",[67,642,643],{"encoding":69},"\\ell^2",[43,645,647],{"className":646,"ariaHidden":75},[74],[43,648,650,654],{"className":649},[79],[43,651],{"className":652,"style":653},[83],"height:0.8141em;",[43,655,657,660],{"className":656},[88],[43,658,637],{"className":659},[88],[43,661,663],{"className":662},[219],[43,664,666],{"className":665},[223],[43,667,669],{"className":668},[228],[43,670,672],{"className":671,"style":653},[232],[43,673,675,678],{"style":674},"top:-3.063em;margin-right:0.05em;",[43,676],{"className":677,"style":241},[240],[43,679,681],{"className":680},[245,246,247,248],[43,682,640],{"className":683},[88,248],": бесконечные последовательности ",[43,686,688,738],{"className":687},[46],[43,689,691],{"className":690},[50],[52,692,693],{"xmlns":54},[56,694,695,735],{},[59,696,697,700,708,710,716,718,725,727,730,732],{},[311,698,699],{"stretchy":405},"(",[187,701,702,705],{},[62,703,704],{},"a",[194,706,707],{},"1",[311,709,414],{"separator":75},[187,711,712,714],{},[62,713,704],{},[194,715,640],{},[311,717,414],{"separator":75},[187,719,720,722],{},[62,721,704],{},[194,723,724],{},"3",[311,726,414],{"separator":75},[311,728,729],{},"…",[307,731,417],{},[311,733,734],{"stretchy":405},")",[67,736,737],{"encoding":69},"(a_1, a_2, a_3, \\dots)",[43,739,741],{"className":740,"ariaHidden":75},[74],[43,742,744,747,750,790,793,796,836,839,842,882,885,888,892,895],{"className":743},[79],[43,745],{"className":746,"style":461},[83],[43,748,699],{"className":749},[465],[43,751,753,756],{"className":752},[88],[43,754,704],{"className":755},[88,341],[43,757,759],{"className":758},[219],[43,760,762,782],{"className":761},[223,224],[43,763,765,779],{"className":764},[228],[43,766,768],{"className":767,"style":233},[232],[43,769,770,773],{"style":236},[43,771],{"className":772,"style":241},[240],[43,774,776],{"className":775},[245,246,247,248],[43,777,707],{"className":778},[88,248],[43,780,256],{"className":781},[255],[43,783,785],{"className":784},[228],[43,786,788],{"className":787,"style":263},[232],[43,789],{},[43,791,414],{"className":792},[475],[43,794],{"className":795,"style":479},[346],[43,797,799,802],{"className":798},[88],[43,800,704],{"className":801},[88,341],[43,803,805],{"className":804},[219],[43,806,808,828],{"className":807},[223,224],[43,809,811,825],{"className":810},[228],[43,812,814],{"className":813,"style":233},[232],[43,815,816,819],{"style":236},[43,817],{"className":818,"style":241},[240],[43,820,822],{"className":821},[245,246,247,248],[43,823,640],{"className":824},[88,248],[43,826,256],{"className":827},[255],[43,829,831],{"className":830},[228],[43,832,834],{"className":833,"style":263},[232],[43,835],{},[43,837,414],{"className":838},[475],[43,840],{"className":841,"style":479},[346],[43,843,845,848],{"className":844},[88],[43,846,704],{"className":847},[88,341],[43,849,851],{"className":850},[219],[43,852,854,874],{"className":853},[223,224],[43,855,857,871],{"className":856},[228],[43,858,860],{"className":859,"style":233},[232],[43,861,862,865],{"style":236},[43,863],{"className":864,"style":241},[240],[43,866,868],{"className":867},[245,246,247,248],[43,869,724],{"className":870},[88,248],[43,872,256],{"className":873},[255],[43,875,877],{"className":876},[228],[43,878,880],{"className":879,"style":263},[232],[43,881],{},[43,883,414],{"className":884},[475],[43,886],{"className":887,"style":479},[346],[43,889,729],{"className":890},[891],"minner",[43,893],{"className":894,"style":479},[346],[43,896,734],{"className":897},[493],", для которых ",[43,900,902,939],{"className":901},[46],[43,903,905],{"className":904},[50],[52,906,907],{"xmlns":54},[56,908,909,936],{},[59,910,911,914,917,924,930,933],{},[311,912,913],{},"∑",[62,915,916],{"mathvariant":191},"∣",[187,918,919,921],{},[62,920,704],{},[62,922,923],{},"k",[633,925,926,928],{},[62,927,916],{"mathvariant":191},[194,929,640],{},[311,931,932],{},"\u003C",[62,934,935],{"mathvariant":191},"∞",[67,937,938],{"encoding":69},"\\sum |a_k|^2 \u003C \\infty",[43,940,942,1042],{"className":941,"ariaHidden":75},[74],[43,943,945,949,956,959,962,1004,1033,1036,1039],{"className":944},[79],[43,946],{"className":947,"style":948},[83],"height:1.0641em;vertical-align:-0.25em;",[43,950,913],{"className":951,"style":955},[952,953,954],"mop","op-symbol","small-op","position:relative;top:0em;",[43,957],{"className":958,"style":479},[346],[43,960,916],{"className":961},[88],[43,963,965,968],{"className":964},[88],[43,966,704],{"className":967},[88,341],[43,969,971],{"className":970},[219],[43,972,974,996],{"className":973},[223,224],[43,975,977,993],{"className":976},[228],[43,978,981],{"className":979,"style":980},[232],"height:0.3361em;",[43,982,983,986],{"style":236},[43,984],{"className":985,"style":241},[240],[43,987,989],{"className":988},[245,246,247,248],[43,990,923],{"className":991,"style":992},[88,341,248],"margin-right:0.0315em;",[43,994,256],{"className":995},[255],[43,997,999],{"className":998},[228],[43,1000,1002],{"className":1001,"style":263},[232],[43,1003],{},[43,1005,1007,1010],{"className":1006},[88],[43,1008,916],{"className":1009},[88],[43,1011,1013],{"className":1012},[219],[43,1014,1016],{"className":1015},[223],[43,1017,1019],{"className":1018},[228],[43,1020,1022],{"className":1021,"style":653},[232],[43,1023,1024,1027],{"style":674},[43,1025],{"className":1026,"style":241},[240],[43,1028,1030],{"className":1029},[245,246,247,248],[43,1031,640],{"className":1032},[88,248],[43,1034],{"className":1035,"style":351},[346],[43,1037,932],{"className":1038},[355],[43,1040],{"className":1041,"style":351},[346],[43,1043,1045,1049],{"className":1044},[79],[43,1046],{"className":1047,"style":1048},[83],"height:0.4306em;",[43,1050,935],{"className":1051},[88],".",[14,1054,1055,1056,1084,1085,1113,1114,1117],{},"Какими бы экзотическими ни казались элементы пространства ",[43,1057,1059,1072],{"className":1058},[46],[43,1060,1062],{"className":1061},[50],[52,1063,1064],{"xmlns":54},[56,1065,1066,1070],{},[59,1067,1068],{},[62,1069,318],{},[67,1071,318],{"encoding":69},[43,1073,1075],{"className":1074,"ariaHidden":75},[74],[43,1076,1078,1081],{"className":1077},[79],[43,1079],{"className":1080,"style":337},[83],[43,1082,318],{"className":1083},[88,341]," (гладкие функции, решения дифференциальных уравнений) и пространства ",[43,1086,1088,1101],{"className":1087},[46],[43,1089,1091],{"className":1090},[50],[52,1092,1093],{"xmlns":54},[56,1094,1095,1099],{},[59,1096,1097],{},[62,1098,324],{},[67,1100,324],{"encoding":69},[43,1102,1104],{"className":1103,"ariaHidden":75},[74],[43,1105,1107,1110],{"className":1106},[79],[43,1108],{"className":1109,"style":337},[83],[43,1111,324],{"className":1112,"style":389},[88,341]," (бесконечные матрицы, ряды Фурье), между ними ",[36,1115,1116],{},"всегда"," существует единственный по структуре «математический переводчик».",[11,1119,1120],{},[14,1121,1122,1125,1126,1129,1130,1133],{},[36,1123,1124],{},"Любопытный факт."," Для ",[17,1127,1128],{},"несепарабельных"," гильбертовых пространств теорема ",[36,1131,1132],{},"не работает",": их существует бесконечно много попарно неизоморфных классов, каждый из которых определяется своей (несчётной) размерностью. Сепарабельность — ключевое ограничение, делающее мир бесконечномерных пространств «одноэтажным».",[21,1135],{},[24,1137,1139],{"id":1138},"_2-повседневная-жизнь-цифровая-обработка-сигналов-и-сжатие-данных","2. Повседневная жизнь: цифровая обработка сигналов и сжатие данных",[14,1141,1142,1143,1146,1147,1150],{},"В инженерном мире теорема позволяет переходить от непрерывных физических процессов к дискретным цифровым кодам ",[36,1144,1145],{},"без потери геометрической структуры",". Мостом служит ",[36,1148,1149],{},"теорема Рисса — Фишера"," (1907), устанавливающая изометрический изоморфизм",[14,1152,1153],{},[43,1154,1156,1203],{"className":1155},[46],[43,1157,1159],{"className":1158},[50],[52,1160,1161],{"xmlns":54},[56,1162,1163,1200],{},[59,1164,1165,1172,1175,1177,1179,1181,1184,1187,1190,1192,1198],{},[633,1166,1167,1170],{},[62,1168,1169],{},"L",[194,1171,640],{},[311,1173,1174],{"stretchy":405},"[",[194,1176,196],{},[311,1178,414],{"separator":75},[194,1180,707],{},[311,1182,1183],{"stretchy":405},"]",[307,1185,1186],{},"  ",[311,1188,1189],{},"≅",[307,1191,1186],{},[633,1193,1194,1196],{},[62,1195,637],{"mathvariant":191},[194,1197,640],{},[311,1199,414],{"separator":75},[67,1201,1202],{"encoding":69},"L^2[0,1] \\;\\cong\\; \\ell^2,",[43,1204,1206,1274],{"className":1205,"ariaHidden":75},[74],[43,1207,1209,1212,1241,1244,1247,1250,1253,1256,1259,1262,1265,1268,1271],{"className":1208},[79],[43,1210],{"className":1211,"style":948},[83],[43,1213,1215,1218],{"className":1214},[88],[43,1216,1169],{"className":1217},[88,341],[43,1219,1221],{"className":1220},[219],[43,1222,1224],{"className":1223},[223],[43,1225,1227],{"className":1226},[228],[43,1228,1230],{"className":1229,"style":653},[232],[43,1231,1232,1235],{"style":674},[43,1233],{"className":1234,"style":241},[240],[43,1236,1238],{"className":1237},[245,246,247,248],[43,1239,640],{"className":1240},[88,248],[43,1242,1174],{"className":1243},[465],[43,1245,196],{"className":1246},[88],[43,1248,414],{"className":1249},[475],[43,1251],{"className":1252,"style":479},[346],[43,1254,707],{"className":1255},[88],[43,1257,1183],{"className":1258},[493],[43,1260],{"className":1261,"style":351},[346],[43,1263],{"className":1264,"style":351},[346],[43,1266,1189],{"className":1267},[355],[43,1269],{"className":1270,"style":351},[346],[43,1272],{"className":1273,"style":351},[346],[43,1275,1277,1281,1310],{"className":1276},[79],[43,1278],{"className":1279,"style":1280},[83],"height:1.0085em;vertical-align:-0.1944em;",[43,1282,1284,1287],{"className":1283},[88],[43,1285,637],{"className":1286},[88],[43,1288,1290],{"className":1289},[219],[43,1291,1293],{"className":1292},[223],[43,1294,1296],{"className":1295},[228],[43,1297,1299],{"className":1298,"style":653},[232],[43,1300,1301,1304],{"style":674},[43,1302],{"className":1303,"style":241},[240],[43,1305,1307],{"className":1306},[245,246,247,248],[43,1308,640],{"className":1309},[88,248],[43,1311,414],{"className":1312},[475],[14,1314,1315,1316,1319],{},"то есть пространство интегрируемых с квадратом функций и пространство числовых последовательностей — ",[17,1317,1318],{},"одно и то же"," гильбертово пространство, записанное в разных координатах.",[123,1321,1323],{"id":1322},"алгоритм-jpeg-и-дискретное-косинусное-преобразование","Алгоритм JPEG и дискретное косинусное преобразование",[14,1325,1326],{},"Когда камера смартфона фиксирует закатное небо, она «видит» непрерывную функцию яркости и цвета. Чтобы сохранить снимок:",[1328,1329,1330,1395,1401,1465,1471],"ol",{},[1331,1332,1333,1336,1337,1394],"li",{},[36,1334,1335],{},"Разбиение."," Изображение нарезается на блоки ",[43,1338,1340,1360],{"className":1339},[46],[43,1341,1343],{"className":1342},[50],[52,1344,1345],{"xmlns":54},[56,1346,1347,1357],{},[59,1348,1349,1352,1355],{},[194,1350,1351],{},"8",[311,1353,1354],{},"×",[194,1356,1351],{},[67,1358,1359],{"encoding":69},"8 \\times 8",[43,1361,1363,1384],{"className":1362,"ariaHidden":75},[74],[43,1364,1366,1370,1373,1377,1381],{"className":1365},[79],[43,1367],{"className":1368,"style":1369},[83],"height:0.7278em;vertical-align:-0.0833em;",[43,1371,1351],{"className":1372},[88],[43,1374],{"className":1375,"style":1376},[346],"margin-right:0.2222em;",[43,1378,1354],{"className":1379},[1380],"mbin",[43,1382],{"className":1383,"style":1376},[346],[43,1385,1387,1391],{"className":1386},[79],[43,1388],{"className":1389,"style":1390},[83],"height:0.6444em;",[43,1392,1351],{"className":1393},[88]," пикселей.",[1331,1396,1397,1400],{},[36,1398,1399],{},"Выбор базиса."," Каждый блок раскладывается по ортонормированному базису дискретного косинусного преобразования (ДКП) — набору «волн» разной частоты и ориентации.",[1331,1402,1403,1406,1407,1052],{},[36,1404,1405],{},"Изоморфизм."," Непрерывная картинка превращается в набор из 64 коэффициентов на блок — координат в ",[43,1408,1410,1427],{"className":1409},[46],[43,1411,1413],{"className":1412},[50],[52,1414,1415],{"xmlns":54},[56,1416,1417,1425],{},[59,1418,1419],{},[633,1420,1421,1423],{},[62,1422,637],{"mathvariant":191},[194,1424,640],{},[67,1426,643],{"encoding":69},[43,1428,1430],{"className":1429,"ariaHidden":75},[74],[43,1431,1433,1436],{"className":1432},[79],[43,1434],{"className":1435,"style":653},[83],[43,1437,1439,1442],{"className":1438},[88],[43,1440,637],{"className":1441},[88],[43,1443,1445],{"className":1444},[219],[43,1446,1448],{"className":1447},[223],[43,1449,1451],{"className":1450},[228],[43,1452,1454],{"className":1453,"style":653},[232],[43,1455,1456,1459],{"style":674},[43,1457],{"className":1458,"style":241},[240],[43,1460,1462],{"className":1461},[245,246,247,248],[43,1463,640],{"className":1464},[88,248],[1331,1466,1467,1470],{},[36,1468,1469],{},"Квантование."," Человеческий глаз нечувствителен к мелкой высокочастотной ряби, поэтому коэффициенты, отвечающие за неё, обнуляются или огрубляются.",[1331,1472,1473,1476],{},[36,1474,1475],{},"Обратное преобразование."," По оставшимся коэффициентам восстанавливается изображение.",[14,1478,1479,1480,1483,1484,1668,1669,1672],{},"Благодаря ",[36,1481,1482],{},"равенству Парсеваля"," (изометрии ",[43,1485,1487,1530],{"className":1486},[46],[43,1488,1490],{"className":1489},[50],[52,1491,1492],{"xmlns":54},[56,1493,1494,1527],{},[59,1495,1496,1499,1502,1508,1510,1512,1514,1521],{},[62,1497,1498],{"mathvariant":191},"∥",[62,1500,1501],{},"f",[633,1503,1504,1506],{},[62,1505,1498],{"mathvariant":191},[194,1507,640],{},[311,1509,432],{},[311,1511,913],{},[62,1513,916],{"mathvariant":191},[187,1515,1516,1519],{},[62,1517,1518],{},"c",[62,1520,923],{},[633,1522,1523,1525],{},[62,1524,916],{"mathvariant":191},[194,1526,640],{},[67,1528,1529],{"encoding":69},"\\|f\\|^2 = \\sum |c_k|^2",[43,1531,1533,1584],{"className":1532,"ariaHidden":75},[74],[43,1534,1536,1539,1542,1546,1575,1578,1581],{"className":1535},[79],[43,1537],{"className":1538,"style":948},[83],[43,1540,1498],{"className":1541},[88],[43,1543,1501],{"className":1544,"style":1545},[88,341],"margin-right:0.1076em;",[43,1547,1549,1552],{"className":1548},[88],[43,1550,1498],{"className":1551},[88],[43,1553,1555],{"className":1554},[219],[43,1556,1558],{"className":1557},[223],[43,1559,1561],{"className":1560},[228],[43,1562,1564],{"className":1563,"style":653},[232],[43,1565,1566,1569],{"style":674},[43,1567],{"className":1568,"style":241},[240],[43,1570,1572],{"className":1571},[245,246,247,248],[43,1573,640],{"className":1574},[88,248],[43,1576],{"className":1577,"style":351},[346],[43,1579,432],{"className":1580},[355],[43,1582],{"className":1583,"style":351},[346],[43,1585,1587,1590,1593,1596,1599,1639],{"className":1586},[79],[43,1588],{"className":1589,"style":948},[83],[43,1591,913],{"className":1592,"style":955},[952,953,954],[43,1594],{"className":1595,"style":479},[346],[43,1597,916],{"className":1598},[88],[43,1600,1602,1605],{"className":1601},[88],[43,1603,1518],{"className":1604},[88,341],[43,1606,1608],{"className":1607},[219],[43,1609,1611,1631],{"className":1610},[223,224],[43,1612,1614,1628],{"className":1613},[228],[43,1615,1617],{"className":1616,"style":980},[232],[43,1618,1619,1622],{"style":236},[43,1620],{"className":1621,"style":241},[240],[43,1623,1625],{"className":1624},[245,246,247,248],[43,1626,923],{"className":1627,"style":992},[88,341,248],[43,1629,256],{"className":1630},[255],[43,1632,1634],{"className":1633},[228],[43,1635,1637],{"className":1636,"style":263},[232],[43,1638],{},[43,1640,1642,1645],{"className":1641},[88],[43,1643,916],{"className":1644},[88],[43,1646,1648],{"className":1647},[219],[43,1649,1651],{"className":1650},[223],[43,1652,1654],{"className":1653},[228],[43,1655,1657],{"className":1656,"style":653},[232],[43,1658,1659,1662],{"style":674},[43,1660],{"className":1661,"style":241},[240],[43,1663,1665],{"className":1664},[245,246,247,248],[43,1666,640],{"className":1667},[88,248],") энергия сигнала распределяется предсказуемо, и отбрасывание «незначимых» компонент не разрушает общую структуру. Итог: файл в ",[36,1670,1671],{},"10–20 раз"," меньше при визуально неотличимом качестве.",[11,1674,1675],{},[14,1676,1677,1678,1681,1682,1685,1686,1715,1716,1719,1720,1723],{},"Тот же принцип изоморфизма лежит в основе ",[36,1679,1680],{},"MP3\u002FAAC"," (аудио), ",[36,1683,1684],{},"МРТ-сканирования"," (пространство ",[43,1687,1689,1702],{"className":1688},[46],[43,1690,1692],{"className":1691},[50],[52,1693,1694],{"xmlns":54},[56,1695,1696,1700],{},[59,1697,1698],{},[62,1699,923],{},[67,1701,923],{"encoding":69},[43,1703,1705],{"className":1704,"ariaHidden":75},[74],[43,1706,1708,1712],{"className":1707},[79],[43,1709],{"className":1710,"style":1711},[83],"height:0.6944em;",[43,1713,923],{"className":1714,"style":992},[88,341],"-частот изоморфно пространству изображений), ",[36,1717,1718],{},"вейвлет-сжатия"," и ",[36,1721,1722],{},"адаптивного шумоподавления"," в наушниках.",[21,1725],{},[24,1727,1729],{"id":1728},"_3-масштаб-вселенной-квантовая-механика-и-чёрные-дыры","3. Масштаб Вселенной: квантовая механика и чёрные дыры",[14,1731,1732,1733,1052],{},"В физике изоморфизм гильбертовых пространств не просто упрощает расчёты — он ",[36,1734,1735],{},"объединяет альтернативные картины реальности",[1737,1738,1744],"pre",{"className":1739,"code":1741,"language":1742,"meta":1743},[1740],"language-text","   [ Квантовое состояние системы ]\n                 |\n      +----------+----------+\n      |                     |\n(Унитарное            (Унитарное\nотображение)          отображение)\n      v                     v\n[ Пространство L² ] [ Пространство ℓ² ]\n  Волновая функция   Векторы и матрицы\n(Э. Шрёдингер, 1926) (В. Гейзенберг, 1925)\n","text","",[1745,1746,1741],"code",{"__ignoreMap":1743},[123,1748,1750],{"id":1749},"разрешение-спора-шрёдингера-и-гейзенберга","Разрешение спора Шрёдингера и Гейзенберга",[14,1752,1753,1754,1812,1813,1858,1859,1918],{},"В середине 1920-х годов Вернер Гейзенберг описал квантовую систему через бесконечные матрицы и векторы-последовательности (",[43,1755,1757,1774],{"className":1756},[46],[43,1758,1760],{"className":1759},[50],[52,1761,1762],{"xmlns":54},[56,1763,1764,1772],{},[59,1765,1766],{},[633,1767,1768,1770],{},[62,1769,637],{"mathvariant":191},[194,1771,640],{},[67,1773,643],{"encoding":69},[43,1775,1777],{"className":1776,"ariaHidden":75},[74],[43,1778,1780,1783],{"className":1779},[79],[43,1781],{"className":1782,"style":653},[83],[43,1784,1786,1789],{"className":1785},[88],[43,1787,637],{"className":1788},[88],[43,1790,1792],{"className":1791},[219],[43,1793,1795],{"className":1794},[223],[43,1796,1798],{"className":1797},[228],[43,1799,1801],{"className":1800,"style":653},[232],[43,1802,1803,1806],{"style":674},[43,1804],{"className":1805,"style":241},[240],[43,1807,1809],{"className":1808},[245,246,247,248],[43,1810,640],{"className":1811},[88,248],"), а Эрвин Шрёдингер — через непрерывные волновые функции ",[43,1814,1816,1837],{"className":1815},[46],[43,1817,1819],{"className":1818},[50],[52,1820,1821],{"xmlns":54},[56,1822,1823,1834],{},[59,1824,1825,1828,1830,1832],{},[62,1826,1827],{},"ψ",[311,1829,699],{"stretchy":405},[62,1831,411],{},[311,1833,734],{"stretchy":405},[67,1835,1836],{"encoding":69},"\\psi(x)",[43,1838,1840],{"className":1839,"ariaHidden":75},[74],[43,1841,1843,1846,1849,1852,1855],{"className":1842},[79],[43,1844],{"className":1845,"style":461},[83],[43,1847,1827],{"className":1848,"style":489},[88,341],[43,1850,699],{"className":1851},[465],[43,1853,411],{"className":1854},[88,341],[43,1856,734],{"className":1857},[493]," и дифференциальные уравнения (",[43,1860,1862,1880],{"className":1861},[46],[43,1863,1865],{"className":1864},[50],[52,1866,1867],{"xmlns":54},[56,1868,1869,1877],{},[59,1870,1871],{},[633,1872,1873,1875],{},[62,1874,1169],{},[194,1876,640],{},[67,1878,1879],{"encoding":69},"L^2",[43,1881,1883],{"className":1882,"ariaHidden":75},[74],[43,1884,1886,1889],{"className":1885},[79],[43,1887],{"className":1888,"style":653},[83],[43,1890,1892,1895],{"className":1891},[88],[43,1893,1169],{"className":1894},[88,341],[43,1896,1898],{"className":1897},[219],[43,1899,1901],{"className":1900},[223],[43,1902,1904],{"className":1903},[228],[43,1905,1907],{"className":1906,"style":653},[232],[43,1908,1909,1912],{"style":674},[43,1910],{"className":1911,"style":241},[240],[43,1913,1915],{"className":1914},[245,246,247,248],[43,1916,640],{"className":1917},[88,248],"). Казалось, это две разные физики.",[14,1920,1921,1922,1925,1926,1929],{},"В 1932 году Джон фон Нейман в монографии ",[17,1923,1924],{},"«Математические основы квантовой механики»"," применил теорему об изоморфизме и доказал: ",[36,1927,1928],{},"матричная и волновая механика математически тождественны",". Физик волен выбирать — считать сложные интегралы или перемножать матрицы; вероятность любого исхода будет одной и той же.",[11,1931,1932],{},[14,1933,1934,1937,1938,1941,1942,2000],{},[36,1935,1936],{},"Иллюстрация."," Квантовая частица в прямоугольной яме и квантовый гармонический осциллятор выглядят совершенно по-разному: разные потенциалы, разные уравнения, разные волновые функции. Но их гильбертовы пространства состояний ",[36,1939,1940],{},"изоморфны"," ",[43,1943,1945,1962],{"className":1944},[46],[43,1946,1948],{"className":1947},[50],[52,1949,1950],{"xmlns":54},[56,1951,1952,1960],{},[59,1953,1954],{},[633,1955,1956,1958],{},[62,1957,637],{"mathvariant":191},[194,1959,640],{},[67,1961,643],{"encoding":69},[43,1963,1965],{"className":1964,"ariaHidden":75},[74],[43,1966,1968,1971],{"className":1967},[79],[43,1969],{"className":1970,"style":653},[83],[43,1972,1974,1977],{"className":1973},[88],[43,1975,637],{"className":1976},[88],[43,1978,1980],{"className":1979},[219],[43,1981,1983],{"className":1982},[223],[43,1984,1986],{"className":1985},[228],[43,1987,1989],{"className":1988,"style":653},[232],[43,1990,1991,1994],{"style":674},[43,1992],{"className":1993,"style":241},[240],[43,1995,1997],{"className":1996},[245,246,247,248],[43,1998,640],{"className":1999},[88,248],". С точки зрения абстрактной структуры — это одна и та же система.",[123,2002,2004],{"id":2003},"adscft-соответствие-и-голографический-принцип","AdS\u002FCFT-соответствие и голографический принцип",[14,2006,2007,2008,2011,2012,313],{},"На экстремальных масштабах — в теории квантовой гравитации — идея изоморфизма принимает форму ",[36,2009,2010],{},"гипотезы Хуана Малдасены"," (1997), известной как ",[36,2013,2014],{},"AdS\u002FCFT-дуальность",[2016,2017,2018,2024],"ul",{},[1331,2019,2020,2023],{},[36,2021,2022],{},"Мир А"," — объём анти-де-ситтеровского пространства (AdS): есть гравитация, искривление пространства-времени, чёрные дыры.",[1331,2025,2026,2029],{},[36,2027,2028],{},"Мир Б"," — граница этого пространства, на которой живёт конформная теория поля (CFT): гравитации нет, только квантовые частицы.",[14,2031,2032,2033,2036],{},"Гильбертовы пространства состояний этих двух миров изоморфны. Трёхмерный (и более) мир с гравитацией ",[36,2034,2035],{},"полностью кодируется"," на двумерной границе без потери информации — подобно голограмме.",[11,2038,2039],{},[14,2040,2041,2044,2045,2048],{},[36,2042,2043],{},"Важная оговорка."," В отличие от теоремы фон Неймана, AdS\u002FCFT остаётся ",[36,2046,2047],{},"гипотезой"," (хотя и подтверждённой тысячами непротиворечивых проверок). Строгого доказательства для физически реалистичных случаев пока нет. Тем не менее структурная логика здесь та же: два внешне несхожих описания оказываются одним пространством в разных координатах.",[123,2050,2052],{"id":2051},"информационный-парадокс-чёрных-дыр","Информационный парадокс чёрных дыр",[14,2054,2055,2056,2059],{},"Когда материя падает в чёрную дыру, а дыра затем испаряется через излучение Хокинга, возникает вопрос: куда девается информация? Общая теория относительности говорит «уничтожается», квантовая механика (закон ",[36,2057,2058],{},"унитарности",") запрещает это.",[14,2061,2062,2063,2066,2067,2070],{},"Решение, подсказанное AdS\u002FCFT: гильбертово пространство гравитационной чёрной дыры изоморфно пространству квантовых степеней свободы на её горизонте. Информация не исчезает — она ",[36,2064,2065],{},"перекодируется"," на поверхность, как трёхмерный объект кодируется на плоской голографической плёнке. В 2019–2024 гг. расчёты с использованием «островов» (",[17,2068,2069],{},"island formula",") и квантовой экстремальной поверхности дали первые количественные подтверждения этого механизма.",[21,2072],{},[24,2074,2076],{"id":2075},"_4-искусственный-интеллект-семантическая-геометрия-и-эмбеддинги","4. Искусственный интеллект: семантическая геометрия и эмбеддинги",[14,2078,2079,2080,1052],{},"Современный прорыв в области больших языковых моделей (LLM) — GPT, Claude, LLaMA — стал возможен благодаря переносу лингвистики в ",[36,2081,2082],{},"метрические векторные пространства",[123,2084,2086],{"id":2085},"векторизация-эмбеддинги","Векторизация (эмбеддинги)",[14,2088,2089,2090,1941,2093,2154,2155,2235],{},"Для компьютера слова «кошка» и «собака» — просто последовательности байтов. Чтобы научить модель рассуждать, инженеры строят отображение из хаотичного пространства языка в ",[36,2091,2092],{},"конечномерное евклидово пространство",[43,2094,2096,2115],{"className":2095},[46],[43,2097,2099],{"className":2098},[50],[52,2100,2101],{"xmlns":54},[56,2102,2103,2112],{},[59,2104,2105],{},[633,2106,2107,2109],{},[62,2108,65],{"mathvariant":64},[62,2110,2111],{},"d",[67,2113,2114],{"encoding":69},"\\mathbb{R}^d",[43,2116,2118],{"className":2117,"ariaHidden":75},[74],[43,2119,2121,2125],{"className":2120},[79],[43,2122],{"className":2123,"style":2124},[83],"height:0.8491em;",[43,2126,2128,2131],{"className":2127},[88],[43,2129,65],{"className":2130},[88,89],[43,2132,2134],{"className":2133},[219],[43,2135,2137],{"className":2136},[223],[43,2138,2140],{"className":2139},[228],[43,2141,2143],{"className":2142,"style":2124},[232],[43,2144,2145,2148],{"style":674},[43,2146],{"className":2147,"style":241},[240],[43,2149,2151],{"className":2150},[245,246,247,248],[43,2152,2111],{"className":2153},[88,341,248]," (обычно ",[43,2156,2158,2187],{"className":2157},[46],[43,2159,2161],{"className":2160},[50],[52,2162,2163],{"xmlns":54},[56,2164,2165,2184],{},[59,2166,2167,2169,2171,2174,2176,2179,2181],{},[62,2168,2111],{},[311,2170,432],{},[194,2172,2173],{},"768",[311,2175,729],{},[194,2177,2178],{},"15",[307,2180,417],{},[194,2182,2183],{},"360",[67,2185,2186],{"encoding":69},"d = 768 \\ldots 15\\,360",[43,2188,2190,2208],{"className":2189,"ariaHidden":75},[74],[43,2191,2193,2196,2199,2202,2205],{"className":2192},[79],[43,2194],{"className":2195,"style":1711},[83],[43,2197,2111],{"className":2198},[88,341],[43,2200],{"className":2201,"style":351},[346],[43,2203,432],{"className":2204},[355],[43,2206],{"className":2207,"style":351},[346],[43,2209,2211,2214,2217,2220,2223,2226,2229,2232],{"className":2210},[79],[43,2212],{"className":2213,"style":1390},[83],[43,2215,2173],{"className":2216},[88],[43,2218],{"className":2219,"style":479},[346],[43,2221,729],{"className":2222},[891],[43,2224],{"className":2225,"style":479},[346],[43,2227,2178],{"className":2228},[88],[43,2230],{"className":2231,"style":479},[346],[43,2233,2183],{"className":2234},[88],"), которое формально тоже является гильбертовым пространством.",[14,2237,2238,2239,2242,2243,2246],{},"Каждое слово или концепт становится ",[36,2240,2241],{},"вектором"," — точкой в этом пространстве. Ключевое свойство: близкие по смыслу понятия оказываются геометрически близкими. Скалярное произведение (точнее, ",[36,2244,2245],{},"косинусное сходство",") отражает семантическую связь:",[14,2248,2249],{},[43,2250,2252,2322],{"className":2251},[46],[43,2253,2255],{"className":2254},[50],[52,2256,2257],{"xmlns":54},[56,2258,2259,2319],{},[59,2260,2261,2264,2267,2270,2272],{},[62,2262,2263],{},"cos",[311,2265,2266],{},"⁡",[62,2268,2269],{},"θ",[311,2271,432],{},[2273,2274,2275,2295],"mfrac",{},[59,2276,2277,2285,2288],{},[2278,2279,2280,2282],"mover",{"accent":75},[62,2281,704],{},[311,2283,2284],{},"⃗",[311,2286,2287],{},"⋅",[2278,2289,2290,2293],{"accent":75},[62,2291,2292],{},"b",[311,2294,2284],{},[59,2296,2297,2299,2305,2307,2309,2311,2317],{},[62,2298,916],{"mathvariant":191},[2278,2300,2301,2303],{"accent":75},[62,2302,704],{},[311,2304,2284],{},[62,2306,916],{"mathvariant":191},[307,2308,417],{},[62,2310,916],{"mathvariant":191},[2278,2312,2313,2315],{"accent":75},[62,2314,2292],{},[311,2316,2284],{},[62,2318,916],{"mathvariant":191},[67,2320,2321],{"encoding":69},"\\cos\\theta = \\frac{\\vec{a}\\cdot\\vec{b}}{|\\vec{a}|\\,|\\vec{b}|}",[43,2323,2325,2350],{"className":2324,"ariaHidden":75},[74],[43,2326,2328,2331,2334,2337,2341,2344,2347],{"className":2327},[79],[43,2329],{"className":2330,"style":1711},[83],[43,2332,2263],{"className":2333},[952],[43,2335],{"className":2336,"style":479},[346],[43,2338,2269],{"className":2339,"style":2340},[88,341],"margin-right:0.0278em;",[43,2342],{"className":2343,"style":351},[346],[43,2345,432],{"className":2346},[355],[43,2348],{"className":2349,"style":351},[346],[43,2351,2353,2357],{"className":2352},[79],[43,2354],{"className":2355,"style":2356},[83],"height:1.7474em;vertical-align:-0.6692em;",[43,2358,2360,2364,2603],{"className":2359},[88],[43,2361],{"className":2362},[465,2363],"nulldelimiter",[43,2365,2367],{"className":2366},[2273],[43,2368,2370,2594],{"className":2369},[223,224],[43,2371,2373,2591],{"className":2372},[228],[43,2374,2377,2495,2506],{"className":2375,"style":2376},[232],"height:1.0782em;",[43,2378,2380,2384],{"style":2379},"top:-2.5058em;",[43,2381],{"className":2382,"style":2383},[240],"height:3em;",[43,2385,2387],{"className":2386},[245,246,247,248],[43,2388,2390,2393,2445,2448,2452,2455,2492],{"className":2389},[88,248],[43,2391,916],{"className":2392},[88,248],[43,2394,2397],{"className":2395},[88,2396,248],"accent",[43,2398,2400],{"className":2399},[223],[43,2401,2403],{"className":2402},[228],[43,2404,2407,2417],{"className":2405,"style":2406},[232],"height:0.714em;",[43,2408,2410,2414],{"style":2409},"top:-2.714em;",[43,2411],{"className":2412,"style":2413},[240],"height:2.714em;",[43,2415,704],{"className":2416},[88,341,248],[43,2418,2419,2422],{"style":2409},[43,2420],{"className":2421,"style":2413},[240],[43,2423,2427],{"className":2424,"style":2426},[2425],"accent-body","left:-0.2355em;",[43,2428,2432],{"className":2429,"style":2431},[2430,248],"overlay","height:0.714em;width:0.471em;",[2433,2434,2441],"svg",{"xmlns":2435,"width":2436,"height":2437,"style":2438,"viewBox":2439,"preserveAspectRatio":2440},"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","0.471em","0.714em","width:0.471em","0 0 471 714","xMinYMin",[2442,2443],"path",{"d":2444},"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",[43,2446,916],{"className":2447},[88,248],[43,2449],{"className":2450,"style":2451},[346,248],"margin-right:0.1952em;",[43,2453,916],{"className":2454},[88,248],[43,2456,2458],{"className":2457},[88,2396,248],[43,2459,2461],{"className":2460},[223],[43,2462,2464],{"className":2463},[228],[43,2465,2468,2476],{"className":2466,"style":2467},[232],"height:0.9774em;",[43,2469,2470,2473],{"style":2409},[43,2471],{"className":2472,"style":2413},[240],[43,2474,2292],{"className":2475},[88,341,248],[43,2477,2479,2482],{"style":2478},"top:-2.9774em;",[43,2480],{"className":2481,"style":2413},[240],[43,2483,2485],{"className":2484,"style":2426},[2425],[43,2486,2488],{"className":2487,"style":2431},[2430,248],[2433,2489,2490],{"xmlns":2435,"width":2436,"height":2437,"style":2438,"viewBox":2439,"preserveAspectRatio":2440},[2442,2491],{"d":2444},[43,2493,916],{"className":2494},[88,248],[43,2496,2498,2501],{"style":2497},"top:-3.23em;",[43,2499],{"className":2500,"style":2383},[240],[43,2502],{"className":2503,"style":2505},[2504],"frac-line","border-bottom-width:0.04em;",[43,2507,2509,2512],{"style":2508},"top:-3.394em;",[43,2510],{"className":2511,"style":2383},[240],[43,2513,2515],{"className":2514},[245,246,247,248],[43,2516,2518,2553,2556],{"className":2517},[88,248],[43,2519,2521],{"className":2520},[88,2396,248],[43,2522,2524],{"className":2523},[223],[43,2525,2527],{"className":2526},[228],[43,2528,2530,2538],{"className":2529,"style":2406},[232],[43,2531,2532,2535],{"style":2409},[43,2533],{"className":2534,"style":2413},[240],[43,2536,704],{"className":2537},[88,341,248],[43,2539,2540,2543],{"style":2409},[43,2541],{"className":2542,"style":2413},[240],[43,2544,2546],{"className":2545,"style":2426},[2425],[43,2547,2549],{"className":2548,"style":2431},[2430,248],[2433,2550,2551],{"xmlns":2435,"width":2436,"height":2437,"style":2438,"viewBox":2439,"preserveAspectRatio":2440},[2442,2552],{"d":2444},[43,2554,2287],{"className":2555},[1380,248],[43,2557,2559],{"className":2558},[88,2396,248],[43,2560,2562],{"className":2561},[223],[43,2563,2565],{"className":2564},[228],[43,2566,2568,2576],{"className":2567,"style":2467},[232],[43,2569,2570,2573],{"style":2409},[43,2571],{"className":2572,"style":2413},[240],[43,2574,2292],{"className":2575},[88,341,248],[43,2577,2578,2581],{"style":2478},[43,2579],{"className":2580,"style":2413},[240],[43,2582,2584],{"className":2583,"style":2426},[2425],[43,2585,2587],{"className":2586,"style":2431},[2430,248],[2433,2588,2589],{"xmlns":2435,"width":2436,"height":2437,"style":2438,"viewBox":2439,"preserveAspectRatio":2440},[2442,2590],{"d":2444},[43,2592,256],{"className":2593},[255],[43,2595,2597],{"className":2596},[228],[43,2598,2601],{"className":2599,"style":2600},[232],"height:0.6692em;",[43,2602],{},[43,2604],{"className":2605},[493,2363],[1737,2607,2610],{"className":2608,"code":2609,"language":1742,"meta":1743},[1740],"[Животные]                   [Техника]\n  • Кошка                      • Холодильник\n  • Собака                     • Телевизор\n  (малое расстояние)           (малое расстояние)\n  ←———————————— большое расстояние ————————————→\n",[1745,2611,2609],{"__ignoreMap":1743},[123,2613,2615],{"id":2614},"алгебра-смыслов","Алгебра смыслов",[14,2617,2618,2619,2622],{},"Поскольку линейная структура сохраняется, над абстрактными понятиями можно выполнять ",[36,2620,2621],{},"векторную арифметику",". Знаменитый пример из работы Миколова и соавторов (2013, word2vec):",[14,2624,2625],{},[43,2626,2628,2681],{"className":2627},[46],[43,2629,2631],{"className":2630},[50],[52,2632,2633],{"xmlns":54},[56,2634,2635,2678],{},[59,2636,2637,2644,2647,2654,2657,2664,2666,2669,2671],{},[2278,2638,2639,2642],{"accent":75},[307,2640,2641],{},"Король",[311,2643,2284],{},[311,2645,2646],{},"−",[2278,2648,2649,2652],{"accent":75},[307,2650,2651],{},"Мужчина",[311,2653,2284],{},[311,2655,2656],{},"+",[2278,2658,2659,2662],{"accent":75},[307,2660,2661],{},"Женщина",[311,2663,2284],{},[307,2665,1186],{},[311,2667,2668],{},"≈",[307,2670,1186],{},[2278,2672,2673,2676],{"accent":75},[307,2674,2675],{},"Королева",[311,2677,2284],{},[67,2679,2680],{"encoding":69},"\\vec{\\text{Король}} - \\vec{\\text{Мужчина}} + \\vec{\\text{Женщина}} \\;\\approx\\; \\vec{\\text{Королева}}",[43,2682,2684,2754,2818,2877],{"className":2683,"ariaHidden":75},[74],[43,2685,2687,2691,2745,2748,2751],{"className":2686},[79],[43,2688],{"className":2689,"style":2690},[83],"height:1.1608em;vertical-align:-0.1944em;",[43,2692,2694],{"className":2693},[88,2396],[43,2695,2697,2736],{"className":2696},[223,224],[43,2698,2700,2733],{"className":2699},[228],[43,2701,2704,2717],{"className":2702,"style":2703},[232],"height:0.9663em;",[43,2705,2707,2710],{"style":2706},"top:-3em;",[43,2708],{"className":2709,"style":2383},[240],[43,2711,2713],{"className":2712},[88,1742],[43,2714,2641],{"className":2715},[88,2716],"cyrillic_fallback",[43,2718,2720,2723],{"style":2719},"top:-3.2523em;",[43,2721],{"className":2722,"style":2383},[240],[43,2724,2726],{"className":2725,"style":2426},[2425],[43,2727,2729],{"className":2728,"style":2431},[2430],[2433,2730,2731],{"xmlns":2435,"width":2436,"height":2437,"style":2438,"viewBox":2439,"preserveAspectRatio":2440},[2442,2732],{"d":2444},[43,2734,256],{"className":2735},[255],[43,2737,2739],{"className":2738},[228],[43,2740,2743],{"className":2741,"style":2742},[232],"height:0.1944em;",[43,2744],{},[43,2746],{"className":2747,"style":1376},[346],[43,2749,2646],{"className":2750},[1380],[43,2752],{"className":2753,"style":1376},[346],[43,2755,2757,2760,2809,2812,2815],{"className":2756},[79],[43,2758],{"className":2759,"style":2690},[83],[43,2761,2763],{"className":2762},[88,2396],[43,2764,2766,2801],{"className":2765},[223,224],[43,2767,2769,2798],{"className":2768},[228],[43,2770,2772,2783],{"className":2771,"style":2703},[232],[43,2773,2774,2777],{"style":2706},[43,2775],{"className":2776,"style":2383},[240],[43,2778,2780],{"className":2779},[88,1742],[43,2781,2651],{"className":2782},[88,2716],[43,2784,2785,2788],{"style":2719},[43,2786],{"className":2787,"style":2383},[240],[43,2789,2791],{"className":2790,"style":2426},[2425],[43,2792,2794],{"className":2793,"style":2431},[2430],[2433,2795,2796],{"xmlns":2435,"width":2436,"height":2437,"style":2438,"viewBox":2439,"preserveAspectRatio":2440},[2442,2797],{"d":2444},[43,2799,256],{"className":2800},[255],[43,2802,2804],{"className":2803},[228],[43,2805,2807],{"className":2806,"style":2742},[232],[43,2808],{},[43,2810],{"className":2811,"style":1376},[346],[43,2813,2656],{"className":2814},[1380],[43,2816],{"className":2817,"style":1376},[346],[43,2819,2821,2824,2862,2865,2868,2871,2874],{"className":2820},[79],[43,2822],{"className":2823,"style":2703},[83],[43,2825,2827],{"className":2826},[88,2396],[43,2828,2830],{"className":2829},[223],[43,2831,2833],{"className":2832},[228],[43,2834,2836,2847],{"className":2835,"style":2703},[232],[43,2837,2838,2841],{"style":2706},[43,2839],{"className":2840,"style":2383},[240],[43,2842,2844],{"className":2843},[88,1742],[43,2845,2661],{"className":2846},[88,2716],[43,2848,2849,2852],{"style":2719},[43,2850],{"className":2851,"style":2383},[240],[43,2853,2855],{"className":2854,"style":2426},[2425],[43,2856,2858],{"className":2857,"style":2431},[2430],[2433,2859,2860],{"xmlns":2435,"width":2436,"height":2437,"style":2438,"viewBox":2439,"preserveAspectRatio":2440},[2442,2861],{"d":2444},[43,2863],{"className":2864,"style":351},[346],[43,2866],{"className":2867,"style":351},[346],[43,2869,2668],{"className":2870},[355],[43,2872],{"className":2873,"style":351},[346],[43,2875],{"className":2876,"style":351},[346],[43,2878,2880,2883],{"className":2879},[79],[43,2881],{"className":2882,"style":2690},[83],[43,2884,2886],{"className":2885},[88,2396],[43,2887,2889,2924],{"className":2888},[223,224],[43,2890,2892,2921],{"className":2891},[228],[43,2893,2895,2906],{"className":2894,"style":2703},[232],[43,2896,2897,2900],{"style":2706},[43,2898],{"className":2899,"style":2383},[240],[43,2901,2903],{"className":2902},[88,1742],[43,2904,2675],{"className":2905},[88,2716],[43,2907,2908,2911],{"style":2719},[43,2909],{"className":2910,"style":2383},[240],[43,2912,2914],{"className":2913,"style":2426},[2425],[43,2915,2917],{"className":2916,"style":2431},[2430],[2433,2918,2919],{"xmlns":2435,"width":2436,"height":2437,"style":2438,"viewBox":2439,"preserveAspectRatio":2440},[2442,2920],{"d":2444},[43,2922,256],{"className":2923},[255],[43,2925,2927],{"className":2926},[228],[43,2928,2930],{"className":2929,"style":2742},[232],[43,2931],{},[123,2933,2935],{"id":2934},"мультимодальность-общий-язык-для-текста-и-изображений","Мультимодальность: общий язык для текста и изображений",[14,2937,2938,2939,2942,2943,2946,2947,2950,2951,2954],{},"Модели вроде ",[36,2940,2941],{},"CLIP"," (OpenAI, 2021) строят изоморфное отображение между пространством текстовых описаний и пространством визуальных образов. Вектор фразы ",[17,2944,2945],{},"«пушистый рыжий кот»"," и вектор реальной фотографии рыжего кота указывают ",[36,2948,2949],{},"в одну и ту же сторону"," в едином скрытом пространстве (",[17,2952,2953],{},"shared embedding space",").",[14,2956,2957],{},"Именно это позволяет:",[2016,2959,2960,2963,2966],{},[1331,2961,2962],{},"генерировать изображения по текстовому запросу (Midjourney, DALL·E, Stable Diffusion);",[1331,2964,2965],{},"понимать содержание видео и находить нужный кадр по описанию;",[1331,2967,2968],{},"выполнять «поиск картинки текстом» и наоборот.",[123,2970,2972],{"id":2971},"взгляд-в-будущее-квантовое-машинное-обучение","Взгляд в будущее: квантовое машинное обучение",[14,2974,2975,2976,2979,2980,3009,3010,3070,3071,1719,3074,3077],{},"На стыке квантовой физики и ИИ рождается ",[36,2977,2978],{},"квантовое машинное обучение"," (QML). Квантовые состояния ",[43,2981,2983,2997],{"className":2982},[46],[43,2984,2986],{"className":2985},[50],[52,2987,2988],{"xmlns":54},[56,2989,2990,2995],{},[59,2991,2992],{},[62,2993,2994],{},"n",[67,2996,2994],{"encoding":69},[43,2998,3000],{"className":2999,"ariaHidden":75},[74],[43,3001,3003,3006],{"className":3002},[79],[43,3004],{"className":3005,"style":1048},[83],[43,3007,2994],{"className":3008},[88,341]," кубитов естественным образом живут в комплексном гильбертовом пространстве размерности ",[43,3011,3013,3031],{"className":3012},[46],[43,3014,3016],{"className":3015},[50],[52,3017,3018],{"xmlns":54},[56,3019,3020,3028],{},[59,3021,3022],{},[633,3023,3024,3026],{},[194,3025,640],{},[62,3027,2994],{},[67,3029,3030],{"encoding":69},"2^n",[43,3032,3034],{"className":3033,"ariaHidden":75},[74],[43,3035,3037,3041],{"className":3036},[79],[43,3038],{"className":3039,"style":3040},[83],"height:0.6644em;",[43,3042,3044,3047],{"className":3043},[88],[43,3045,640],{"className":3046},[88],[43,3048,3050],{"className":3049},[219],[43,3051,3053],{"className":3052},[223],[43,3054,3056],{"className":3055},[228],[43,3057,3059],{"className":3058,"style":3040},[232],[43,3060,3061,3064],{"style":674},[43,3062],{"className":3063,"style":241},[240],[43,3065,3067],{"className":3066},[245,246,247,248],[43,3068,2994],{"className":3069},[88,341,248],". Исследователи пытаются отображать пространства признаков больших данных непосредственно в состояния кубитов, чтобы использовать ",[36,3072,3073],{},"квантовую суперпозицию",[36,3075,3076],{},"запутанность"," для ускорения линейно-алгебраических операций (например, алгоритм HHL для решения систем линейных уравнений).",[11,3079,3080],{},[14,3081,3082,3085,3086,3089,3090,3148],{},[36,3083,3084],{},"Честная оговорка."," Речь идёт о ",[17,3087,3088],{},"конечномерных"," пространствах размерности ",[43,3091,3093,3110],{"className":3092},[46],[43,3094,3096],{"className":3095},[50],[52,3097,3098],{"xmlns":54},[56,3099,3100,3108],{},[59,3101,3102],{},[633,3103,3104,3106],{},[194,3105,640],{},[62,3107,2994],{},[67,3109,3030],{"encoding":69},[43,3111,3113],{"className":3112,"ariaHidden":75},[74],[43,3114,3116,3119],{"className":3115},[79],[43,3117],{"className":3118,"style":3040},[83],[43,3120,3122,3125],{"className":3121},[88],[43,3123,640],{"className":3124},[88],[43,3126,3128],{"className":3127},[219],[43,3129,3131],{"className":3130},[223],[43,3132,3134],{"className":3133},[228],[43,3135,3137],{"className":3136,"style":3040},[232],[43,3138,3139,3142],{"style":674},[43,3140],{"className":3141,"style":241},[240],[43,3143,3145],{"className":3144},[245,246,247,248],[43,3146,2994],{"className":3147},[88,341,248],", а не о бесконечномерных. Тем не менее сама логика — «перевести задачу в удобное гильбертово пространство, решить, перевести обратно» — прямо наследует духу теоремы, о которой эта статья. Практические преимущества QML пока продемонстрированы лишь на небольших модельных задачах, и путь к реальному ускорению для промышленных нейросетей ещё долог.",[21,3150],{},[24,3152,3154],{"id":3153},"заключение","Заключение",[14,3156,3157,3158,3161,3162,3165],{},"Теорема об изоморфизме бесконечномерных сепарабельных гильбертовых пространств — это манифест ",[36,3159,3160],{},"универсальности математики",". Она доказывает, что за бесконечным разнообразием форм нашей Вселенной — от пикселя на экране смартфона и человеческого слова до квантового перехода электрона и термодинамики чёрных дыр — скрывается ",[36,3163,3164],{},"одна и та же"," элегантная геометрическая структура.",[14,3167,3168],{},"Меняются координаты и базисы. Правила игры остаются неизменными.",[21,3170],{},[24,3172,3174],{"id":3173},"краткая-хронология-идей","Краткая хронология идей",[131,3176,3177,3187],{},[134,3178,3179],{},[137,3180,3181,3184],{},[140,3182,3183],{},"Год",[140,3185,3186],{},"Событие",[147,3188,3189,3255,3433,3441,3449,3459,3467,3475,3483],{},[137,3190,3191,3194],{},[152,3192,3193],{},"1904–1910",[152,3195,3196,3197],{},"Давид Гильберт изучает бесконечномерные квадратичные формы; рождается понятие ",[43,3198,3200,3217],{"className":3199},[46],[43,3201,3203],{"className":3202},[50],[52,3204,3205],{"xmlns":54},[56,3206,3207,3215],{},[59,3208,3209],{},[633,3210,3211,3213],{},[62,3212,637],{"mathvariant":191},[194,3214,640],{},[67,3216,643],{"encoding":69},[43,3218,3220],{"className":3219,"ariaHidden":75},[74],[43,3221,3223,3226],{"className":3222},[79],[43,3224],{"className":3225,"style":653},[83],[43,3227,3229,3232],{"className":3228},[88],[43,3230,637],{"className":3231},[88],[43,3233,3235],{"className":3234},[219],[43,3236,3238],{"className":3237},[223],[43,3239,3241],{"className":3240},[228],[43,3242,3244],{"className":3243,"style":653},[232],[43,3245,3246,3249],{"style":674},[43,3247],{"className":3248,"style":241},[240],[43,3250,3252],{"className":3251},[245,246,247,248],[43,3253,640],{"className":3254},[88,248],[137,3256,3257,3260],{},[152,3258,3259],{},"1907",[152,3261,3262,3263,3321,3322],{},"Фридьеш Рисс и Эрнст Фишер доказывают полноту ",[43,3264,3266,3283],{"className":3265},[46],[43,3267,3269],{"className":3268},[50],[52,3270,3271],{"xmlns":54},[56,3272,3273,3281],{},[59,3274,3275],{},[633,3276,3277,3279],{},[62,3278,1169],{},[194,3280,640],{},[67,3282,1879],{"encoding":69},[43,3284,3286],{"className":3285,"ariaHidden":75},[74],[43,3287,3289,3292],{"className":3288},[79],[43,3290],{"className":3291,"style":653},[83],[43,3293,3295,3298],{"className":3294},[88],[43,3296,1169],{"className":3297},[88,341],[43,3299,3301],{"className":3300},[219],[43,3302,3304],{"className":3303},[223],[43,3305,3307],{"className":3306},[228],[43,3308,3310],{"className":3309,"style":653},[232],[43,3311,3312,3315],{"style":674},[43,3313],{"className":3314,"style":241},[240],[43,3316,3318],{"className":3317},[245,246,247,248],[43,3319,640],{"className":3320},[88,248]," и изоморфизм ",[43,3323,3325,3351],{"className":3324},[46],[43,3326,3328],{"className":3327},[50],[52,3329,3330],{"xmlns":54},[56,3331,3332,3348],{},[59,3333,3334,3340,3342],{},[633,3335,3336,3338],{},[62,3337,1169],{},[194,3339,640],{},[311,3341,1189],{},[633,3343,3344,3346],{},[62,3345,637],{"mathvariant":191},[194,3347,640],{},[67,3349,3350],{"encoding":69},"L^2 \\cong \\ell^2",[43,3352,3354,3398],{"className":3353,"ariaHidden":75},[74],[43,3355,3357,3360,3389,3392,3395],{"className":3356},[79],[43,3358],{"className":3359,"style":653},[83],[43,3361,3363,3366],{"className":3362},[88],[43,3364,1169],{"className":3365},[88,341],[43,3367,3369],{"className":3368},[219],[43,3370,3372],{"className":3371},[223],[43,3373,3375],{"className":3374},[228],[43,3376,3378],{"className":3377,"style":653},[232],[43,3379,3380,3383],{"style":674},[43,3381],{"className":3382,"style":241},[240],[43,3384,3386],{"className":3385},[245,246,247,248],[43,3387,640],{"className":3388},[88,248],[43,3390],{"className":3391,"style":351},[346],[43,3393,1189],{"className":3394},[355],[43,3396],{"className":3397,"style":351},[346],[43,3399,3401,3404],{"className":3400},[79],[43,3402],{"className":3403,"style":653},[83],[43,3405,3407,3410],{"className":3406},[88],[43,3408,637],{"className":3409},[88],[43,3411,3413],{"className":3412},[219],[43,3414,3416],{"className":3415},[223],[43,3417,3419],{"className":3418},[228],[43,3420,3422],{"className":3421,"style":653},[232],[43,3423,3424,3427],{"style":674},[43,3425],{"className":3426,"style":241},[240],[43,3428,3430],{"className":3429},[245,246,247,248],[43,3431,640],{"className":3432},[88,248],[137,3434,3435,3438],{},[152,3436,3437],{},"1925–1926",[152,3439,3440],{},"Гейзенберг (матричная механика) и Шрёдингер (волновая механика)",[137,3442,3443,3446],{},[152,3444,3445],{},"1929–1932",[152,3447,3448],{},"Фон Нейман и Стоун формулируют теорему о единственности сепарабельного гильбертова пространства",[137,3450,3451,3454],{},[152,3452,3453],{},"1932",[152,3455,3456,3457],{},"Фон Нейман публикует ",[17,3458,1924],{},[137,3460,3461,3464],{},[152,3462,3463],{},"1992",[152,3465,3466],{},"Дискретное косинусное преобразование стандартизировано в JPEG (ISO\u002FIEC 10918)",[137,3468,3469,3472],{},[152,3470,3471],{},"1997",[152,3473,3474],{},"Хуан Малдасена публикует гипотезу AdS\u002FCFT",[137,3476,3477,3480],{},[152,3478,3479],{},"2013",[152,3481,3482],{},"Миколов и соавторы демонстрируют векторную алгебру слов (word2vec)",[137,3484,3485,3488],{},[152,3486,3487],{},"2021",[152,3489,3490],{},"OpenAI выпускает CLIP — мультимодальное эмбеддинг-пространство",[21,3492],{},[14,3494,3495],{},[17,3496,3497],{},"Если после прочтения вы посмотрите на JPEG-снимок заката, на уравнение Шрёдингера и на ответ чат-бота как на три проекции одного и того же бесконечномерного пространства — значит, теорема сработала ещё раз.",{"title":1743,"searchDepth":3499,"depth":3499,"links":3500},3,[3501,3506,3509,3514,3520,3521],{"id":26,"depth":3502,"text":27,"children":3503},2,[3504,3505],{"id":125,"depth":3499,"text":126},{"id":612,"depth":3499,"text":613},{"id":1138,"depth":3502,"text":1139,"children":3507},[3508],{"id":1322,"depth":3499,"text":1323},{"id":1728,"depth":3502,"text":1729,"children":3510},[3511,3512,3513],{"id":1749,"depth":3499,"text":1750},{"id":2003,"depth":3499,"text":2004},{"id":2051,"depth":3499,"text":2052},{"id":2075,"depth":3502,"text":2076,"children":3515},[3516,3517,3518,3519],{"id":2085,"depth":3499,"text":2086},{"id":2614,"depth":3499,"text":2615},{"id":2934,"depth":3499,"text":2935},{"id":2971,"depth":3499,"text":2972},{"id":3153,"depth":3502,"text":3154},{"id":3173,"depth":3502,"text":3174},"Science","\u002Fcovers\u002Fthe-unity-of-infinities.webp","2026-10-19",false,"md",{},true,"\u002Fblog\u002Fthe-unity-of-infinities",{"title":6,"description":19},"blog\u002Fthe-unity-of-infinities",[52,3533,3534,3535],"physics","llm","ai",null,"5NCbq2wBl2QPzE1LRnl7rLq1BU113fRiIcJc3T6FCEA",{"id":3539,"title":3540,"body":3541,"category":4635,"cover":4636,"date":4637,"description":4638,"draft":3525,"extension":3526,"meta":4639,"navigation":3528,"path":4640,"seo":4641,"stem":4642,"tags":4643,"updated":3536,"__hash__":4646},"blog\u002Fblog\u002Fcqrs.md","CQRS на практике: разделение команд и запросов без лишней сложности",{"type":8,"value":3542,"toc":4598},[3543,3547,3553,3575,3586,3597,3601,3642,3653,3657,3661,3668,3674,3677,3681,3684,3690,3693,3697,3700,3704,3758,3762,3806,3809,3843,3847,3850,3856,3861,3885,3889,3893,3896,3976,3979,3983,4064,4067,4071,4105,4109,4112,4116,4119,4148,4154,4165,4169,4173,4180,4237,4240,4247,4250,4316,4319,4323,4334,4338,4342,4345,4349,4356,4360,4374,4378,4381,4385,4388,4392,4412,4415,4429,4433,4497,4501,4564,4568,4571,4577,4591,4594],[24,3544,3546],{"id":3545},"что-такое-cqrs","Что такое CQRS",[14,3548,3549,3552],{},[36,3550,3551],{},"CQRS (Command Query Responsibility Segregation)"," — архитектурный паттерн, который разделяет операции над системой на два принципиально разных типа:",[2016,3554,3555,3565],{},[1331,3556,3557,3560,3561,3564],{},[36,3558,3559],{},"Command"," (команда) — действие, которое ",[17,3562,3563],{},"изменяет"," состояние системы.",[1331,3566,3567,3570,3571,3574],{},[36,3568,3569],{},"Query"," (запрос) — операция, которая ",[17,3572,3573],{},"читает"," данные, не производя изменений.",[14,3576,3577,3578,3581,3582,3585],{},"Идея не нова: ещё в 1988 году Бертран Мейер в книге ",[17,3579,3580],{},"Object-Oriented Software Construction"," сформулировал принцип ",[36,3583,3584],{},"CQS"," (Command Query Separation) на уровне отдельных методов.\nCQRS поднимает ту же идею на уровень архитектуры: команды и запросы разделяются не просто по методам, а по классам, модулям, а иногда и по целым сервисам.",[14,3587,3588,3589,3592,3593,3596],{},"Термин популяризировали ",[36,3590,3591],{},"Грег Янг"," (Greg Young) и ",[36,3594,3595],{},"Уди Дахан"," (Udi Dahan) в конце 2000-х, когда стало ясно, что в сложных доменах модели чтения и записи живут по разным правилам и пытаются ужиться в одной сущности себе в убыток.",[24,3598,3600],{"id":3599},"главный-вопрос-это-команда-или-запрос","Главный вопрос: это команда или запрос?",[131,3602,3603,3616],{},[134,3604,3605],{},[137,3606,3607,3610,3613],{},[140,3608,3609],{},"Вопрос об операции",[140,3611,3612],{},"Тип",[140,3614,3615],{},"Пример",[147,3617,3618,3630],{},[137,3619,3620,3623,3627],{},[152,3621,3622],{},"Меняет ли она данные в системе?",[152,3624,3625],{},[1745,3626,3559],{},[152,3628,3629],{},"Создание заказа, списание средств",[137,3631,3632,3635,3639],{},[152,3633,3634],{},"Только возвращает данные?",[152,3636,3637],{},[1745,3638,3569],{},[152,3640,3641],{},"Получение списка заказов, расчёт итога корзины",[14,3643,3644,3647,3648,3650,3651,1052],{},[36,3645,3646],{},"Критерий простой:"," если после операции данные в хранилище (БД, кэш, очередь) изменились — это ",[1745,3649,3559],{},".\nЕсли данные остались прежними — ",[1745,3652,3569],{},[24,3654,3656],{"id":3655},"два-уровня-cqrs","Два уровня CQRS",[123,3658,3660],{"id":3659},"лёгкий-cqrs-в-рамках-одного-сервиса","Лёгкий CQRS (в рамках одного сервиса)",[14,3662,3663,3664,3667],{},"Команды и запросы живут в одном приложении, работают с одной базой данных, но ",[36,3665,3666],{},"разделены по папкам, классам и семантике",".\nЭто самый распространённый вариант: он даёт 80 % пользы при 20 % усилий.",[1737,3669,3672],{"className":3670,"code":3671,"language":1742,"meta":1743},[1740],"Один сервис\n├── Commands → пишут в БД\n└── Queries → читают из БД\n",[1745,3673,3671],{"__ignoreMap":1743},[14,3675,3676],{},"Именно о нём пойдёт речь ниже.",[123,3678,3680],{"id":3679},"полный-cqrs-раздельные-модели","Полный CQRS (раздельные модели)",[14,3682,3683],{},"Модель записи и модель чтения физически разделены: разные базы, разные схемы, синхронизация через события.\nПрименяется в высоконагруженных системах, где нагрузка на чтение и запись отличается на порядки.",[1737,3685,3688],{"className":3686,"code":3687,"language":1742,"meta":1743},[1740],"Command Side (PostgreSQL) ──события──▶ Query Side (Elasticsearch \u002F Redis)\n",[1745,3689,3687],{"__ignoreMap":1743},[14,3691,3692],{},"Это мощный, но дорогой инструмент. Если у вас нет миллионов запросов в секунду, скорее всего, он избыточен.",[24,3694,3696],{"id":3695},"примеры-команды-и-запросы","Примеры: команды и запросы",[14,3698,3699],{},"Чтобы не привязываться к одному домену, возьмём несколько типичных.",[123,3701,3703],{"id":3702},"команды-изменяют-состояние","Команды (изменяют состояние)",[131,3705,3706,3716],{},[134,3707,3708],{},[137,3709,3710,3713],{},[140,3711,3712],{},"Команда",[140,3714,3715],{},"Что делает",[147,3717,3718,3728,3738,3748],{},[137,3719,3720,3725],{},[152,3721,3722],{},[1745,3723,3724],{},"PlaceOrderCommand",[152,3726,3727],{},"Создаёт заказ и списывает товары со склада",[137,3729,3730,3735],{},[152,3731,3732],{},[1745,3733,3734],{},"CancelSubscriptionCommand",[152,3736,3737],{},"Меняет статус подписки на «отменена»",[137,3739,3740,3745],{},[152,3741,3742],{},[1745,3743,3744],{},"ResetUserPreferencesCommand",[152,3746,3747],{},"Удаляет пользовательские настройки из кэша и БД",[137,3749,3750,3755],{},[152,3751,3752],{},[1745,3753,3754],{},"PublishArticleCommand",[152,3756,3757],{},"Переводит статью из черновика в опубликованную",[123,3759,3761],{"id":3760},"запросы-читают-данные","Запросы (читают данные)",[131,3763,3764,3774],{},[134,3765,3766],{},[137,3767,3768,3771],{},[140,3769,3770],{},"Запрос",[140,3772,3773],{},"Что возвращает",[147,3775,3776,3786,3796],{},[137,3777,3778,3783],{},[152,3779,3780],{},[1745,3781,3782],{},"GetOrderHistoryQuery",[152,3784,3785],{},"Список заказов пользователя с пагинацией",[137,3787,3788,3793],{},[152,3789,3790],{},[1745,3791,3792],{},"GetDashboardStatsQuery",[152,3794,3795],{},"Агрегированные метрики для дашборда",[137,3797,3798,3803],{},[152,3799,3800],{},[1745,3801,3802],{},"GetArticleByIdQuery",[152,3804,3805],{},"Текст и метаданные статьи",[14,3807,3808],{},"Обратите внимание на именование:",[2016,3810,3811,3831],{},[1331,3812,3813,3814,3817,3818,3821,3822,3821,3825,3821,3828,1052],{},"Команды отражают ",[36,3815,3816],{},"действие",": ",[1745,3819,3820],{},"Place",", ",[1745,3823,3824],{},"Cancel",[1745,3826,3827],{},"Reset",[1745,3829,3830],{},"Publish",[1331,3832,3833,3834,3817,3837,3821,3840,1052],{},"Запросы начинаются с ",[36,3835,3836],{},"Get",[1745,3838,3839],{},"GetOrderHistory",[1745,3841,3842],{},"GetDashboardStats",[24,3844,3846],{"id":3845},"структура-кода","Структура кода",[14,3848,3849],{},"При лёгком CQRS логично организовать папки по типу операции и по доменной области:",[1737,3851,3854],{"className":3852,"code":3853,"language":1742,"meta":1743},[1740],"Application\u002F\n├── Order\u002F\n│ ├── Command\u002F\n│ │ └── PlaceOrderCommand.php\n│ ├── CommandHandler\u002F\n│ │ └── PlaceOrderHandler.php\n│ ├── Query\u002F\n│ │ └── GetOrderHistoryQuery.php\n│ ├── QueryHandler\u002F\n│ │ └── GetOrderHistoryHandler.php\n│ └── DTO\u002F\n│   └── OrderSummary.php\n│\n├── Analytics\u002F\n│ ├── Query\u002F\n│ │ └── GetDashboardStatsQuery.php\n│ ├── QueryHandler\u002F\n│ │ ├── GetDashboardStatsHandler.php\n│ │ └── CachedGetDashboardStatsHandler.php\n│ └── DTO\u002F\n│   └── DashboardStats.php\n",[1745,3855,3853],{"__ignoreMap":1743},[14,3857,3858],{},[36,3859,3860],{},"Соглашения:",[2016,3862,3863,3873,3882],{},[1331,3864,3865,3866,3869,3870,1052],{},"Команды лежат в ",[1745,3867,3868],{},"Command\u002F",", их обработчики — в ",[1745,3871,3872],{},"CommandHandler\u002F",[1331,3874,3875,3876,3869,3879,1052],{},"Запросы лежат в ",[1745,3877,3878],{},"Query\u002F",[1745,3880,3881],{},"QueryHandler\u002F",[1331,3883,3884],{},"Каждый класс — одна операция. Никаких «универсальных» обработчиков.",[24,3886,3888],{"id":3887},"почему-это-важно","Почему это важно",[123,3890,3892],{"id":3891},"_1-явная-семантика","1. Явная семантика",[14,3894,3895],{},"По имени класса мгновенно понятно, что происходит:",[1737,3897,3901],{"className":3898,"code":3899,"language":3900,"meta":1743,"style":1743},"language-php shiki shiki-themes github-light github-dark","\u002F\u002F Очевидно: создаёт заказ, меняет состояние\n$this->handler->handle(new PlaceOrderCommand($cartId, $userId));\n\n\u002F\u002F Очевидно: только читает историю\n$this->handler->handle(new GetOrderHistoryQuery($userId, $page));\n","php",[1745,3902,3903,3911,3942,3947,3953],{"__ignoreMap":1743},[43,3904,3907],{"class":3905,"line":3906},"line",1,[43,3908,3910],{"class":3909},"sJ8bj","\u002F\u002F Очевидно: создаёт заказ, меняет состояние\n",[43,3912,3913,3917,3921,3925,3927,3931,3933,3936,3939],{"class":3905,"line":3502},[43,3914,3916],{"class":3915},"sj4cs","$this",[43,3918,3920],{"class":3919},"szBVR","->",[43,3922,3924],{"class":3923},"sVt8B","handler",[43,3926,3920],{"class":3919},[43,3928,3930],{"class":3929},"sScJk","handle",[43,3932,699],{"class":3923},[43,3934,3935],{"class":3919},"new",[43,3937,3938],{"class":3915}," PlaceOrderCommand",[43,3940,3941],{"class":3923},"($cartId, $userId));\n",[43,3943,3944],{"class":3905,"line":3499},[43,3945,3946],{"emptyLinePlaceholder":3528},"\n",[43,3948,3950],{"class":3905,"line":3949},4,[43,3951,3952],{"class":3909},"\u002F\u002F Очевидно: только читает историю\n",[43,3954,3956,3958,3960,3962,3964,3966,3968,3970,3973],{"class":3905,"line":3955},5,[43,3957,3916],{"class":3915},[43,3959,3920],{"class":3919},[43,3961,3924],{"class":3923},[43,3963,3920],{"class":3919},[43,3965,3930],{"class":3929},[43,3967,699],{"class":3923},[43,3969,3935],{"class":3919},[43,3971,3972],{"class":3915}," GetOrderHistoryQuery",[43,3974,3975],{"class":3923},"($userId, $page));\n",[14,3977,3978],{},"Читая код ревью, вы сразу видите, где система мутирует данные, а где нет.\nЭто снижает когнитивную нагрузку на порядок.",[123,3980,3982],{"id":3981},"_2-разные-стратегии-обработки","2. Разные стратегии обработки",[131,3984,3985,3996],{},[134,3986,3987],{},[137,3988,3989,3992,3994],{},[140,3990,3991],{},"Аспект",[140,3993,3559],{},[140,3995,3569],{},[147,3997,3998,4009,4020,4031,4042,4053],{},[137,3999,4000,4003,4006],{},[152,4001,4002],{},"Транзакции БД",[152,4004,4005],{},"Обязательны",[152,4007,4008],{},"Не нужны",[137,4010,4011,4014,4017],{},[152,4012,4013],{},"Кэширование",[152,4015,4016],{},"Нельзя кэшировать",[152,4018,4019],{},"Можно и нужно",[137,4021,4022,4025,4028],{},[152,4023,4024],{},"Валидация бизнес-правил",[152,4026,4027],{},"Полная",[152,4029,4030],{},"Минимальная",[137,4032,4033,4036,4039],{},[152,4034,4035],{},"Масштабирование",[152,4037,4038],{},"Master-нода БД",[152,4040,4041],{},"Read-replicas",[137,4043,4044,4047,4050],{},[152,4045,4046],{},"Идемпотентность",[152,4048,4049],{},"Нужно проектировать",[152,4051,4052],{},"Естественна",[137,4054,4055,4058,4061],{},[152,4056,4057],{},"Логирование \u002F аудит",[152,4059,4060],{},"Критично",[152,4062,4063],{},"Опционально",[14,4065,4066],{},"Кэширование команды — ошибка, которая приводит к потере данных. Кэширование запроса — оптимизация.\nРазделение исключает путаницу.",[123,4068,4070],{"id":4069},"_3-разные-модели-данных","3. Разные модели данных",[2016,4072,4073,4086,4099,4102],{},[1331,4074,4075,4078,4079,3821,4082,4085],{},[36,4076,4077],{},"Команды"," работают с доменными агрегатами (",[1745,4080,4081],{},"Order",[1745,4083,4084],{},"Subscription",") и соблюдают бизнес-инварианты.",[1331,4087,4088,4091,4092,3821,4095,4098],{},[36,4089,4090],{},"Запросы"," возвращают специализированные DTO (",[1745,4093,4094],{},"OrderSummary",[1745,4096,4097],{},"DashboardStats","), оптимизированные под конкретный экран или API-эндпоинт.",[1331,4100,4101],{},"Не нужно тянуть весь граф объектов заказа, чтобы показать пользователю список из десяти строк.",[1331,4103,4104],{},"Query-модель плоская и лёгкая.",[123,4106,4108],{"id":4107},"_4-тестируемость","4. Тестируемость",[14,4110,4111],{},"Команды тестируются через побочный эффект: «после выполнения в БД появилась запись X».\nЗапросы тестируются через возвращаемое значение: «для входных данных Y возвращается DTO Z».\nЭто разные типы тестов, и разделение позволяет не смешивать их.",[24,4113,4115],{"id":4114},"когда-граница-размывается","Когда граница размывается",[14,4117,4118],{},"Операция может и читать, и писать. Например, обработчик размещения заказа:",[1328,4120,4121,4127,4133,4142],{},[1331,4122,4123,4126],{},[36,4124,4125],{},"Читает"," состав корзины из Redis.",[1331,4128,4129,4132],{},[36,4130,4131],{},"Проверяет"," наличие товаров на складе.",[1331,4134,4135,4138,4139,4141],{},[36,4136,4137],{},"Создаёт"," запись ",[1745,4140,4081],{}," в БД.",[1331,4143,4144,4147],{},[36,4145,4146],{},"Уменьшает"," остатки на складе.",[14,4149,4150,4151,4153],{},"Это ",[1745,4152,3559],{},", потому что главное — изменение состояния. Чтение здесь вспомогательное.",[11,4155,4156],{},[14,4157,4158,4161,4162,4164],{},[36,4159,4160],{},"Правило:"," определяйте тип по конечному эффекту.\nЕсли данные изменились — ",[1745,4163,3559],{},".\nЧтение внутри команды не делает её запросом.",[24,4166,4168],{"id":4167},"связь-с-другими-паттернами","Связь с другими паттернами",[123,4170,4172],{"id":4171},"mediator-message-bus","Mediator \u002F Message Bus",[14,4174,4175,4176,4179],{},"Команды и запросы часто передаются через ",[36,4177,4178],{},"шину сообщений"," (Mediator). Вызов выглядит единообразно:",[1737,4181,4183],{"className":3898,"code":4182,"language":3900,"meta":1743,"style":1743},"$this->messageBus->dispatch(new PlaceOrderCommand(...));\n$this->messageBus->dispatch(new GetOrderHistoryQuery(...));\n",[1745,4184,4185,4213],{"__ignoreMap":1743},[43,4186,4187,4189,4191,4194,4196,4199,4201,4203,4205,4207,4210],{"class":3905,"line":3906},[43,4188,3916],{"class":3915},[43,4190,3920],{"class":3919},[43,4192,4193],{"class":3923},"messageBus",[43,4195,3920],{"class":3919},[43,4197,4198],{"class":3929},"dispatch",[43,4200,699],{"class":3923},[43,4202,3935],{"class":3919},[43,4204,3938],{"class":3915},[43,4206,699],{"class":3923},[43,4208,4209],{"class":3919},"...",[43,4211,4212],{"class":3923},"));\n",[43,4214,4215,4217,4219,4221,4223,4225,4227,4229,4231,4233,4235],{"class":3905,"line":3502},[43,4216,3916],{"class":3915},[43,4218,3920],{"class":3919},[43,4220,4193],{"class":3923},[43,4222,3920],{"class":3919},[43,4224,4198],{"class":3929},[43,4226,699],{"class":3923},[43,4228,3935],{"class":3919},[43,4230,3972],{"class":3915},[43,4232,699],{"class":3923},[43,4234,4209],{"class":3919},[43,4236,4212],{"class":3923},[14,4238,4239],{},"Шина не знает, что внутри: она просто маршрутизирует объект в нужный обработчик.\nЭто убирает жёсткую связность между контроллером и бизнес-логикой.",[123,4241,4243,4244],{"id":4242},"паттерн-__invoke","Паттерн ",[1745,4245,4246],{},"__invoke",[14,4248,4249],{},"Обработчики удобно делать «вызываемыми» объектами:",[1737,4251,4253],{"className":3898,"code":4252,"language":3900,"meta":1743,"style":1743},"final class PlaceOrderHandler\n{\n    public function __invoke(PlaceOrderCommand $command): OrderId\n    {\n        \u002F\u002F логика создания заказа\n    }\n}\n",[1745,4254,4255,4266,4271,4294,4299,4304,4310],{"__ignoreMap":1743},[43,4256,4257,4260,4263],{"class":3905,"line":3906},[43,4258,4259],{"class":3919},"final",[43,4261,4262],{"class":3919}," class",[43,4264,4265],{"class":3929}," PlaceOrderHandler\n",[43,4267,4268],{"class":3905,"line":3502},[43,4269,4270],{"class":3923},"{\n",[43,4272,4273,4276,4279,4282,4284,4286,4289,4291],{"class":3905,"line":3499},[43,4274,4275],{"class":3919},"    public",[43,4277,4278],{"class":3919}," function",[43,4280,4281],{"class":3915}," __invoke",[43,4283,699],{"class":3923},[43,4285,3724],{"class":3915},[43,4287,4288],{"class":3923}," $command)",[43,4290,313],{"class":3919},[43,4292,4293],{"class":3915}," OrderId\n",[43,4295,4296],{"class":3905,"line":3949},[43,4297,4298],{"class":3923},"    {\n",[43,4300,4301],{"class":3905,"line":3955},[43,4302,4303],{"class":3909},"        \u002F\u002F логика создания заказа\n",[43,4305,4307],{"class":3905,"line":4306},6,[43,4308,4309],{"class":3923},"    }\n",[43,4311,4313],{"class":3905,"line":4312},7,[43,4314,4315],{"class":3923},"}\n",[14,4317,4318],{},"Это упрощает DI-контейнеру регистрацию и делает вызов лаконичным.",[123,4320,4322],{"id":4321},"repository-и-read-модель","Repository и Read-модель",[14,4324,4325,4326,4329,4330,4333],{},"В лёгком CQRS команды обычно идут через ",[36,4327,4328],{},"Repository"," (паттерн для работы с агрегатами), а запросы — через ",[36,4331,4332],{},"Read-модель"," (прямые SQL-запросы, Query Builder, Elasticsearch).\nНе нужно прогонять аналитический запрос через агрегат и коллекцию объектов.",[24,4335,4337],{"id":4336},"частые-заблуждения","Частые заблуждения",[123,4339,4341],{"id":4340},"cqrs-требует-две-разные-базы-данных","«CQRS требует две разные базы данных»",[14,4343,4344],{},"Нет. Полный CQRS с раздельными хранилищами — продвинутый вариант для высоконагруженных систем.\nЛёгкий CQRS на уровне кода даёт главные преимущества (семантика, кэширование, тестируемость) без усложнения инфраструктуры.",[123,4346,4348],{"id":4347},"каждый-select-к-бд-это-query","«Каждый SELECT к БД — это Query»",[14,4350,4351,4352,4355],{},"Нет. Если метод читает данные как часть команды (например, проверка «есть ли товар на складе?» внутри ",[1745,4353,4354],{},"PlaceOrderHandler",") — это часть Command, а не отдельный Query.\nQuery — это самостоятельная операция чтения, инициированная извне.",[123,4357,4359],{"id":4358},"command-не-может-возвращать-данные","«Command не может возвращать данные»",[14,4361,4362,4363,4365,4366,4369,4370,4373],{},"Может, но минимум. ",[1745,4364,4354],{}," возвращает ",[1745,4367,4368],{},"OrderId"," — этого достаточно для HTTP-ответа ",[1745,4371,4372],{},"201 Created",".\nНо команда не должна возвращать большие структуры данных: для этого есть Query.",[123,4375,4377],{"id":4376},"cqrs-это-про-микросервисы","«CQRS — это про микросервисы»",[14,4379,4380],{},"Нет. CQRS отлично работает в монолите.\nБолее того, в монолите он часто приносит больше пользы, потому что без него границы между чтением и записью размываются быстрее.",[123,4382,4384],{"id":4383},"нужен-event-sourcing","«Нужен Event Sourcing»",[14,4386,4387],{},"CQRS и Event Sourcing часто упоминаются вместе, но это независимые паттерны.\nМожно использовать CQRS без Event Sourcing и наоборот.\nСвязка имеет смысл в сложных доменах с аудитом, но не является обязательной.",[24,4389,4391],{"id":4390},"когда-cqrs-не-нужен","Когда CQRS не нужен",[2016,4393,4394,4400,4406],{},[1331,4395,4396,4399],{},[36,4397,4398],{},"CRUD-приложение без бизнес-логики."," Если у вас пять таблиц и стандартный админ-панель, разделение на команды и запросы добавит boilerplate без реальной пользы.",[1331,4401,4402,4405],{},[36,4403,4404],{},"Прототип \u002F MVP."," На этапе проверки гипотезы скорость важнее архитектуры.",[1331,4407,4408,4411],{},[36,4409,4410],{},"Команда не знакома с паттерном."," CQRS, внедрённый формально, без понимания, превращается в ритуал и усложняет онбординг.",[14,4413,4414],{},"CQRS оправдан, когда:",[2016,4416,4417,4420,4423,4426],{},[1331,4418,4419],{},"Операции чтения и записи имеют разную нагрузку.",[1331,4421,4422],{},"Бизнес-правила при записи сложны и требуют явного моделирования.",[1331,4424,4425],{},"Разные клиенты (веб, мобильное приложение, API) нуждаются в разных проекциях данных.",[1331,4427,4428],{},"Команда растёт и нужна чёткая конвенция, чтобы не скатиться в «богатые сервисы».",[24,4430,4432],{"id":4431},"антипаттерны","Антипаттерны",[131,4434,4435,4445],{},[134,4436,4437],{},[137,4438,4439,4442],{},[140,4440,4441],{},"Антипаттерн",[140,4443,4444],{},"Почему плохо",[147,4446,4447,4465,4473,4481,4489],{},[137,4448,4449,4455],{},[152,4450,4451,4454],{},[1745,4452,4453],{},"SaveOrderCommand",", которая и создаёт, и обновляет, и удаляет",[152,4456,4457,4458,3821,4460,3821,4463],{},"Нарушает единственную ответственность; разбейте на ",[1745,4459,3820],{},[1745,4461,4462],{},"Update",[1745,4464,3824],{},[137,4466,4467,4470],{},[152,4468,4469],{},"Query с побочным эффектом (логирует, шлёт уведомления)",[152,4471,4472],{},"Скрытая мутация; кэширование такого запроса сломает логику",[137,4474,4475,4478],{},[152,4476,4477],{},"Один «God Handler» на все команды",[152,4479,4480],{},"Убивает всю пользу от разделения",[137,4482,4483,4486],{},[152,4484,4485],{},"Возврат полного агрегата из Query",[152,4487,4488],{},"Тянет лишние данные, связывает read-модель с доменной",[137,4490,4491,4494],{},[152,4492,4493],{},"Команда без валидации инвариантов",[152,4495,4496],{},"CQRS не отменяет проверку бизнес-правил",[24,4498,4500],{"id":4499},"чек-лист-для-внедрения","Чек-лист для внедрения",[1328,4502,4503,4518,4534,4540,4546,4552,4558],{},[1331,4504,4505,4508,4509,3821,4511,3821,4514,4517],{},[36,4506,4507],{},"Определите доменные области"," (",[1745,4510,4081],{},[1745,4512,4513],{},"Analytics",[1745,4515,4516],{},"Identity","…).",[1331,4519,4520,3817,4523,3821,4525,3821,4527,3821,4529,3821,4531,1052],{},[36,4521,4522],{},"Разнесите папки",[1745,4524,3868],{},[1745,4526,3872],{},[1745,4528,3878],{},[1745,4530,3881],{},[1745,4532,4533],{},"DTO\u002F",[1331,4535,4536,4539],{},[36,4537,4538],{},"Договоритесь об именовании",": глагол действия для команд, Get для запросов.",[1331,4541,4542,4545],{},[36,4543,4544],{},"Настройте шину \u002F Mediator",", чтобы контроллеры не знали о конкретных обработчиках.",[1331,4547,4548,4551],{},[36,4549,4550],{},"Запретите кэширование на уровне команд",", разрешите на уровне запросов.",[1331,4553,4554,4557],{},[36,4555,4556],{},"Пишите тесты по типу",": для команд — проверка побочного эффекта, для запросов — проверка возвращаемых данных.",[1331,4559,4560,4563],{},[36,4561,4562],{},"Проведите ревью",": убедитесь, что ни один Query не мутирует состояние.",[24,4565,4567],{"id":4566},"итоги","Итоги",[14,4569,4570],{},"CQRS — не обязательный атрибут «серьёзной архитектуры».",[14,4572,4150,4573,4576],{},[36,4574,4575],{},"инструмент упорядочивания",", который:",[2016,4578,4579,4582,4585,4588],{},[1331,4580,4581],{},"делает намерения кода явными,",[1331,4583,4584],{},"развязывает руки для кэширования и масштабирования чтения,",[1331,4586,4587],{},"упрощает тестирование и код-ревью,",[1331,4589,4590],{},"задаёт понятную конвенцию для растущей команды.",[14,4592,4593],{},"Начните с лёгкого CQRS: разделите папки, дайте классам говорящие имена, уберите SELECT-запросы из команд.\nЭто займёт несколько часов \\ дней, а окупаться будет годами.",[4595,4596,4597],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":1743,"searchDepth":3499,"depth":3499,"links":4599},[4600,4601,4602,4606,4610,4611,4617,4618,4624,4631,4632,4633,4634],{"id":3545,"depth":3502,"text":3546},{"id":3599,"depth":3502,"text":3600},{"id":3655,"depth":3502,"text":3656,"children":4603},[4604,4605],{"id":3659,"depth":3499,"text":3660},{"id":3679,"depth":3499,"text":3680},{"id":3695,"depth":3502,"text":3696,"children":4607},[4608,4609],{"id":3702,"depth":3499,"text":3703},{"id":3760,"depth":3499,"text":3761},{"id":3845,"depth":3502,"text":3846},{"id":3887,"depth":3502,"text":3888,"children":4612},[4613,4614,4615,4616],{"id":3891,"depth":3499,"text":3892},{"id":3981,"depth":3499,"text":3982},{"id":4069,"depth":3499,"text":4070},{"id":4107,"depth":3499,"text":4108},{"id":4114,"depth":3502,"text":4115},{"id":4167,"depth":3502,"text":4168,"children":4619},[4620,4621,4623],{"id":4171,"depth":3499,"text":4172},{"id":4242,"depth":3499,"text":4622},"Паттерн __invoke",{"id":4321,"depth":3499,"text":4322},{"id":4336,"depth":3502,"text":4337,"children":4625},[4626,4627,4628,4629,4630],{"id":4340,"depth":3499,"text":4341},{"id":4347,"depth":3499,"text":4348},{"id":4358,"depth":3499,"text":4359},{"id":4376,"depth":3499,"text":4377},{"id":4383,"depth":3499,"text":4384},{"id":4390,"depth":3502,"text":4391},{"id":4431,"depth":3502,"text":4432},{"id":4499,"depth":3502,"text":4500},{"id":4566,"depth":3502,"text":4567},"Backend","\u002Fcovers\u002Fcqrs.webp","2026-08-07","Архитектурный паттерн, который разделяет операции над системой.",{},"\u002Fblog\u002Fcqrs",{"title":3540,"description":4638},"blog\u002Fcqrs",[4644,4645,3900],"architecture","pattern","bFZJtolTlzzCJQMiL6kROb2nQs36aQ-wPSTMdMbDZCo",{"id":4648,"title":4649,"body":4650,"category":8250,"cover":8251,"date":8252,"description":8253,"draft":3525,"extension":3526,"meta":8254,"navigation":3528,"path":8255,"seo":8256,"stem":8257,"tags":8258,"updated":3536,"__hash__":8260},"blog\u002Fblog\u002Fllm-itself.md","LLM: Как это работает, где взять и как приручить",{"type":8,"value":4651,"toc":8194},[4652,4656,4659,4662,4665,4671,4674,4676,4680,4683,4700,4704,4707,4713,4719,4729,4735,4739,4742,4755,4761,4782,4786,4789,4795,4816,4830,4836,4842,4855,4859,4864,4870,4875,4881,4886,4892,4897,4903,4907,4913,4918,4936,4938,4942,4945,4948,4954,4960,4974,4980,4984,4987,4993,5001,5004,5010,5018,5024,5032,5038,5049,5055,5063,5069,5073,5076,5108,5112,5115,5141,5144,5148,5153,5164,5169,5177,5182,5193,5198,5209,5213,5216,5222,5228,5234,5238,5266,5270,5273,5278,5281,5301,5307,5313,5317,5320,5340,5346,5351,5355,5358,5372,5375,5379,5382,5408,5412,5417,5449,5475,5480,5522,5527,5561,5563,5567,5570,5573,5579,5585,5588,5591,5593,5597,5603,5607,5611,5617,5620,5624,5627,5851,5854,5858,5861,6069,6076,6081,6244,6249,6258,6263,6267,6287,6292,6299,6328,6335,6340,6360,6365,6368,6373,6379,6384,6390,6393,6554,6559,6794,6799,6802,6963,6966,7066,7068,7162,7167,7170,7252,7257,7262,7321,7326,7337,7342,7353,7357,7360,7386,7388,7392,7399,7402,7405,7419,7432,7435,7446,7450,7454,7457,7462,7468,7471,7476,7482,7488,7492,7495,7500,7506,7511,7515,7651,7655,7658,7662,7668,7671,7676,7682,7685,7691,7696,7700,7703,7708,7714,7719,7723,7726,7731,7737,7740,7744,7748,7753,7759,7764,7770,7776,7780,7784,7790,7794,7800,7805,7809,7813,7819,7823,7829,7834,7838,7842,7848,7852,7858,7863,7867,7871,7877,7881,7887,7892,7896,7900,7906,7909,7913,7919,7924,7928,7931,7999,8003,8009,8014,8020,8027,8032,8038,8041,8046,8052,8055,8060,8066,8069,8073,8076,8108,8111,8113,8117,8120,8126,8129,8132,8150,8156,8158,8162,8165,8168,8188,8191],[24,4653,4655],{"id":4654},"_1-введение-развенчание-мифов","1. Введение. Развенчание мифов",[14,4657,4658],{},"Большие языковые модели — LLM.\nНачнем с того, что развеем главный миф: LLM — это не волшебный шар, который читает ваши мысли и знает все ответы.",[14,4660,4661],{},"Когда мы впервые сталкиваемся с ChatGPT или аналогичными системами, возникает ощущение магии.\nМы пишем вопрос — получаем ответ. Кажется, что перед нами разумная сущность, которая всё понимает.\nНо на самом деле LLM — это очень сложный, но предсказуемый статистический калькулятор слов.",[14,4663,4664],{},"Что это значит на практике? Это значит, что модель не «понимает» смысл ваших слов в человеческом смысле.\nОна не знает ваших внутренних бизнес-процессов, если вы ей о них не рассказали. Она не может прочитать ваши мысли.",[14,4666,4667,4670],{},[36,4668,4669],{},"LLM — это движок предсказания следующего токена.","\nОна обучена на огромном массиве текстов и научилась угадывать, какое слово (или часть слова) должно идти дальше с наибольшей вероятностью.\nОна не ищет истину. Она ищет наиболее вероятное продолжение текста на основе своих весов.",[14,4672,4673],{},"Наша задача как инженеров, менеджеров и всех, кто работает с LLM — научиться управлять этой вероятностью.\nРазберемся, как это делать.",[21,4675],{},[24,4677,4679],{"id":4678},"_2-анатомия-мышления-токены-и-температура","2. Анатомия «мышления»: Токены и Температура",[14,4681,4682],{},"Начнем с базовых понятий. Когда вы пишете текст модели, она видит его не как слова, а как токены.",[14,4684,4685,4686,4689,4690,3821,4693,1719,4696,4699],{},"Токен — это базовая единица обработки. Это может быть целое слово, часть слова или даже отдельный символ.\nНапример, фраза ",[1745,4687,4688],{},"«Clean Architecture»"," разбивается на три токена: ",[1745,4691,4692],{},"«Clean»",[1745,4694,4695],{},"« Arch»",[1745,4697,4698],{},"«itecture»",".\nОбратите внимание: токенов больше, чем слов, потому что модель работает с частями слов.",[123,4701,4703],{"id":4702},"как-тратятся-токены","Как тратятся токены",[14,4705,4706],{},"Когда вы отправляете запрос к модели, токены тратятся в двух направлениях:",[14,4708,4709,4712],{},[36,4710,4711],{},"Input токены"," — это всё, что вы отправляете модели: ваш промпт, системные инструкции, история диалога, контекст из RAG.\nЭто то, что модель должна «прочитать» и понять.",[14,4714,4715,4718],{},[36,4716,4717],{},"Output токены"," — это то, что модель генерирует в ответ.\nИменно за эти токены вы платите больше всего, потому что генерация требует больше вычислительных ресурсов.",[14,4720,4721,4724,4725,4728],{},[36,4722,4723],{},"Важно для менеджеров:"," Стоимость API обычно считается так: ",[1745,4726,4727],{},"$X за 1M input токенов + $Y за 1M output токенов",".\nПри этом output токены часто стоят в 2-4 раза дороже. Поэтому длинные ответы модели — это дорого.",[14,4730,4731,4734],{},[36,4732,4733],{},"Важно для разработчиков:"," Лимит контекстного окна (например, 8K, 32K, 128K токенов) включает и input, и output.\nЕсли у вас история диалога на 7000 токенов, а лимит 8000, то на ответ остается всего 1000 токенов.\nЭто примерно 750 слов — модель может оборвать ответ на полуслове.",[123,4736,4738],{"id":4737},"лимит-токенов-max_tokens","Лимит токенов: max_tokens",[14,4740,4741],{},"Параметр max_tokens ограничивает длину ответа модели. Что произойдет, если модель достигнет этого лимита?",[14,4743,4744,4747,4748,4751,4752,1052],{},[36,4745,4746],{},"Сценарий 1: Ответ оборвался."," Модель генерировала длинный код, но достигла лимита.\nВы получите обрезанный, нерабочий код. В ответе API будет флаг ",[1745,4749,4750],{},"finish_reason: \"length\""," вместо ",[1745,4753,4754],{},"\"stop\"",[14,4756,4757,4760],{},[36,4758,4759],{},"Сценарий 2: Модель не успела закончить мысль.","\nНапример, вы попросили объяснить концепцию, но модель остановилась на середине предложения.",[14,4762,4763,4766,4767,4770,4771,4774,4775,4778,4779,4781],{},[36,4764,4765],{},"Как избежать:"," Всегда проверяйте ",[1745,4768,4769],{},"finish_reason"," в ответе API.\nЕсли это ",[1745,4772,4773],{},"\"length\"",", значит ответ обрезан, и нужно либо увеличить ",[1745,4776,4777],{},"max_tokens",", либо попросить модель продолжить.\nДля генерации кода ставьте ",[1745,4780,4777],{}," с запасом — 2000-4000 токенов, чтобы модель могла написать полный класс без обрезания.",[123,4783,4785],{"id":4784},"температура-и-другие-параметры-контроля","Температура и другие параметры контроля",[14,4787,4788],{},"Температура — это не единственный параметр, который управляет «креативностью» модели. Давайте разберем весь набор.",[14,4790,4791,4794],{},[36,4792,4793],{},"Temperature (0.0 — 2.0)"," — основной параметр. На температуре 0.0 модель максимально строгая и детерминированная.\nЕсли вы попросите её сгенерировать PHP-код, SQL-запрос или извлечь данные в JSON — ставьте температуру 0.0 или 0.1.\nВы получите предсказуемый, стабильный результат. На температуре 0.7–0.9 модель становится креативной, хаотичной.\nЭто идеально для брейншторма идей, написания маркетингового текста.\nНо для кода или точных данных такая температура опасна.",[14,4796,4797,4800,4801,4804,4805,4808,4809,4812,4813,1052],{},[36,4798,4799],{},"Top_p (nucleus sampling, 0.0 — 1.0)"," — альтернатива температуре.\nМодель рассматривает только токены, которые в сумме дают вероятность p.\nНапример, ",[1745,4802,4803],{},"top_p=0.9"," означает, что модель выбирает из токенов, которые покрывают 90% вероятности.\nЧем ниже значение, тем более предсказуемый ответ. Обычно используется либо ",[1745,4806,4807],{},"temperature",", либо ",[1745,4810,4811],{},"top_p",", но не оба сразу.\nДля кода ставьте ",[1745,4814,4815],{},"top_p=0.1-0.3",[14,4817,4818,4821,4822,4825,4826,4829],{},[36,4819,4820],{},"Top_k (1 — бесконечность)"," — модель рассматривает только k наиболее вероятных следующих токенов.\n",[1745,4823,4824],{},"top_k=1"," означает, что модель всегда выбирает самый вероятный токен (жадный поиск, greedy decoding).\nЭто максимально детерминированный режим. Для PHP-кода и JSON ",[1745,4827,4828],{},"top_k=1-10"," дает очень стабильные результаты.",[14,4831,4832,4835],{},[36,4833,4834],{},"Frequency penalty (-2.0 — 2.0)"," — штрафует токены, которые уже часто встречались в ответе.\nЧем выше значение, тем меньше модель повторяется. Полезно для генерации длинных текстов, чтобы избежать зацикливания.\nДля кода ставьте 0.0 — повторения в коде (например, использование одних и тех же переменных) — это нормально.",[14,4837,4838,4841],{},[36,4839,4840],{},"Presence penalty (-2.0 — 2.0)"," — штрафует токены, которые уже появлялись в ответе, независимо от частоты.\nЭто заставляет модель переходить к новым темам. Для креативного письма ставьте 0.5-1.0. Для кода — 0.0.",[14,4843,4844,4847,4848,90,4851,4854],{},[36,4845,4846],{},"Stop sequences"," — список строк, при появлении которых модель останавливается.\nНапример, если вы генерируете JSON и не хотите, чтобы модель добавляла пояснения после JSON, добавьте ",[1745,4849,4850],{},"stop=[\"\\n\\n\"]",[1745,4852,4853],{},"stop=[\"```\"]",".\nЭто гарантирует, что ответ закончится ровно там, где вам нужно.",[123,4856,4858],{"id":4857},"практические-рекомендации-для-разных-задач","Практические рекомендации для разных задач",[14,4860,4861],{},[36,4862,4863],{},"Для генерации PHP-кода:",[1737,4865,4868],{"className":4866,"code":4867,"language":1742,"meta":1743},[1740],"temperature: 0.0-0.1\ntop_p: 0.1-0.3\ntop_k: 1-10\nfrequency_penalty: 0.0\npresence_penalty: 0.0\nmax_tokens: 2000-4000\n",[1745,4869,4867],{"__ignoreMap":1743},[14,4871,4872],{},[36,4873,4874],{},"Для извлечения данных в JSON:",[1737,4876,4879],{"className":4877,"code":4878,"language":1742,"meta":1743},[1740],"temperature: 0.0\ntop_p: 0.1\ntop_k: 1\nmax_tokens: 500-1000 (зависит от сложности JSON)\n",[1745,4880,4878],{"__ignoreMap":1743},[14,4882,4883],{},[36,4884,4885],{},"Для брейншторма идей:",[1737,4887,4890],{"className":4888,"code":4889,"language":1742,"meta":1743},[1740],"temperature: 0.7-0.9\ntop_p: 0.9\nfrequency_penalty: 0.5\npresence_penalty: 0.5\nmax_tokens: 1000-2000\n",[1745,4891,4889],{"__ignoreMap":1743},[14,4893,4894],{},[36,4895,4896],{},"Для суммаризации текста:",[1737,4898,4901],{"className":4899,"code":4900,"language":1742,"meta":1743},[1740],"temperature: 0.3-0.5\ntop_p: 0.5\nmax_tokens: 200-500 (зависит от желаемой длины саммари)\n",[1745,4902,4900],{"__ignoreMap":1743},[123,4904,4906],{"id":4905},"галлюцинации","Галлюцинации",[14,4908,4909,4910,4912],{},"И последнее важное: ",[36,4911,4905],{},". Это не баг, это фича стохастической модели.\nЕсли модель не знает ответа на ваш вопрос, она всё равно сгенерирует наиболее вероятное продолжение.\nИ это продолжение может быть полностью выдуманным.\nМодель не скажет «я не знаю» — она уверенно сгенерирует текст, который звучит правдоподобно, но может не соответствовать реальности.",[14,4914,4915],{},[36,4916,4917],{},"Как бороться:",[1328,4919,4920,4927,4930,4933],{},[1331,4921,4922,4923,4926],{},"Используйте ",[1745,4924,4925],{},"temperature=0.0"," для фактических вопросов",[1331,4928,4929],{},"Применяйте RAG — давайте модели реальные данные в контексте",[1331,4931,4932],{},"В промпте явно указывайте: «Если не знаешь ответа, скажи \"Я не знаю\"»",[1331,4934,4935],{},"Всегда проверяйте факты в критичных задачах",[21,4937],{},[24,4939,4941],{"id":4940},"_3-анатомия-модели-где-брать-и-что-значат-цифры","3. Анатомия модели: Где брать и что значат цифры",[14,4943,4944],{},"Теперь разберемся, что такое модель и как выбирать подходящую.",[14,4946,4947],{},"У модели есть три ключевых параметра, которые нужно понимать.",[14,4949,4950,4953],{},[36,4951,4952],{},"Первый — размер в параметрах."," Вы видите обозначения вроде 7B, 8B, 70B.\nB — это миллиард параметров. Условно говоря, это «размер мозга» модели.\nМодели на 7-8 миллиардов параметров (например, Llama 3 8B или Mistral 7B) достаточно для большинства задач: суммаризация текста, простые чаты, написание кода, извлечение данных.\nМодели на 70B и больше нужны для сложной логики, глубоких рассуждений, работы с большими контекстами.\nНо они требуют гораздо больше ресурсов.",[14,4955,4956,4959],{},[36,4957,4958],{},"Второй — квантование."," Это сжатие модели. Вы видите обозначения вроде Q4_K_M, Q8, FP16.\nКвантование уменьшает размер модели и потребление оперативной памяти с минимальной потерей качества.\nНапример, модель 8B в квантовании Q4 занимает около 5 ГБ оперативной памяти и спокойно запускается на хорошем ноутбуке.\nВ полном качестве (FP16) она заняла бы 16 ГБ.\nДля большинства задач разница в качестве между Q4 и FP16 минимальна, а разница в ресурсах — колоссальная.",[14,4961,4962,4965,4966,4969,4970,4973],{},[36,4963,4964],{},"Третий — где брать модели."," Мы не тренируем модели с нуля. Мы берем готовые open-source решения.\nОсновные источники: ",[36,4967,4968],{},"Hugging Face"," — это как GitHub для ML-моделей, там лежат тысячи моделей с документацией.\nИ официальный реестр ",[36,4971,4972],{},"Ollama"," — там модели уже оптимизированы для локального запуска.",[14,4975,4976,4977,1052],{},"Но есть еще один критически важный аспект — ",[36,4978,4979],{},"семейство моделей",[123,4981,4983],{"id":4982},"семейства-моделей-кто-есть-кто","Семейства моделей: кто есть кто",[14,4985,4986],{},"На рынке open-source моделей доминирует несколько ключевых семейств. Каждый имеет свою специализацию.",[14,4988,4989,4992],{},[36,4990,4991],{},"Meta Llama (3.3, 4)"," — самое популярное семейство. Llama 4, представленная в 2025 году, перевела флагманские модели на MoE-архитектуру.",[2016,4994,4995,4998],{},[1331,4996,4997],{},"Llama 4 Scout: 109B параметров (17B активных), нативная мультимодальность (изображения, видео), контекстное окно до 10M токенов.",[1331,4999,5000],{},"Llama 4 Maverick: 402B параметров (17B активных), 1M контекст.",[14,5002,5003],{},"Обе отлично справляются с чатами, суммаризацией, сложной логикой и генерацией кода.\nLlama 3.3 70B остаётся мощной плотной моделью для тех, кому нужна стабильность и меньший объём VRAM.\nДля локального запуска в условиях ограниченных ресурсов всё ещё актуальны Llama 3.1 8B и Llama 3.2 (мультимодальные 11B \u002F 90B).",[14,5005,5006,5009],{},[36,5007,5008],{},"Mistral"," — французское семейство, славящееся эффективностью.",[2016,5011,5012,5015],{},[1331,5013,5014],{},"Mistral Large 3 (123B) — флагман 2025 года, 256K контекст, мультимодальность, лучший выбор для сложных задач.",[1331,5016,5017],{},"Mistral Small 3 (24B) — «рабочая лошадка» для локального запуска: при квантовании помещается в 16 ГБ RAM и превосходит многих конкурентов в кодировании и рассуждениях.",[14,5019,5020,5023],{},[36,5021,5022],{},"Qwen 3"," — семейство от Alibaba. Вышло весной 2025 года. Поддержка 119 языков, включая превосходную работу с русским и китайским.",[2016,5025,5026,5029],{},[1331,5027,5028],{},"Qwen 3 Coder (специализированные версии 8B, 32B) — лидеры в бенчмарках кода, обходят GPT-4o в задачах генерации и отладки.",[1331,5030,5031],{},"Qwen 3 8B \u002F 32B — универсальные мультиязычные модели с контекстом до 1M токенов.",[14,5033,5034,5037],{},[36,5035,5036],{},"DeepSeek"," — китайское семейство, флагман эффективности и рассуждений.",[2016,5039,5040,5043,5046],{},[1331,5041,5042],{},"DeepSeek V3.1 (март 2025): 671B MoE (37B активных), 128K контекст, выдающееся качество в коде и математике.",[1331,5044,5045],{},"DeepSeek R1 — модель с продвинутой цепочкой рассуждений, решает задачи, требующие пошаговой логики.",[1331,5047,5048],{},"DeepSeek Coder V3 — узкая специализация на программировании, стабильно в топе бенчмарков.",[14,5050,5051,5054],{},[36,5052,5053],{},"Microsoft Phi-4"," — маленькие, но мощные модели (конец 2024 – 2025).",[2016,5056,5057,5060],{},[1331,5058,5059],{},"Phi-4-mini (3.3B) — удивительно сильна в рассуждениях, математике и следовании инструкциям. Идеальна для edge-устройств и мобильных приложений.",[1331,5061,5062],{},"Phi-4 (14B) — более крупная версия, контекст 128K, хороша для аналитики и длинных документов.",[14,5064,5065,5068],{},[36,5066,5067],{},"Google Gemma 3"," — открытое семейство на базе технологий Gemini (2025). Модели от 1B до 27B, все с контекстом 128K и мультимодальностью. Gemma 3 27B сравнима с Llama 3.3 70B по качеству, но значительно легче.",[123,5070,5072],{"id":5071},"как-выбирать-модель-бенчмарки-и-специализация","Как выбирать модель: бенчмарки и специализация",[14,5074,5075],{},"Ни одна модель не решает все задачи одинаково хорошо. Ориентируйтесь на ключевые тесты.",[2016,5077,5078,5084,5090,5096,5102],{},[1331,5079,5080,5083],{},[36,5081,5082],{},"MMLU (Massive Multitask Language Understanding)"," — общие знания и рассуждения. DeepSeek V3.1 и Llama 4 Maverick показывают ≈88‑89%, Qwen 3 235B — около 87%. Хороший уровень для прикладной системы — от 80%.",[1331,5085,5086,5089],{},[36,5087,5088],{},"HumanEval \u002F MBPP"," — генерация и понимание кода (Python, JavaScript, PHP и др.). Здесь лидируют Qwen 3 Coder 32B и DeepSeek Coder V3, набирая выше 90% pass@1.",[1331,5091,5092,5095],{},[36,5093,5094],{},"MT-Bench \u002F AlpacaEval"," — качество диалога и следования инструкциям. Важно для чат-ботов и ассистентов. Лидеры — Llama 4 Maverick, Mistral Large 3 и Qwen 3 235B.",[1331,5097,5098,5101],{},[36,5099,5100],{},"GSM8K \u002F MATH"," — математические и логические рассуждения. DeepSeek R1 и Qwen 3 Coder решают почти 100% задач GSM8K и сложные олимпиадные примеры.",[1331,5103,5104,5107],{},[36,5105,5106],{},"Мультиязычность"," — если работаете с русским, обязательно проверяйте. Llama 4, Qwen 3, Mistral Large 3 и DeepSeek V3 прекрасно понимают кириллицу, генерируют текст и код с комментариями на русском. Маленькие модели (Phi-4-mini, Gemma 3 1B) могут «спотыкаться» на сложных конструкциях.",[123,5109,5111],{"id":5110},"контекстное-окно-сколько-текста-модель-может-увидеть","Контекстное окно: сколько текста модель может «увидеть»",[14,5113,5114],{},"Лимит токенов (input + output) критичен для RAG, обработки длинных документов и многошаговых диалогов.",[2016,5116,5117,5123,5129,5135],{},[1331,5118,5119,5122],{},[36,5120,5121],{},"Llama 4 Scout"," — до 10 000 000 токенов (беспрецедентный объём, ~7 млн слов). Позволяет загружать целые книги и большие кодовые базы.",[1331,5124,5125,5128],{},[36,5126,5127],{},"Llama 4 Maverick \u002F Qwen 3 (крупные)"," — 1 000 000 токенов.",[1331,5130,5131,5134],{},[36,5132,5133],{},"Mistral Large 3"," — 256K токенов.",[1331,5136,5137,5140],{},[36,5138,5139],{},"DeepSeek V3.1 \u002F R1, Phi-4, Gemma 3"," — 128K токенов.",[14,5142,5143],{},"Практический совет: если ваш RAG-пайплайн подгружает десятки чанков из векторной БД, выбирайте модель с окном от 128K, чтобы избежать лишней суммаризации.",[123,5145,5147],{"id":5146},"практические-рекомендации-по-выбору","Практические рекомендации по выбору",[14,5149,5150],{},[36,5151,5152],{},"Для локального чат-бота на ноутбуке (8–16 ГБ RAM):",[2016,5154,5155,5158,5161],{},[1331,5156,5157],{},"Qwen 3 8B Q4 (~5 ГБ) — универсальный мультиязычный выбор.",[1331,5159,5160],{},"Mistral Small 3 24B Q4_K_M (~14 ГБ) — если есть 16 ГБ и нужен упор на код и логику.",[1331,5162,5163],{},"Phi-4-mini Q4 (~2 ГБ) — для очень ограниченных ресурсов.",[14,5165,5166],{},[36,5167,5168],{},"Для корпоративного RAG с большими документами:",[2016,5170,5171,5174],{},[1331,5172,5173],{},"Llama 4 Scout Q4 на GPU с ≥24 ГБ VRAM (RTX 4090\u002F5090 или A6000) — контекст 10M, экономично.",[1331,5175,5176],{},"Облачный API DeepSeek V3.1 или Mistral Large 3 — если нужна максимальная точность без собственного парка GPU.",[14,5178,5179],{},[36,5180,5181],{},"Для генерации кода (PHP, Python, JavaScript):",[2016,5183,5184,5187,5190],{},[1331,5185,5186],{},"Qwen 3 Coder 32B (локально или в облаке).",[1331,5188,5189],{},"DeepSeek Coder V3.",[1331,5191,5192],{},"Mistral Large 3 (облачный API) — мощный универсал с сильным кодом.",[14,5194,5195],{},[36,5196,5197],{},"Для edge-устройств и мобильных приложений:",[2016,5199,5200,5203,5206],{},[1331,5201,5202],{},"Phi-4-mini (3.3B).",[1331,5204,5205],{},"Gemma 3 1B \u002F 4B.",[1331,5207,5208],{},"Qwen 3 3B.",[123,5210,5212],{"id":5211},"мультиязычность-и-русский-язык","Мультиязычность и русский язык",[14,5214,5215],{},"При работе с русским языком опирайтесь на модели, прошедшие обучение на многоязычных корпусах.",[14,5217,5218,5221],{},[36,5219,5220],{},"Отличная поддержка:"," Llama 4, Qwen 3, Mistral Large 3 \u002F Small 3, DeepSeek V3.",[14,5223,5224,5227],{},[36,5225,5226],{},"Хорошая поддержка:"," Gemma 3 27B, Phi-4 (базовая).",[14,5229,5230,5233],{},[36,5231,5232],{},"Как проверить:"," дайте модели инструкцию на русском с требованием написать код с комментариями на русском и оцените качество. Модели вроде Qwen 3 или Llama 4 справятся без нареканий.",[123,5235,5237],{"id":5236},"где-брать-модели-детализация-источников","Где брать модели: детализация источников",[2016,5239,5240,5245,5254,5260],{},[1331,5241,5242,5244],{},[36,5243,4968],{}," — главный репозиторий. Все модели доступны в различных форматах: GGUF для Ollama, safetensors для vLLM, PyTorch для дообучения. Множество community-сборок под медицинские, юридические, финансовые задачи.",[1331,5246,5247,5249,5250,5253],{},[36,5248,4972],{}," — по-прежнему самый простой способ локального запуска. Одна команда ",[1745,5251,5252],{},"ollama run llama4:scout"," — и модель готова к работе. Поддерживает все популярные кванты.",[1331,5255,5256,5259],{},[36,5257,5258],{},"LM Studio"," — графический интерфейс с поиском по Hugging Face, авто-квантованием и чатом. Удобен для быстрого прототипирования.",[1331,5261,5262,5265],{},[36,5263,5264],{},"vLLM"," — движок для продакшен-инференса. PagedAttention, continuous batching, поддержка квантов FP8\u002FFP4. Требует настройки, но даёт максимальный throughput.",[123,5267,5269],{"id":5268},"проприетарные-облачные-модели","Проприетарные облачные модели",[14,5271,5272],{},"Эти модели нельзя запустить локально, они доступны только через API. Но именно они задают планку качества для индустрии.",[5274,5275,5277],"h4",{"id":5276},"anthropic-claude-opus-4-sonnet-4-haiku-4","Anthropic Claude (Opus 4, Sonnet 4, Haiku 4)",[14,5279,5280],{},"Флагманское семейство 2025–2026 годов. Claude считается эталоном для сложных инженерных и аналитических задач.",[2016,5282,5283,5289,5295],{},[1331,5284,5285,5288],{},[36,5286,5287],{},"Opus 4"," — самая мощная модель для глубоких рассуждений, анализа многотысячестраничных документов и комплексной разработки. Контекст до 500K токенов, отлично держит детали из начала.",[1331,5290,5291,5294],{},[36,5292,5293],{},"Sonnet 4"," — оптимальный баланс скорости и качества, лучший выбор для генерации кода, рефакторинга и RAG. Контекст 200K, отличное следование инструкциям.",[1331,5296,5297,5300],{},[36,5298,5299],{},"Haiku 4"," — быстрая и недорогая, подходит для простых чат-ботов, классификации и рутинной обработки.",[14,5302,5303,5306],{},[36,5304,5305],{},"Сильные стороны:"," минимальный уровень галлюцинаций, феноменальная точность в «needle in a haystack», строгие корпоративные политики безопасности (включая опцию нулевого удержания данных).",[14,5308,5309,5312],{},[36,5310,5311],{},"Ограничения:"," только облако, платный API, невозможность локального дообучения.",[5274,5314,5316],{"id":5315},"openai-gpt-gpt-4o-gpt-41-gpt-5-mini","OpenAI GPT (GPT-4o, GPT-4.1, GPT-5 mini)",[14,5318,5319],{},"Базовый ориентир для большинства разработчиков.",[2016,5321,5322,5328,5334],{},[1331,5323,5324,5327],{},[36,5325,5326],{},"GPT-4o"," (2024) — мультимодальный универсал, понимает текст, изображения и аудио.",[1331,5329,5330,5333],{},[36,5331,5332],{},"GPT-4.1"," (2025) — улучшенная логика и следование инструкциям, особенно в коде.",[1331,5335,5336,5339],{},[36,5337,5338],{},"GPT-5 mini"," (2026) — сверхбыстрая и крайне дешёвая модель, унаследовавшая качество старших версий для простых задач вроде суммаризации, извлечения JSON и диалогов.",[14,5341,5342,5345],{},[36,5343,5344],{},"Особенность для разработчиков:"," у OpenAI одни из самых надёжных Structured Outputs и JSON Mode, что критично при интеграции с PHP\u002FPython-бэкендами.",[14,5347,5348,5350],{},[36,5349,5311],{}," закрытый исходный код, данные обрабатываются на серверах OpenAI, стоимость старших моделей всё ещё высока.",[5274,5352,5354],{"id":5353},"google-gemini-25-pro-25-flash","Google Gemini (2.5 Pro, 2.5 Flash)",[14,5356,5357],{},"Проприетарные модели с самым большим контекстным окном на рынке — до 2 миллионов токенов у Gemini 2.5 Pro.",[2016,5359,5360,5366],{},[1331,5361,5362,5365],{},[36,5363,5364],{},"Gemini 2.5 Pro"," — флагман, отлично проявляет себя в аналитике, мультимодальных задачах и поиске по гигантским массивам документов.",[1331,5367,5368,5371],{},[36,5369,5370],{},"Gemini 2.5 Flash"," — быстрая и экономичная версия для повседневных задач, контекст до 1M токенов.",[14,5373,5374],{},"Обе модели глубоко интегрированы с экосистемой Google Cloud, что удобно, если инфраструктура уже там. Качество мультиязычной работы (включая русский) на высоком уровне.",[5274,5376,5378],{"id":5377},"как-это-меняет-выбор-обновленная-матрица","Как это меняет выбор (Обновленная матрица)",[14,5380,5381],{},"Теперь, когда мы видим полную картину, выбор модели становится осознанным компромиссом:",[2016,5383,5384,5390,5396,5402],{},[1331,5385,5386,5389],{},[36,5387,5388],{},"Нужна максимальная приватность и работа без интернета?"," → Только open-source: Llama 3.1 8B\u002F70B, Qwen 2.5, Mistral (запуск через Ollama\u002FvLLM).",[1331,5391,5392,5395],{},[36,5393,5394],{},"Нужно анализировать 100-страничный технический документ или писать сложный рефакторинг, и данные можно отправлять в облако?"," → Claude 3.5 Sonnet (лучшее качество рассуждений и работы с большим контекстом).",[1331,5397,5398,5401],{},[36,5399,5400],{},"Нужно надежно извлекать данные в JSON для PHP-приложения с минимальными затратами?"," → GPT-4o mini (дешево, быстро, отличный Structured Output) или локальный Qwen 2.5 Coder 7B (если данные чувствительные).",[1331,5403,5404,5407],{},[36,5405,5406],{},"Нужно встроить модель в мобильное приложение или IoT-устройство?"," → Phi 3.5 Mini или Gemma 2 2B (работают прямо на устройстве).",[123,5409,5411],{"id":5410},"экономика-сколько-это-стоит","Экономика: сколько это стоит",[14,5413,5414],{},[36,5415,5416],{},"Облачные API (цены ориентировочные на середину 2026):",[2016,5418,5419,5430,5436,5442],{},[1331,5420,5421,5422,5425,5426,5429],{},"OpenAI GPT-4o: ",[1745,5423,5424],{},"~$1.0"," за 1M входящих токенов, ",[1745,5427,5428],{},"~$4.0"," за 1M исходящих.",[1331,5431,5432,5433,1052],{},"Anthropic Claude 4 Sonnet: ",[1745,5434,5435],{},"~$3\u002F$15",[1331,5437,5438,5439,1052],{},"Mistral Large 3: ",[1745,5440,5441],{},"~$2\u002F$6",[1331,5443,5444,5445,5448],{},"DeepSeek V3.1: ",[1745,5446,5447],{},"~$0.27\u002F$1.1"," — одно из лучших соотношений цена\u002Fкачество.",[14,5450,5451,5452,5455,5456,5459,5460,5463,5464,5467,5468,5471,5472,1052],{},"Для приложения с ",[36,5453,5454],{},"1 000"," запросов в день (",[36,5457,5458],{},"500"," входных + ",[36,5461,5462],{},"200"," выходных токенов) ежемесячные расходы на GPT-4o составят около ",[1745,5465,5466],{},"$60",", на ",[36,5469,5470],{},"DeepSeek V3.1"," — менее ",[1745,5473,5474],{},"$10",[14,5476,5477],{},[36,5478,5479],{},"Локальный запуск:",[14,5481,5482,5483,5486,5487,5490,5491,5494,5495,5498,5499,5502,5503,5506,5507,5510,5511,5513,5514,5517,5518,5521],{},"Стоимость ",[36,5484,5485],{},"GPU RTX 5090 (32 ГБ)"," — около ",[1745,5488,5489],{},"$2 000",". Модель ",[36,5492,5493],{},"Llama 4 Scout Q4"," занимает ",[1745,5496,5497],{},"~20 ГБ VRAM"," и потребляет порядка ",[1745,5500,5501],{},"250 Вт",". При круглосуточной работе и цене ",[1745,5504,5505],{},"$0.1 за кВт·ч"," расходы на электричество — около ",[1745,5508,5509],{},"$18\u002Fмес",".\nОкупаемость железа по сравнению с ",[36,5512,5326],{}," наступает примерно через ",[1745,5515,5516],{},"9–12 месяцев"," при нагрузке ",[1745,5519,5520],{},"от 5 000 запросов в день",". Для стартапов с высоким трафиком локальный инференс становится выгодным очень быстро.",[14,5523,5524],{},[36,5525,5526],{},"Вывод для менеджеров",[14,5528,5529,5530,5533,5534,90,5536,1941,5539,5542,5543,90,5546,5548,5549,1719,5552,5555,5556,1719,5558,1052],{},"Если у вас регулярный поток ",[1745,5531,5532],{},">10 000 запросов в день"," и доступен GPU — вложения в локальный запуск ",[36,5535,5121],{},[36,5537,5538],{},"Qwen 3 32B",[1745,5540,5541],{},"окупаются за год"," и далее приносят чистую экономию.\nПри низком или нестабильном трафике облачные ",[36,5544,5545],{},"API DeepSeek V3.1",[36,5547,5133],{}," дают максимальную гибкость и минимальный порог входа.\nДля кодовых задач лучшими помощниками остаются ",[36,5550,5551],{},"Qwen 3 Coder",[36,5553,5554],{},"DeepSeek Coder",", а для русского языка уверенно лидируют ",[36,5557,5022],{},[36,5559,5560],{},"Llama 4",[21,5562],{},[24,5564,5566],{"id":5565},"_4-где-и-как-запускать-облако-vs-локально","4. Где и как запускать: Облако vs Локально",[14,5568,5569],{},"Теперь вопрос инфраструктуры. Где запускать модель?",[14,5571,5572],{},"Есть два основных пути: облако и локально.",[14,5574,5575,5578],{},[36,5576,5577],{},"Облачные API"," — это OpenAI, Anthropic, YandexGPT и другие.\nПлюсы: не нужно своё железо, доступны самые мощные модели (GPT-4, Claude 3), не нужно разбираться в инфраструктуре.\nМинусы: ваши данные уходят наружу (для многих компаний это критично), оплата за каждый токен, зависимость от интернета и доступности сервиса.",[14,5580,5581,5584],{},[36,5582,5583],{},"Локальный запуск"," — это LM Studio, Ollama, vLLM.\nПлюсы: полная приватность данных (всё остается у вас), бесплатно после покупки железа, работа без интернета.\nМинусы: нужна оперативная память (от 8-16 ГБ для небольших моделей), модели чуть менее мощные, чем топовые облачные.",[14,5586,5587],{},"Для прототипирования, личных задач и тестирования идеально подходит LM Studio — это красивый графический интерфейс, скачал модель, нажал кнопку Run, и всё работает.\nИли Ollama — работает через терминал, легко интегрируется в скрипты и автоматизацию.",[14,5589,5590],{},"Для корпоративного продакшена, где нужны чувствительные данные и высокая нагрузка, мы поднимаем свои инстансы Ollama или vLLM внутри нашего периметра, обычно в Docker-контейнерах.\nvLLM особенно хорош для высоконагруженных систем, где нужна максимальная скорость отдачи.",[21,5592],{},[24,5594,5596],{"id":5595},"_5-форматы-промптов-как-правильно-разговаривать","5. Форматы промптов: Как правильно «разговаривать»",[14,5598,5599,5600,1052],{},"Теперь самое интересное — как писать промпты, чтобы получать предсказуемый результат.\nЭто не просто \"напиши текст\", это целая дисциплина — ",[36,5601,5602],{},"промпт-инжиниринг",[123,5604,5606],{"id":5605},"базовые-форматы-промптов","Базовые форматы промптов",[5274,5608,5610],{"id":5609},"_1-простой-текст","1. Простой текст",[1737,5612,5615],{"className":5613,"code":5614,"language":1742,"meta":1743},[1740],"Напиши функцию на PHP, которая сортирует массив пользователей по дате регистрации.\n",[1745,5616,5614],{"__ignoreMap":1743},[14,5618,5619],{},"Это работает для простых задач, но для сложных может быть недостаточно. Модель может интерпретировать запрос по-разному каждый раз.",[5274,5621,5623],{"id":5622},"_2-xml-markdown-разметка","2. XML \u002F Markdown разметка",[14,5625,5626],{},"Это мощный инструмент для структурирования промпта. Вы используете теги, чтобы явно разделить инструкции и данные:",[1737,5628,5632],{"className":5629,"code":5630,"language":5631,"meta":1743,"style":1743},"language-xml shiki shiki-themes github-light github-dark","\u003Crole>\nТы опытный PHP-разработчик с 10-летним стажем.\nТы всегда используешь строгую типизацию и PSR-12.\n\u003C\u002Frole>\n\n\u003Crules>\n1. Используй только PHP 8.5+\n2. Добавляй PHPDoc для всех публичных методов\n3. Обрабатывай все возможные ошибки\n4. Пиши код в стиле Clean Architecture\n\u003C\u002Frules>\n\n\u003Ccontext>\nВот текущий код, который нужно рефакторить:\n```php\nclass UserService {\n    public function saveUser($data) {\n        mysql_query(\"INSERT INTO users...\");\n    }\n}\n\u003C\u002Fcontext>\n\n\u003Ctask>\nПримени паттерн Repository к этому коду.\nВыдели интерфейс UserRepository и реализацию MysqlUserRepository.\n\u003C\u002Ftask>\n\n\u003Coutput_format>\nВерни результат в виде двух блоков кода:\n1. Интерфейс UserRepository\n2. Класс MysqlUserRepository\n\u003C\u002Foutput_format>\n","xml",[1745,5633,5634,5645,5650,5655,5664,5668,5677,5682,5688,5694,5700,5709,5714,5724,5730,5736,5742,5748,5754,5759,5764,5773,5778,5788,5794,5800,5809,5814,5824,5830,5836,5842],{"__ignoreMap":1743},[43,5635,5636,5638,5642],{"class":3905,"line":3906},[43,5637,932],{"class":3923},[43,5639,5641],{"class":5640},"s9eBZ","role",[43,5643,5644],{"class":3923},">\n",[43,5646,5647],{"class":3905,"line":3502},[43,5648,5649],{"class":3923},"Ты опытный PHP-разработчик с 10-летним стажем.\n",[43,5651,5652],{"class":3905,"line":3499},[43,5653,5654],{"class":3923},"Ты всегда используешь строгую типизацию и PSR-12.\n",[43,5656,5657,5660,5662],{"class":3905,"line":3949},[43,5658,5659],{"class":3923},"\u003C\u002F",[43,5661,5641],{"class":5640},[43,5663,5644],{"class":3923},[43,5665,5666],{"class":3905,"line":3955},[43,5667,3946],{"emptyLinePlaceholder":3528},[43,5669,5670,5672,5675],{"class":3905,"line":4306},[43,5671,932],{"class":3923},[43,5673,5674],{"class":5640},"rules",[43,5676,5644],{"class":3923},[43,5678,5679],{"class":3905,"line":4312},[43,5680,5681],{"class":3923},"1. Используй только PHP 8.5+\n",[43,5683,5685],{"class":3905,"line":5684},8,[43,5686,5687],{"class":3923},"2. Добавляй PHPDoc для всех публичных методов\n",[43,5689,5691],{"class":3905,"line":5690},9,[43,5692,5693],{"class":3923},"3. Обрабатывай все возможные ошибки\n",[43,5695,5697],{"class":3905,"line":5696},10,[43,5698,5699],{"class":3923},"4. Пиши код в стиле Clean Architecture\n",[43,5701,5703,5705,5707],{"class":3905,"line":5702},11,[43,5704,5659],{"class":3923},[43,5706,5674],{"class":5640},[43,5708,5644],{"class":3923},[43,5710,5712],{"class":3905,"line":5711},12,[43,5713,3946],{"emptyLinePlaceholder":3528},[43,5715,5717,5719,5722],{"class":3905,"line":5716},13,[43,5718,932],{"class":3923},[43,5720,5721],{"class":5640},"context",[43,5723,5644],{"class":3923},[43,5725,5727],{"class":3905,"line":5726},14,[43,5728,5729],{"class":3923},"Вот текущий код, который нужно рефакторить:\n",[43,5731,5733],{"class":3905,"line":5732},15,[43,5734,5735],{"class":3923},"```php\n",[43,5737,5739],{"class":3905,"line":5738},16,[43,5740,5741],{"class":3923},"class UserService {\n",[43,5743,5745],{"class":3905,"line":5744},17,[43,5746,5747],{"class":3923},"    public function saveUser($data) {\n",[43,5749,5751],{"class":3905,"line":5750},18,[43,5752,5753],{"class":3923},"        mysql_query(\"INSERT INTO users...\");\n",[43,5755,5757],{"class":3905,"line":5756},19,[43,5758,4309],{"class":3923},[43,5760,5762],{"class":3905,"line":5761},20,[43,5763,4315],{"class":3923},[43,5765,5767,5769,5771],{"class":3905,"line":5766},21,[43,5768,5659],{"class":3923},[43,5770,5721],{"class":5640},[43,5772,5644],{"class":3923},[43,5774,5776],{"class":3905,"line":5775},22,[43,5777,3946],{"emptyLinePlaceholder":3528},[43,5779,5781,5783,5786],{"class":3905,"line":5780},23,[43,5782,932],{"class":3923},[43,5784,5785],{"class":5640},"task",[43,5787,5644],{"class":3923},[43,5789,5791],{"class":3905,"line":5790},24,[43,5792,5793],{"class":3923},"Примени паттерн Repository к этому коду.\n",[43,5795,5797],{"class":3905,"line":5796},25,[43,5798,5799],{"class":3923},"Выдели интерфейс UserRepository и реализацию MysqlUserRepository.\n",[43,5801,5803,5805,5807],{"class":3905,"line":5802},26,[43,5804,5659],{"class":3923},[43,5806,5785],{"class":5640},[43,5808,5644],{"class":3923},[43,5810,5812],{"class":3905,"line":5811},27,[43,5813,3946],{"emptyLinePlaceholder":3528},[43,5815,5817,5819,5822],{"class":3905,"line":5816},28,[43,5818,932],{"class":3923},[43,5820,5821],{"class":5640},"output_format",[43,5823,5644],{"class":3923},[43,5825,5827],{"class":3905,"line":5826},29,[43,5828,5829],{"class":3923},"Верни результат в виде двух блоков кода:\n",[43,5831,5833],{"class":3905,"line":5832},30,[43,5834,5835],{"class":3923},"1. Интерфейс UserRepository\n",[43,5837,5839],{"class":3905,"line":5838},31,[43,5840,5841],{"class":3923},"2. Класс MysqlUserRepository\n",[43,5843,5845,5847,5849],{"class":3905,"line":5844},32,[43,5846,5659],{"class":3923},[43,5848,5821],{"class":5640},[43,5850,5644],{"class":3923},[14,5852,5853],{},"Модель гораздо лучше понимает структуру. Она не перепутает инструкцию с данными.\nXML-теги работают как \"разделители контекста\" для внимания модели (attention mechanism).",[5274,5855,5857],{"id":5856},"_3-json-mode-structured-output","3. JSON Mode \u002F Structured Output",[14,5859,5860],{},"Это критически важно для разработчиков. Если вам нужно, чтобы модель вернула структурированные данные для обработки в коде, всегда используйте JSON Mode:",[1737,5862,5866],{"className":5863,"code":5864,"language":5865,"meta":1743,"style":1743},"language-json shiki shiki-themes github-light github-dark","{\n  \"prompt\": \"Извлеки из текста имя пользователя и email\",\n  \"text\": \"Меня зовут Иван Петров, мой email ivan@example.com\",\n  \"response_format\": {\n    \"type\": \"json_schema\",\n    \"json_schema\": {\n      \"name\": \"user_extraction\",\n      \"strict\": true,\n      \"schema\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"name\": {\"type\": \"string\"},\n          \"email\": {\"type\": \"string\", \"format\": \"email\"}\n        },\n        \"required\": [\"name\", \"email\"],\n        \"additionalProperties\": false\n      }\n    }\n  }\n}\n","json",[1745,5867,5868,5872,5886,5898,5906,5918,5925,5937,5948,5955,5967,5974,5993,6018,6023,6041,6051,6056,6060,6065],{"__ignoreMap":1743},[43,5869,5870],{"class":3905,"line":3906},[43,5871,4270],{"class":3923},[43,5873,5874,5877,5879,5883],{"class":3905,"line":3502},[43,5875,5876],{"class":3915},"  \"prompt\"",[43,5878,3817],{"class":3923},[43,5880,5882],{"class":5881},"sZZnC","\"Извлеки из текста имя пользователя и email\"",[43,5884,5885],{"class":3923},",\n",[43,5887,5888,5891,5893,5896],{"class":3905,"line":3499},[43,5889,5890],{"class":3915},"  \"text\"",[43,5892,3817],{"class":3923},[43,5894,5895],{"class":5881},"\"Меня зовут Иван Петров, мой email ivan@example.com\"",[43,5897,5885],{"class":3923},[43,5899,5900,5903],{"class":3905,"line":3949},[43,5901,5902],{"class":3915},"  \"response_format\"",[43,5904,5905],{"class":3923},": {\n",[43,5907,5908,5911,5913,5916],{"class":3905,"line":3955},[43,5909,5910],{"class":3915},"    \"type\"",[43,5912,3817],{"class":3923},[43,5914,5915],{"class":5881},"\"json_schema\"",[43,5917,5885],{"class":3923},[43,5919,5920,5923],{"class":3905,"line":4306},[43,5921,5922],{"class":3915},"    \"json_schema\"",[43,5924,5905],{"class":3923},[43,5926,5927,5930,5932,5935],{"class":3905,"line":4312},[43,5928,5929],{"class":3915},"      \"name\"",[43,5931,3817],{"class":3923},[43,5933,5934],{"class":5881},"\"user_extraction\"",[43,5936,5885],{"class":3923},[43,5938,5939,5942,5944,5946],{"class":3905,"line":5684},[43,5940,5941],{"class":3915},"      \"strict\"",[43,5943,3817],{"class":3923},[43,5945,75],{"class":3915},[43,5947,5885],{"class":3923},[43,5949,5950,5953],{"class":3905,"line":5690},[43,5951,5952],{"class":3915},"      \"schema\"",[43,5954,5905],{"class":3923},[43,5956,5957,5960,5962,5965],{"class":3905,"line":5696},[43,5958,5959],{"class":3915},"        \"type\"",[43,5961,3817],{"class":3923},[43,5963,5964],{"class":5881},"\"object\"",[43,5966,5885],{"class":3923},[43,5968,5969,5972],{"class":3905,"line":5702},[43,5970,5971],{"class":3915},"        \"properties\"",[43,5973,5905],{"class":3923},[43,5975,5976,5979,5982,5985,5987,5990],{"class":3905,"line":5711},[43,5977,5978],{"class":3915},"          \"name\"",[43,5980,5981],{"class":3923},": {",[43,5983,5984],{"class":3915},"\"type\"",[43,5986,3817],{"class":3923},[43,5988,5989],{"class":5881},"\"string\"",[43,5991,5992],{"class":3923},"},\n",[43,5994,5995,5998,6000,6002,6004,6006,6008,6011,6013,6016],{"class":3905,"line":5716},[43,5996,5997],{"class":3915},"          \"email\"",[43,5999,5981],{"class":3923},[43,6001,5984],{"class":3915},[43,6003,3817],{"class":3923},[43,6005,5989],{"class":5881},[43,6007,3821],{"class":3923},[43,6009,6010],{"class":3915},"\"format\"",[43,6012,3817],{"class":3923},[43,6014,6015],{"class":5881},"\"email\"",[43,6017,4315],{"class":3923},[43,6019,6020],{"class":3905,"line":5726},[43,6021,6022],{"class":3923},"        },\n",[43,6024,6025,6028,6031,6034,6036,6038],{"class":3905,"line":5732},[43,6026,6027],{"class":3915},"        \"required\"",[43,6029,6030],{"class":3923},": [",[43,6032,6033],{"class":5881},"\"name\"",[43,6035,3821],{"class":3923},[43,6037,6015],{"class":5881},[43,6039,6040],{"class":3923},"],\n",[43,6042,6043,6046,6048],{"class":3905,"line":5738},[43,6044,6045],{"class":3915},"        \"additionalProperties\"",[43,6047,3817],{"class":3923},[43,6049,6050],{"class":3915},"false\n",[43,6052,6053],{"class":3905,"line":5744},[43,6054,6055],{"class":3923},"      }\n",[43,6057,6058],{"class":3905,"line":5750},[43,6059,4309],{"class":3923},[43,6061,6062],{"class":3905,"line":5756},[43,6063,6064],{"class":3923},"  }\n",[43,6066,6067],{"class":3905,"line":5761},[43,6068,4315],{"class":3923},[14,6070,6071,6072,6075],{},"Это гарантирует, что вы получите валидный JSON, который можно распарсить через ",[1745,6073,6074],{},"json_decode($response, true)"," без ошибок.\nИначе модель может ответить текстом вроде \"Конечно, вот ваш JSON:\" и добавить пояснения, которые сломают парсинг.",[14,6077,6078],{},[36,6079,6080],{},"Пример на PHP:",[1737,6082,6084],{"className":3898,"code":6083,"language":3900,"meta":1743,"style":1743},"$response = $llm->generate($prompt, [\n    'response_format' => ['type' => 'json_object']\n]);\n\n$data = json_decode($response, true);\nif (json_last_error() === JSON_ERROR_NONE) {\n    \u002F\u002F Успешно распарсили\n    $user = new User($data['name'], $data['email']);\n} else {\n    \u002F\u002F Обработка ошибки\n    throw new \\Exception('Invalid JSON response');\n}\n",[1745,6085,6086,6104,6126,6131,6135,6153,6175,6180,6207,6218,6223,6240],{"__ignoreMap":1743},[43,6087,6088,6091,6093,6096,6098,6101],{"class":3905,"line":3906},[43,6089,6090],{"class":3923},"$response ",[43,6092,432],{"class":3919},[43,6094,6095],{"class":3923}," $llm",[43,6097,3920],{"class":3919},[43,6099,6100],{"class":3929},"generate",[43,6102,6103],{"class":3923},"($prompt, [\n",[43,6105,6106,6109,6112,6115,6118,6120,6123],{"class":3905,"line":3502},[43,6107,6108],{"class":5881},"    'response_format'",[43,6110,6111],{"class":3919}," =>",[43,6113,6114],{"class":3923}," [",[43,6116,6117],{"class":5881},"'type'",[43,6119,6111],{"class":3919},[43,6121,6122],{"class":5881}," 'json_object'",[43,6124,6125],{"class":3923},"]\n",[43,6127,6128],{"class":3905,"line":3499},[43,6129,6130],{"class":3923},"]);\n",[43,6132,6133],{"class":3905,"line":3949},[43,6134,3946],{"emptyLinePlaceholder":3528},[43,6136,6137,6140,6142,6145,6148,6150],{"class":3905,"line":3955},[43,6138,6139],{"class":3923},"$data ",[43,6141,432],{"class":3919},[43,6143,6144],{"class":3915}," json_decode",[43,6146,6147],{"class":3923},"($response, ",[43,6149,75],{"class":3915},[43,6151,6152],{"class":3923},");\n",[43,6154,6155,6158,6160,6163,6166,6169,6172],{"class":3905,"line":4306},[43,6156,6157],{"class":3919},"if",[43,6159,4508],{"class":3923},[43,6161,6162],{"class":3915},"json_last_error",[43,6164,6165],{"class":3923},"() ",[43,6167,6168],{"class":3919},"===",[43,6170,6171],{"class":3915}," JSON_ERROR_NONE",[43,6173,6174],{"class":3923},") {\n",[43,6176,6177],{"class":3905,"line":4312},[43,6178,6179],{"class":3909},"    \u002F\u002F Успешно распарсили\n",[43,6181,6182,6185,6187,6190,6193,6196,6199,6202,6205],{"class":3905,"line":5684},[43,6183,6184],{"class":3923},"    $user ",[43,6186,432],{"class":3919},[43,6188,6189],{"class":3919}," new",[43,6191,6192],{"class":3915}," User",[43,6194,6195],{"class":3923},"($data[",[43,6197,6198],{"class":5881},"'name'",[43,6200,6201],{"class":3923},"], $data[",[43,6203,6204],{"class":5881},"'email'",[43,6206,6130],{"class":3923},[43,6208,6209,6212,6215],{"class":3905,"line":5690},[43,6210,6211],{"class":3923},"} ",[43,6213,6214],{"class":3919},"else",[43,6216,6217],{"class":3923}," {\n",[43,6219,6220],{"class":3905,"line":5696},[43,6221,6222],{"class":3909},"    \u002F\u002F Обработка ошибки\n",[43,6224,6225,6228,6230,6233,6235,6238],{"class":3905,"line":5702},[43,6226,6227],{"class":3919},"    throw",[43,6229,6189],{"class":3919},[43,6231,6232],{"class":3915}," \\Exception",[43,6234,699],{"class":3923},[43,6236,6237],{"class":5881},"'Invalid JSON response'",[43,6239,6152],{"class":3923},[43,6241,6242],{"class":3905,"line":5711},[43,6243,4315],{"class":3923},[6245,6246,6248],"h5",{"id":6247},"json-mode-ограничения-и-альтернативы","JSON Mode: ограничения и альтернативы",[14,6250,6251,6254,6255,1052],{},[36,6252,6253],{},"Важно:"," JSON Mode (особенно Structured Outputs с гарантированной валидацией схемы) доступен ",[36,6256,6257],{},"не для всех моделей и фреймворков",[14,6259,6260],{},[36,6261,6262],{},"Где JSON Mode работает надёжно",[14,6264,6265],{},[36,6266,5577],{},[2016,6268,6269,6275,6281],{},[1331,6270,6271,6274],{},[36,6272,6273],{},"OpenAI GPT-4.1, GPT-5 mini."," Полная поддержка response_format: { \"type\": \"json_object\" } и Structured Outputs — режим, в котором модель строго соблюдает переданную JSON-схему (100% гарантия валидности ответа). GPT-4.1 также позволяет совмещать Structured Outputs с вызовом функций, что удобно для сложных конвейеров на PHP‑бэкенде.",[1331,6276,6277,6280],{},[36,6278,6279],{},"Anthropic Claude (Opus 4, Sonnet 4)."," Гарантированный JSON достигается через tool use (function calling) — модель возвращает данные в полях аргументов функции, соответствующих заранее заданной схеме. В расширенном режиме (extended tool use) можно явно указать, что ответ всегда должен быть валидным JSON. Sonnet 4 при этом отлично держит структуру даже для вложенных объектов, а Opus 4 незаменим, когда схема сложная и требует многошаговых рассуждений.",[1331,6282,6283,6286],{},[36,6284,6285],{},"Google Gemini 2.5 Pro, 2.5 Flash",". Нативная поддержка JSON Mode через параметр response_mime_type: \"application\u002Fjson\". В сочетании с system instruction, описывающей желаемую структуру, Gemini 2.5 даёт очень стабильный JSON. Модель также поддерживает Controlled Generation — указание схемы напрямую, что исключает невалидные ответы.",[14,6288,6289],{},[36,6290,6291],{},"Open-source \u002F локальный запуск",[14,6293,6294,6295,6298],{},"Современные движки позволяют получить ",[36,6296,6297],{},"надёжный JSON Mode"," за счёт принудительного ограничения генерации грамматикой (guided\u002Fconstrained decoding). Ключевые инструменты:",[2016,6300,6301,6310,6322],{},[1331,6302,6303,6306,6307],{},[36,6304,6305],{},"llama.cpp \u002F Ollama"," — встроенная поддержка JSON grammar (формат GBNF). Достаточно передать описание схемы, и модель сгенерирует токены строго по ней.\n",[17,6308,6309],{},"Проверенные модели: Qwen 3, Llama 4 (обе конвертируются в GGUF), Mistral Small 3, Phi‑4‑mini.",[1331,6311,6312,6314,6315,6318,6319],{},[36,6313,5264],{}," — режим ",[1745,6316,6317],{},"guided_decoding_backend"," с опорой на outlines или lm-format-enforcer. Позволяет передать Pydantic-модель или JSON Schema прямо в API.\n",[17,6320,6321],{},"Рекомендуемые модели: Qwen 3 Coder 32B, DeepSeek V3.1 (при развёртывании через vLLM).",[1331,6323,6324,6327],{},[36,6325,6326],{},"Outlines"," (библиотека) — строит FSM, гарантирующий генерацию токенов по регулярному выражению или JSON-схеме. Работает поверх transformers, vLLM, llama.cpp. Идеален, если нужна максимальная скорость и строгость.",[14,6329,6330,6331,6334],{},"Таким образом, если раньше JSON Mode считался вотчиной проприетарных API, то сейчас ",[36,6332,6333],{},"любая open-source модель, запущенная через llama.cpp с грамматикой или vLLM с guided decoding, гарантирует 100% валидный JSON",". Это полностью снимает проблему «сломанного» вывода при интеграции с PHP-приложениями — можно смело выбирать локальную Qwen 3 8B для извлечения данных и быть уверенным в структуре ответа.",[14,6336,6337],{},[36,6338,6339],{},"Где JSON Mode НЕ работает или работает плохо:",[2016,6341,6342,6348,6354],{},[1331,6343,6344,6347],{},[36,6345,6346],{},"Старые модели"," (Llama 2, Mistral v1) — не обучались на JSON-формате, часто генерируют невалидный JSON",[1331,6349,6350,6353],{},[36,6351,6352],{},"Маленькие модели"," (\u003C 7B параметров) — могут \"ломаться\" на сложных JSON-схемах",[1331,6355,6356,6359],{},[36,6357,6358],{},"Модели без fine-tuning на JSON"," — некоторые специализированные модели (например, для кода) могут не понимать JSON-структуру",[14,6361,6362],{},[36,6363,6364],{},"Альтернативы, если JSON Mode недоступен",[14,6366,6367],{},"Если ваша модель не поддерживает JSON Mode или генерирует невалидный JSON, есть несколько рабочих паттернов:",[14,6369,6370],{},[36,6371,6372],{},"Паттерн 1: Явная инструкция + пример (Few-shot)",[1737,6374,6377],{"className":6375,"code":6376,"language":1742,"meta":1743},[1740],"Верни результат СТРОГО в формате JSON. Никаких пояснений, никакого текста до или после JSON.\n\nПример правильного ответа:\n{\"name\": \"Иван\", \"email\": \"ivan@example.com\"}\n\nТекст для обработки:\n\"Меня зовут Петр, мой email petr@test.com\"\n",[1745,6378,6376],{"__ignoreMap":1743},[14,6380,6381],{},[36,6382,6383],{},"Паттерн 2: Обертка в XML-теги + парсинг",[1737,6385,6388],{"className":6386,"code":6387,"language":1742,"meta":1743},[1740],"Верни результат в тегах \u003Cjson>...\u003C\u002Fjson>.\n\nПример:\n\u003Cjson>\n{\"name\": \"Иван\", \"email\": \"ivan@example.com\"}\n\u003C\u002Fjson>\n",[1745,6389,6387],{"__ignoreMap":1743},[14,6391,6392],{},"На PHP:",[1737,6394,6396],{"className":3898,"code":6395,"language":3900,"meta":1743,"style":1743},"$response = $llm->generate($prompt);\n\n\u002F\u002F Извлекаем JSON из тегов\nif (preg_match('\u002F\u003Cjson>(.*?)\u003C\\\u002Fjson>\u002Fs', $response, $matches)) {\n    $jsonString = trim($matches[1]);\n    $data = json_decode($jsonString, true);\n    \n    if (json_last_error() === JSON_ERROR_NONE) {\n        \u002F\u002F Успешно\n    } else {\n        \u002F\u002F Попытка восстановить JSON\n        $data = attemptJsonRepair($jsonString);\n    }\n}\n",[1745,6397,6398,6413,6417,6422,6459,6476,6492,6497,6514,6519,6528,6533,6546,6550],{"__ignoreMap":1743},[43,6399,6400,6402,6404,6406,6408,6410],{"class":3905,"line":3906},[43,6401,6090],{"class":3923},[43,6403,432],{"class":3919},[43,6405,6095],{"class":3923},[43,6407,3920],{"class":3919},[43,6409,6100],{"class":3929},[43,6411,6412],{"class":3923},"($prompt);\n",[43,6414,6415],{"class":3905,"line":3502},[43,6416,3946],{"emptyLinePlaceholder":3528},[43,6418,6419],{"class":3905,"line":3499},[43,6420,6421],{"class":3909},"\u002F\u002F Извлекаем JSON из тегов\n",[43,6423,6424,6426,6428,6431,6433,6436,6440,6443,6446,6450,6453,6456],{"class":3905,"line":3949},[43,6425,6157],{"class":3919},[43,6427,4508],{"class":3923},[43,6429,6430],{"class":3915},"preg_match",[43,6432,699],{"class":3923},[43,6434,6435],{"class":5881},"'\u002F",[43,6437,6439],{"class":6438},"sA_wV","\u003Cjson>(.",[43,6441,6442],{"class":3919},"*",[43,6444,6445],{"class":6438},"?)\u003C",[43,6447,6449],{"class":6448},"snhLl","\\\u002F",[43,6451,6452],{"class":6438},"json>",[43,6454,6455],{"class":5881},"\u002Fs'",[43,6457,6458],{"class":3923},", $response, $matches)) {\n",[43,6460,6461,6464,6466,6469,6472,6474],{"class":3905,"line":3955},[43,6462,6463],{"class":3923},"    $jsonString ",[43,6465,432],{"class":3919},[43,6467,6468],{"class":3915}," trim",[43,6470,6471],{"class":3923},"($matches[",[43,6473,707],{"class":3915},[43,6475,6130],{"class":3923},[43,6477,6478,6481,6483,6485,6488,6490],{"class":3905,"line":4306},[43,6479,6480],{"class":3923},"    $data ",[43,6482,432],{"class":3919},[43,6484,6144],{"class":3915},[43,6486,6487],{"class":3923},"($jsonString, ",[43,6489,75],{"class":3915},[43,6491,6152],{"class":3923},[43,6493,6494],{"class":3905,"line":4312},[43,6495,6496],{"class":3923},"    \n",[43,6498,6499,6502,6504,6506,6508,6510,6512],{"class":3905,"line":5684},[43,6500,6501],{"class":3919},"    if",[43,6503,4508],{"class":3923},[43,6505,6162],{"class":3915},[43,6507,6165],{"class":3923},[43,6509,6168],{"class":3919},[43,6511,6171],{"class":3915},[43,6513,6174],{"class":3923},[43,6515,6516],{"class":3905,"line":5690},[43,6517,6518],{"class":3909},"        \u002F\u002F Успешно\n",[43,6520,6521,6524,6526],{"class":3905,"line":5696},[43,6522,6523],{"class":3923},"    } ",[43,6525,6214],{"class":3919},[43,6527,6217],{"class":3923},[43,6529,6530],{"class":3905,"line":5702},[43,6531,6532],{"class":3909},"        \u002F\u002F Попытка восстановить JSON\n",[43,6534,6535,6538,6540,6543],{"class":3905,"line":5711},[43,6536,6537],{"class":3923},"        $data ",[43,6539,432],{"class":3919},[43,6541,6542],{"class":3929}," attemptJsonRepair",[43,6544,6545],{"class":3923},"($jsonString);\n",[43,6547,6548],{"class":3905,"line":5716},[43,6549,4309],{"class":3923},[43,6551,6552],{"class":3905,"line":5726},[43,6553,4315],{"class":3923},[14,6555,6556],{},[36,6557,6558],{},"Паттерн 3: Retry с валидацией",[1737,6560,6562],{"className":3898,"code":6561,"language":3900,"meta":1743,"style":1743},"$maxRetries = 3;\n$lastError = null;\n\nfor ($i = 0; $i \u003C $maxRetries; $i++) {\n    $response = $llm->generate($prompt);\n    $data = json_decode($response, true);\n    \n    if (json_last_error() === JSON_ERROR_NONE) {\n        \u002F\u002F Валидный JSON\n        break;\n    }\n    \n    $lastError = json_last_error_msg();\n    \n    \u002F\u002F Добавляем ошибку в промпт для следующей попытки\n    $prompt = $originalPrompt . \"\\n\\nПредыдущий ответ был невалидным JSON: $lastError. Попробуй снова.\";\n}\n\nif (json_last_error() !== JSON_ERROR_NONE) {\n    throw new \\Exception(\"Failed to get valid JSON after $maxRetries retries: $lastError\");\n}\n",[1745,6563,6564,6577,6589,6593,6619,6634,6648,6652,6668,6673,6680,6684,6688,6701,6705,6710,6739,6743,6747,6764,6790],{"__ignoreMap":1743},[43,6565,6566,6569,6571,6574],{"class":3905,"line":3906},[43,6567,6568],{"class":3923},"$maxRetries ",[43,6570,432],{"class":3919},[43,6572,6573],{"class":3915}," 3",[43,6575,6576],{"class":3923},";\n",[43,6578,6579,6582,6584,6587],{"class":3905,"line":3502},[43,6580,6581],{"class":3923},"$lastError ",[43,6583,432],{"class":3919},[43,6585,6586],{"class":3915}," null",[43,6588,6576],{"class":3923},[43,6590,6591],{"class":3905,"line":3499},[43,6592,3946],{"emptyLinePlaceholder":3528},[43,6594,6595,6598,6601,6603,6606,6609,6611,6614,6617],{"class":3905,"line":3949},[43,6596,6597],{"class":3919},"for",[43,6599,6600],{"class":3923}," ($i ",[43,6602,432],{"class":3919},[43,6604,6605],{"class":3915}," 0",[43,6607,6608],{"class":3923},"; $i ",[43,6610,932],{"class":3919},[43,6612,6613],{"class":3923}," $maxRetries; $i",[43,6615,6616],{"class":3919},"++",[43,6618,6174],{"class":3923},[43,6620,6621,6624,6626,6628,6630,6632],{"class":3905,"line":3955},[43,6622,6623],{"class":3923},"    $response ",[43,6625,432],{"class":3919},[43,6627,6095],{"class":3923},[43,6629,3920],{"class":3919},[43,6631,6100],{"class":3929},[43,6633,6412],{"class":3923},[43,6635,6636,6638,6640,6642,6644,6646],{"class":3905,"line":4306},[43,6637,6480],{"class":3923},[43,6639,432],{"class":3919},[43,6641,6144],{"class":3915},[43,6643,6147],{"class":3923},[43,6645,75],{"class":3915},[43,6647,6152],{"class":3923},[43,6649,6650],{"class":3905,"line":4312},[43,6651,6496],{"class":3923},[43,6653,6654,6656,6658,6660,6662,6664,6666],{"class":3905,"line":5684},[43,6655,6501],{"class":3919},[43,6657,4508],{"class":3923},[43,6659,6162],{"class":3915},[43,6661,6165],{"class":3923},[43,6663,6168],{"class":3919},[43,6665,6171],{"class":3915},[43,6667,6174],{"class":3923},[43,6669,6670],{"class":3905,"line":5690},[43,6671,6672],{"class":3909},"        \u002F\u002F Валидный JSON\n",[43,6674,6675,6678],{"class":3905,"line":5696},[43,6676,6677],{"class":3919},"        break",[43,6679,6576],{"class":3923},[43,6681,6682],{"class":3905,"line":5702},[43,6683,4309],{"class":3923},[43,6685,6686],{"class":3905,"line":5711},[43,6687,6496],{"class":3923},[43,6689,6690,6693,6695,6698],{"class":3905,"line":5716},[43,6691,6692],{"class":3923},"    $lastError ",[43,6694,432],{"class":3919},[43,6696,6697],{"class":3915}," json_last_error_msg",[43,6699,6700],{"class":3923},"();\n",[43,6702,6703],{"class":3905,"line":5726},[43,6704,6496],{"class":3923},[43,6706,6707],{"class":3905,"line":5732},[43,6708,6709],{"class":3909},"    \u002F\u002F Добавляем ошибку в промпт для следующей попытки\n",[43,6711,6712,6715,6717,6720,6722,6725,6728,6731,6734,6737],{"class":3905,"line":5738},[43,6713,6714],{"class":3923},"    $prompt ",[43,6716,432],{"class":3919},[43,6718,6719],{"class":3923}," $originalPrompt ",[43,6721,1052],{"class":3919},[43,6723,6724],{"class":5881}," \"",[43,6726,6727],{"class":3915},"\\n\\n",[43,6729,6730],{"class":5881},"Предыдущий ответ был невалидным JSON: ",[43,6732,6733],{"class":3923},"$lastError",[43,6735,6736],{"class":5881},". Попробуй снова.\"",[43,6738,6576],{"class":3923},[43,6740,6741],{"class":3905,"line":5744},[43,6742,4315],{"class":3923},[43,6744,6745],{"class":3905,"line":5750},[43,6746,3946],{"emptyLinePlaceholder":3528},[43,6748,6749,6751,6753,6755,6757,6760,6762],{"class":3905,"line":5756},[43,6750,6157],{"class":3919},[43,6752,4508],{"class":3923},[43,6754,6162],{"class":3915},[43,6756,6165],{"class":3923},[43,6758,6759],{"class":3919},"!==",[43,6761,6171],{"class":3915},[43,6763,6174],{"class":3923},[43,6765,6766,6768,6770,6772,6774,6777,6780,6783,6785,6788],{"class":3905,"line":5761},[43,6767,6227],{"class":3919},[43,6769,6189],{"class":3919},[43,6771,6232],{"class":3915},[43,6773,699],{"class":3923},[43,6775,6776],{"class":5881},"\"Failed to get valid JSON after ",[43,6778,6779],{"class":3923},"$maxRetries",[43,6781,6782],{"class":5881}," retries: ",[43,6784,6733],{"class":3923},[43,6786,6787],{"class":5881},"\"",[43,6789,6152],{"class":3923},[43,6791,6792],{"class":3905,"line":5766},[43,6793,4315],{"class":3923},[14,6795,6796],{},[36,6797,6798],{},"Паттерн 4: Function Calling (Tool Use)",[14,6800,6801],{},"Вместо JSON Mode используйте function calling — многие модели лучше справляются с вызовом функций, чем с генерацией JSON:",[1737,6803,6805],{"className":5863,"code":6804,"language":5865,"meta":1743,"style":1743},"{\n  \"tools\": [\n    {\n      \"type\": \"function\",\n      \"function\": {\n        \"name\": \"extract_user\",\n        \"description\": \"Извлекает имя и email из текста\",\n        \"parameters\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"name\": {\"type\": \"string\"},\n            \"email\": {\"type\": \"string\"}\n          },\n          \"required\": [\"name\", \"email\"]\n        }\n      }\n    }\n  ]\n}\n",[1745,6806,6807,6811,6819,6823,6835,6842,6854,6866,6873,6884,6891,6906,6921,6926,6941,6946,6950,6954,6959],{"__ignoreMap":1743},[43,6808,6809],{"class":3905,"line":3906},[43,6810,4270],{"class":3923},[43,6812,6813,6816],{"class":3905,"line":3502},[43,6814,6815],{"class":3915},"  \"tools\"",[43,6817,6818],{"class":3923},": [\n",[43,6820,6821],{"class":3905,"line":3499},[43,6822,4298],{"class":3923},[43,6824,6825,6828,6830,6833],{"class":3905,"line":3949},[43,6826,6827],{"class":3915},"      \"type\"",[43,6829,3817],{"class":3923},[43,6831,6832],{"class":5881},"\"function\"",[43,6834,5885],{"class":3923},[43,6836,6837,6840],{"class":3905,"line":3955},[43,6838,6839],{"class":3915},"      \"function\"",[43,6841,5905],{"class":3923},[43,6843,6844,6847,6849,6852],{"class":3905,"line":4306},[43,6845,6846],{"class":3915},"        \"name\"",[43,6848,3817],{"class":3923},[43,6850,6851],{"class":5881},"\"extract_user\"",[43,6853,5885],{"class":3923},[43,6855,6856,6859,6861,6864],{"class":3905,"line":4312},[43,6857,6858],{"class":3915},"        \"description\"",[43,6860,3817],{"class":3923},[43,6862,6863],{"class":5881},"\"Извлекает имя и email из текста\"",[43,6865,5885],{"class":3923},[43,6867,6868,6871],{"class":3905,"line":5684},[43,6869,6870],{"class":3915},"        \"parameters\"",[43,6872,5905],{"class":3923},[43,6874,6875,6878,6880,6882],{"class":3905,"line":5690},[43,6876,6877],{"class":3915},"          \"type\"",[43,6879,3817],{"class":3923},[43,6881,5964],{"class":5881},[43,6883,5885],{"class":3923},[43,6885,6886,6889],{"class":3905,"line":5696},[43,6887,6888],{"class":3915},"          \"properties\"",[43,6890,5905],{"class":3923},[43,6892,6893,6896,6898,6900,6902,6904],{"class":3905,"line":5702},[43,6894,6895],{"class":3915},"            \"name\"",[43,6897,5981],{"class":3923},[43,6899,5984],{"class":3915},[43,6901,3817],{"class":3923},[43,6903,5989],{"class":5881},[43,6905,5992],{"class":3923},[43,6907,6908,6911,6913,6915,6917,6919],{"class":3905,"line":5711},[43,6909,6910],{"class":3915},"            \"email\"",[43,6912,5981],{"class":3923},[43,6914,5984],{"class":3915},[43,6916,3817],{"class":3923},[43,6918,5989],{"class":5881},[43,6920,4315],{"class":3923},[43,6922,6923],{"class":3905,"line":5716},[43,6924,6925],{"class":3923},"          },\n",[43,6927,6928,6931,6933,6935,6937,6939],{"class":3905,"line":5726},[43,6929,6930],{"class":3915},"          \"required\"",[43,6932,6030],{"class":3923},[43,6934,6033],{"class":5881},[43,6936,3821],{"class":3923},[43,6938,6015],{"class":5881},[43,6940,6125],{"class":3923},[43,6942,6943],{"class":3905,"line":5732},[43,6944,6945],{"class":3923},"        }\n",[43,6947,6948],{"class":3905,"line":5738},[43,6949,6055],{"class":3923},[43,6951,6952],{"class":3905,"line":5744},[43,6953,4309],{"class":3923},[43,6955,6956],{"class":3905,"line":5750},[43,6957,6958],{"class":3923},"  ]\n",[43,6960,6961],{"class":3905,"line":5756},[43,6962,4315],{"class":3923},[14,6964,6965],{},"Модель вернет:",[1737,6967,6969],{"className":5863,"code":6968,"language":5865,"meta":1743,"style":1743},"{\n  \"tool_calls\": [\n    {\n      \"function\": {\n        \"name\": \"extract_user\",\n        \"arguments\": \"{\\\"name\\\": \\\"Иван\\\", \\\"email\\\": \\\"ivan@example.com\\\"}\"\n      }\n    }\n  ]\n}\n",[1745,6970,6971,6975,6982,6986,6992,7002,7050,7054,7058,7062],{"__ignoreMap":1743},[43,6972,6973],{"class":3905,"line":3906},[43,6974,4270],{"class":3923},[43,6976,6977,6980],{"class":3905,"line":3502},[43,6978,6979],{"class":3915},"  \"tool_calls\"",[43,6981,6818],{"class":3923},[43,6983,6984],{"class":3905,"line":3499},[43,6985,4298],{"class":3923},[43,6987,6988,6990],{"class":3905,"line":3949},[43,6989,6839],{"class":3915},[43,6991,5905],{"class":3923},[43,6993,6994,6996,6998,7000],{"class":3905,"line":3955},[43,6995,6846],{"class":3915},[43,6997,3817],{"class":3923},[43,6999,6851],{"class":5881},[43,7001,5885],{"class":3923},[43,7003,7004,7007,7009,7012,7015,7018,7020,7022,7024,7027,7029,7031,7033,7036,7038,7040,7042,7045,7047],{"class":3905,"line":4306},[43,7005,7006],{"class":3915},"        \"arguments\"",[43,7008,3817],{"class":3923},[43,7010,7011],{"class":5881},"\"{",[43,7013,7014],{"class":3915},"\\\"",[43,7016,7017],{"class":5881},"name",[43,7019,7014],{"class":3915},[43,7021,3817],{"class":5881},[43,7023,7014],{"class":3915},[43,7025,7026],{"class":5881},"Иван",[43,7028,7014],{"class":3915},[43,7030,3821],{"class":5881},[43,7032,7014],{"class":3915},[43,7034,7035],{"class":5881},"email",[43,7037,7014],{"class":3915},[43,7039,3817],{"class":5881},[43,7041,7014],{"class":3915},[43,7043,7044],{"class":5881},"ivan@example.com",[43,7046,7014],{"class":3915},[43,7048,7049],{"class":5881},"}\"\n",[43,7051,7052],{"class":3905,"line":4312},[43,7053,6055],{"class":3923},[43,7055,7056],{"class":3905,"line":5684},[43,7057,4309],{"class":3923},[43,7059,7060],{"class":3905,"line":5690},[43,7061,6958],{"class":3923},[43,7063,7064],{"class":3905,"line":5696},[43,7065,4315],{"class":3923},[14,7067,6392],{},[1737,7069,7071],{"className":3898,"code":7070,"language":3900,"meta":1743,"style":1743},"$response = $llm->generate($prompt, ['tools' => $tools]);\n\nif (isset($response['tool_calls'])) {\n    $args = json_decode($response['tool_calls'][0]['function']['arguments'], true);\n    \u002F\u002F $args['name'], $args['email']\n}\n",[1745,7072,7073,7096,7100,7118,7153,7158],{"__ignoreMap":1743},[43,7074,7075,7077,7079,7081,7083,7085,7088,7091,7093],{"class":3905,"line":3906},[43,7076,6090],{"class":3923},[43,7078,432],{"class":3919},[43,7080,6095],{"class":3923},[43,7082,3920],{"class":3919},[43,7084,6100],{"class":3929},[43,7086,7087],{"class":3923},"($prompt, [",[43,7089,7090],{"class":5881},"'tools'",[43,7092,6111],{"class":3919},[43,7094,7095],{"class":3923}," $tools]);\n",[43,7097,7098],{"class":3905,"line":3502},[43,7099,3946],{"emptyLinePlaceholder":3528},[43,7101,7102,7104,7106,7109,7112,7115],{"class":3905,"line":3499},[43,7103,6157],{"class":3919},[43,7105,4508],{"class":3923},[43,7107,7108],{"class":3915},"isset",[43,7110,7111],{"class":3923},"($response[",[43,7113,7114],{"class":5881},"'tool_calls'",[43,7116,7117],{"class":3923},"])) {\n",[43,7119,7120,7123,7125,7127,7129,7131,7134,7136,7138,7141,7143,7146,7149,7151],{"class":3905,"line":3949},[43,7121,7122],{"class":3923},"    $args ",[43,7124,432],{"class":3919},[43,7126,6144],{"class":3915},[43,7128,7111],{"class":3923},[43,7130,7114],{"class":5881},[43,7132,7133],{"class":3923},"][",[43,7135,196],{"class":3915},[43,7137,7133],{"class":3923},[43,7139,7140],{"class":5881},"'function'",[43,7142,7133],{"class":3923},[43,7144,7145],{"class":5881},"'arguments'",[43,7147,7148],{"class":3923},"], ",[43,7150,75],{"class":3915},[43,7152,6152],{"class":3923},[43,7154,7155],{"class":3905,"line":3955},[43,7156,7157],{"class":3909},"    \u002F\u002F $args['name'], $args['email']\n",[43,7159,7160],{"class":3905,"line":4306},[43,7161,4315],{"class":3923},[14,7163,7164],{},[36,7165,7166],{},"Паттерн 5: Post-processing с LLM",[14,7168,7169],{},"Если модель сгенерировала \"грязный\" JSON, используйте вторую (более дешевую) модель для очистки:",[1737,7171,7173],{"className":3898,"code":7172,"language":3900,"meta":1743,"style":1743},"$dirtyResponse = $llm->generate($extractionPrompt);\n\n$cleanupPrompt = \"Исправь этот JSON, чтобы он был валидным. Верни ТОЛЬКО исправленный JSON:\\n\" . $dirtyResponse;\n$cleanJson = $cheapLlm->generate($cleanupPrompt);\n\n$data = json_decode($cleanJson, true);\n",[1745,7174,7175,7191,7195,7216,7233,7237],{"__ignoreMap":1743},[43,7176,7177,7180,7182,7184,7186,7188],{"class":3905,"line":3906},[43,7178,7179],{"class":3923},"$dirtyResponse ",[43,7181,432],{"class":3919},[43,7183,6095],{"class":3923},[43,7185,3920],{"class":3919},[43,7187,6100],{"class":3929},[43,7189,7190],{"class":3923},"($extractionPrompt);\n",[43,7192,7193],{"class":3905,"line":3502},[43,7194,3946],{"emptyLinePlaceholder":3528},[43,7196,7197,7200,7202,7205,7208,7210,7213],{"class":3905,"line":3499},[43,7198,7199],{"class":3923},"$cleanupPrompt ",[43,7201,432],{"class":3919},[43,7203,7204],{"class":5881}," \"Исправь этот JSON, чтобы он был валидным. Верни ТОЛЬКО исправленный JSON:",[43,7206,7207],{"class":3915},"\\n",[43,7209,6787],{"class":5881},[43,7211,7212],{"class":3919}," .",[43,7214,7215],{"class":3923}," $dirtyResponse;\n",[43,7217,7218,7221,7223,7226,7228,7230],{"class":3905,"line":3949},[43,7219,7220],{"class":3923},"$cleanJson ",[43,7222,432],{"class":3919},[43,7224,7225],{"class":3923}," $cheapLlm",[43,7227,3920],{"class":3919},[43,7229,6100],{"class":3929},[43,7231,7232],{"class":3923},"($cleanupPrompt);\n",[43,7234,7235],{"class":3905,"line":3955},[43,7236,3946],{"emptyLinePlaceholder":3528},[43,7238,7239,7241,7243,7245,7248,7250],{"class":3905,"line":4306},[43,7240,6139],{"class":3923},[43,7242,432],{"class":3919},[43,7244,6144],{"class":3915},[43,7246,7247],{"class":3923},"($cleanJson, ",[43,7249,75],{"class":3915},[43,7251,6152],{"class":3923},[14,7253,7254],{},[36,7255,7256],{},"Практические рекомендации",[14,7258,7259],{},[36,7260,7261],{},"Для продакшена с критичными данными:",[2016,7263,7264,7269,7281,7293,7306,7311],{},[1331,7265,7266],{},[36,7267,7268],{},"Облако:",[1331,7270,7271],{},[2016,7272,7273],{},[1331,7274,7275,90,7278,7280],{},[36,7276,7277],{},"OpenAI GPT-4.1",[36,7279,5338],{}," — Structured Outputs со строгим соблюдением переданной JSON-схемы.",[1331,7282,7283],{},[2016,7284,7285],{},[1331,7286,7287,90,7290,7292],{},[36,7288,7289],{},"Anthropic Claude Sonnet 4",[36,7291,5287],{}," — JSON через tool use, гарантированно валидный и идеально подходящий для сложных многошаговых сценариев.",[1331,7294,7295],{},[2016,7296,7297],{},[1331,7298,7299,90,7302,7305],{},[36,7300,7301],{},"Google Gemini 2.5 Pro",[36,7303,7304],{},"Flash"," — нативный JSON Mode + Controlled Generation с явным указанием схемы.",[1331,7307,7308],{},[36,7309,7310],{},"Локально:",[1331,7312,7313],{},[2016,7314,7315],{},[1331,7316,7317,7320],{},[36,7318,7319],{},"vLLM с guided decoding + сильная модель",": Qwen 3 32B, DeepSeek V3.1 (развёрнутая через vLLM), Mistral Small 3 24B. Это даёт 100% валидный JSON на собственной инфраструктуре без компромиссов по приватности.",[14,7322,7323],{},[36,7324,7325],{},"Для локального запуска с Ollama:",[2016,7327,7328,7331,7334],{},[1331,7329,7330],{},"Используйте встроенную поддержку JSON Schema: передайте желаемую структуру через параметр format (с версии Ollama 0.5.0+). Модель будет сгенерирована с грамматикой, гарантирующей точное соответствие схеме.",[1331,7332,7333],{},"Рекомендуемые модели: Qwen 3 8B (универсальная), Mistral Small 3 24B (с упором на код и логику), Llama 4 Scout (если хватает памяти). Для простых задач отлично работают Phi-4-mini или Gemma 3 4B.",[1331,7335,7336],{},"Паттерны с XML-тегами и повторными попытками (retry) больше не обязательны — грамматика исключает невалидный вывод на корню.",[14,7338,7339],{},[36,7340,7341],{},"Для маленьких моделей (\u003C 7B):",[2016,7343,7344,7347,7350],{},[1331,7345,7346],{},"Принудительная JSON-грамматика гарантирует валидность даже на скромных моделях, однако смысловое наполнение может уступать старшим собратьям.",[1331,7348,7349],{},"Чтобы повысить точность, обязательно добавляйте few-shot примеры в промпт — это помогает модели лучше понять, какие данные ожидаются в полях.",[1331,7351,7352],{},"Для критичных приложений придерживайтесь простых схем (один–два уровня вложенности) и всегда проверяйте смысловую корректность ответа.",[5274,7354,7356],{"id":7355},"_4-специальные-токены-chat-templates","4. Специальные токены (Chat Templates)",[14,7358,7359],{},"У разных моделей есть свои особенности разметки диалога:",[2016,7361,7362,7370,7378],{},[1331,7363,7364,1941,7367],{},[36,7365,7366],{},"Mistral:",[1745,7368,7369],{},"[INST] Инструкция [\u002FINST] Ответ",[1331,7371,7372,1941,7375],{},[36,7373,7374],{},"Llama 3:",[1745,7376,7377],{},"\u003C|start_header_id|>user\u003C|end_header_id|> Сообщение \u003C|eot_id|>",[1331,7379,7380,1941,7383],{},[36,7381,7382],{},"ChatML (OpenAI):",[1745,7384,7385],{},"\u003C|im_start|>Предоставьте контекст и\u002Fили инструкции для модели.\u003C|im_end|>",[21,7387],{},[24,7389,7391],{"id":7390},"_6-почему-сделай-мне-хорошо-не-работает-сила-детализации","6. Почему «сделай мне хорошо» не работает: Сила детализации",[14,7393,7394,7395,7398],{},"А теперь главный практический вывод. Почему запрос «",[17,7396,7397],{},"сделай мне хорошо","» не работает?",[14,7400,7401],{},"Потому что LLM не может прочитать ваши мысли. Если вы не описали требование в промпте, его для модели не существует.\nМодель работает по принципу близости токенов — она сильнее всего связывает слова, которые стоят рядом в вашем запросе.\nЧем детальнее запрос, тем точнее результат.",[14,7403,7404],{},"Давайте посмотрим на конкретный кейс с PHP.",[14,7406,7407,7410,7411,7414,7415,7418],{},[36,7408,7409],{},"Плохой запрос:"," «",[17,7412,7413],{},"Напиши скрипт на PHP для сохранения пользователя","». Что вы получите?\nСкорее всего, устаревший код с ",[1745,7416,7417],{},"mysql_query"," (который давно deprecated) или спагетти-код без валидации, без обработки ошибок, без типизации.\nМодель сделала то, что вы попросили — написала скрипт. Но она не знает, что вам нужен production-ready код.",[14,7420,7421,7410,7424,7431],{},[36,7422,7423],{},"Хороший запрос:",[17,7425,7426,7427,7430],{},"Напиши класс на PHP 8.5 для сохранения пользователя.\nИспользуй Clean Architecture, строгую типизацию (",[1745,7428,7429],{},"declare(strict_types=1)","), паттерн Repository, PDO для работы с базой данных и кастомные исключения.\nДобавь PHPDoc для всех методов","». Что вы получите?\nГотовый к использованию код, который соответствует современным стандартам, с правильной архитектурой, типизацией и документацией.",[14,7433,7434],{},"Разница колоссальная. И эта разница — в детализации запроса.",[14,7436,7437,7438,7441,7442,7445],{},"Еще один важный инструмент — ",[36,7439,7440],{},"System Prompt",". Это инструкция, которая действует на протяжении всего диалога.\nНапример: «",[17,7443,7444],{},"Ты опытный PHP-разработчик с 10-летним стажем. Ты всегда проверяешь входные данные.\nТы используешь PSR-12. Ты пишешь PHPDoc для всех публичных методов","».\nЭтот промпт задает контекст и роль модели для всего разговора.",[123,7447,7449],{"id":7448},"паттерны-промпт-инжиниринга","Паттерны промпт-инжиниринга",[5274,7451,7453],{"id":7452},"паттерн-1-chain-of-thought-cot-думай-шаг-за-шагом","Паттерн 1: Chain of Thought (CoT) — \"Думай шаг за шагом\"",[14,7455,7456],{},"Модели гораздо лучше решают сложные задачи, если явно попросить их рассуждать вслух. Это особенно важно для рефакторинга, анализа кода, отладки.",[14,7458,7459],{},[36,7460,7461],{},"Плохой промпт:",[1737,7463,7466],{"className":7464,"code":7465,"language":1742,"meta":1743},[1740],"Найди баг в этом PHP-коде и исправь его.\n",[1745,7467,7465],{"__ignoreMap":1743},[14,7469,7470],{},"Модель может пропустить тонкую ошибку или предложить неверное решение.",[14,7472,7473],{},[36,7474,7475],{},"Хороший промпт с CoT:",[1737,7477,7480],{"className":7478,"code":7479,"language":1742,"meta":1743},[1740],"Проанализируй этот PHP-код шаг за шагом:\n\n1. Сначала опиши, что делает каждая функция\n2. Затем найди потенциальные баги (учти race conditions, SQL injection, \n   проблемы с типами)\n3. Для каждого бага объясни, почему он опасен\n4. Предложи исправление с примером кода\n\n\u003Ccode>\n\u003C?php\nfunction getUserById($id) {\n    global $db;\n    $result = $db->query(\"SELECT * FROM users WHERE id = $id\");\n    return $result->fetch();\n}\n\u003C\u002Fcode>\n",[1745,7481,7479],{"__ignoreMap":1743},[14,7483,7484,7487],{},[36,7485,7486],{},"Почему это работает:"," Модель вынуждена \"пройтись\" по коду логически, а не угадывать ответ. Качество исправлений вырастает на 30-50% по бенчмаркам.",[5274,7489,7491],{"id":7490},"паттерн-2-few-shot-примеры-в-промпте","Паттерн 2: Few-shot — примеры в промпте",[14,7493,7494],{},"Модель учится \"на лету\" из примеров, которые вы даете в промпте. Это критически важно для задач классификации, извлечения данных, форматирования.",[14,7496,7497],{},[36,7498,7499],{},"Пример для извлечения сущностей из логов:",[1737,7501,7504],{"className":7502,"code":7503,"language":1742,"meta":1743},[1740],"Извлеки из текста лога уровень, сообщение и контекст.\n\nПример 1:\nТекст: \"[ERROR] Connection failed: timeout after 30s (db=primary)\"\nОтвет: {\"level\": \"ERROR\", \"message\": \"Connection failed: timeout after 30s\", \"context\": {\"db\": \"primary\"}}\n\nПример 2:\nТекст: \"[INFO] User logged in successfully (user_id=123, ip=192.168.1.1)\"\nОтвет: {\"level\": \"INFO\", \"message\": \"User logged in successfully\", \"context\": {\"user_id\": \"123\", \"ip\": \"192.168.1.1\"}}\n\nТекст для обработки:\n\"[WARNING] Disk space low: 5% remaining (server=web-01, path=\u002Fvar\u002Flog)\"\n",[1745,7505,7503],{"__ignoreMap":1743},[14,7507,7508,7510],{},[36,7509,7486],{}," Модель видит паттерн и воспроизводит его. Без примеров она может вернуть JSON в другом формате, с другими ключами или вообще текстом.",[14,7512,7513],{},[36,7514,6392],{},[1737,7516,7518],{"className":3898,"code":7517,"language":3900,"meta":1743,"style":1743},"$examples = [\n    ['input' => '[ERROR] ...', 'output' => ['level' => 'ERROR', ...]],\n    ['input' => '[INFO] ...', 'output' => ['level' => 'INFO', ...]],\n];\n\n$prompt = buildFewShotPrompt($examples, $newLogEntry);\n$response = $llm->generate($prompt, ['response_format' => ['type' => 'json_object']]);\n",[1745,7519,7520,7530,7567,7599,7604,7608,7621],{"__ignoreMap":1743},[43,7521,7522,7525,7527],{"class":3905,"line":3906},[43,7523,7524],{"class":3923},"$examples ",[43,7526,432],{"class":3919},[43,7528,7529],{"class":3923}," [\n",[43,7531,7532,7535,7538,7540,7543,7545,7548,7550,7552,7555,7557,7560,7562,7564],{"class":3905,"line":3502},[43,7533,7534],{"class":3923},"    [",[43,7536,7537],{"class":5881},"'input'",[43,7539,6111],{"class":3919},[43,7541,7542],{"class":5881}," '[ERROR] ...'",[43,7544,3821],{"class":3923},[43,7546,7547],{"class":5881},"'output'",[43,7549,6111],{"class":3919},[43,7551,6114],{"class":3923},[43,7553,7554],{"class":5881},"'level'",[43,7556,6111],{"class":3919},[43,7558,7559],{"class":5881}," 'ERROR'",[43,7561,3821],{"class":3923},[43,7563,4209],{"class":3919},[43,7565,7566],{"class":3923},"]],\n",[43,7568,7569,7571,7573,7575,7578,7580,7582,7584,7586,7588,7590,7593,7595,7597],{"class":3905,"line":3499},[43,7570,7534],{"class":3923},[43,7572,7537],{"class":5881},[43,7574,6111],{"class":3919},[43,7576,7577],{"class":5881}," '[INFO] ...'",[43,7579,3821],{"class":3923},[43,7581,7547],{"class":5881},[43,7583,6111],{"class":3919},[43,7585,6114],{"class":3923},[43,7587,7554],{"class":5881},[43,7589,6111],{"class":3919},[43,7591,7592],{"class":5881}," 'INFO'",[43,7594,3821],{"class":3923},[43,7596,4209],{"class":3919},[43,7598,7566],{"class":3923},[43,7600,7601],{"class":3905,"line":3949},[43,7602,7603],{"class":3923},"];\n",[43,7605,7606],{"class":3905,"line":3955},[43,7607,3946],{"emptyLinePlaceholder":3528},[43,7609,7610,7613,7615,7618],{"class":3905,"line":4306},[43,7611,7612],{"class":3923},"$prompt ",[43,7614,432],{"class":3919},[43,7616,7617],{"class":3929}," buildFewShotPrompt",[43,7619,7620],{"class":3923},"($examples, $newLogEntry);\n",[43,7622,7623,7625,7627,7629,7631,7633,7635,7638,7640,7642,7644,7646,7648],{"class":3905,"line":4312},[43,7624,6090],{"class":3923},[43,7626,432],{"class":3919},[43,7628,6095],{"class":3923},[43,7630,3920],{"class":3919},[43,7632,6100],{"class":3929},[43,7634,7087],{"class":3923},[43,7636,7637],{"class":5881},"'response_format'",[43,7639,6111],{"class":3919},[43,7641,6114],{"class":3923},[43,7643,6117],{"class":5881},[43,7645,6111],{"class":3919},[43,7647,6122],{"class":5881},[43,7649,7650],{"class":3923},"]]);\n",[5274,7652,7654],{"id":7653},"паттерн-3-decomposition-разбиение-сложной-задачи","Паттерн 3: Decomposition — разбиение сложной задачи",[14,7656,7657],{},"Если задача слишком сложная для одного промпта, разбейте её на подзадачи. Это особенно полезно для генерации сложной архитектуры.",[14,7659,7660],{},[36,7661,7461],{},[1737,7663,7666],{"className":7664,"code":7665,"language":1742,"meta":1743},[1740],"Создай систему аутентификации на PHP с JWT, refresh tokens, \nrate limiting и двухфакторной аутентификацией.\n",[1745,7667,7665],{"__ignoreMap":1743},[14,7669,7670],{},"Модель выдаст поверхностный код, не покрывающий все аспекты.",[14,7672,7673],{},[36,7674,7675],{},"Хороший промпт с декомпозицией:",[1737,7677,7680],{"className":7678,"code":7679,"language":1742,"meta":1743},[1740],"Мы строим систему аутентификации. Реализуй ТОЛЬКО первый компонент:\n\nЗадача: Создать класс JwtTokenService на PHP 8.5\n\nТребования:\n- Использование HMAC SHA256 для подписи\n- Поддержка access и refresh токенов с разными TTL\n- Методы: generateAccessToken(), generateRefreshToken(), validateToken()\n- Обработка истекших токенов через кастомное исключение TokenExpiredException\n- Строгая типизация, PHPDoc для всех методов\n\nНе пиши остальные компоненты (контроллеры, middleware) — только этот сервис.\n",[1745,7681,7679],{"__ignoreMap":1743},[14,7683,7684],{},"Затем в следующем запросе:",[1737,7686,7689],{"className":7687,"code":7688,"language":1742,"meta":1743},[1740],"Теперь создай AuthMiddleware, который использует JwtTokenService...\n",[1745,7690,7688],{"__ignoreMap":1743},[14,7692,7693,7695],{},[36,7694,7486],{}," Модель фокусируется на одной задаче и выдает production-ready код. Каждый компонент можно протестировать отдельно.",[5274,7697,7699],{"id":7698},"паттерн-4-generated-knowledge-модель-генерирует-контекст","Паттерн 4: Generated Knowledge — модель генерирует контекст",[14,7701,7702],{},"Попросите модель сначала сгенерировать релевантные знания, а потом использовать их для ответа.",[14,7704,7705],{},[36,7706,7707],{},"Пример:",[1737,7709,7712],{"className":7710,"code":7711,"language":1742,"meta":1743},[1740],"Шаг 1: Перечисли 5 лучших практик безопасности для PHP-приложений, \nработающих с пользовательскими данными.\n\nШаг 2: Используя эти практики, проверь этот код и предложи улучшения:\n\u003Ccode>...\u003C\u002Fcode>\n",[1745,7713,7711],{"__ignoreMap":1743},[14,7715,7716,7718],{},[36,7717,7486],{}," Модель \"вспоминает\" релевантные знания перед анализом, что повышает качество рекомендаций.",[5274,7720,7722],{"id":7721},"паттерн-5-react-reason-act-мостик-к-агентам","Паттерн 5: ReAct (Reason + Act) — мостик к агентам",[14,7724,7725],{},"Это основа работы агентов. Модель чередует рассуждения и действия.",[14,7727,7728],{},[36,7729,7730],{},"Пример промпта для агента:",[1737,7732,7735],{"className":7733,"code":7734,"language":1742,"meta":1743},[1740],"Ты PHP-разработчик с доступом к инструментам:\n- read_file(path) — читает файл\n- run_tests() — запускает PHPUnit\n- search_codebase(query) — ищет по коду\n\nЗадача: Исправь падающий тест UserServiceTest::testCreateUser\n\nДумай вслух:\n1. Какие файлы нужно прочитать?\n2. Какой инструмент вызвать?\n3. Что показал результат?\n4. Что делать дальше?\n\nФормат ответа:\nThought: [твои рассуждения]\nAction: [инструмент(аргументы)]\n",[1745,7736,7734],{"__ignoreMap":1743},[14,7738,7739],{},"Почему это работает: Модель получает возможность \"исследовать\" кодовую базу, а не гадать.",[123,7741,7743],{"id":7742},"антипаттерны-промпт-инжиниринга-чего-не-делать","Антипаттерны промпт-инжиниринга (чего НЕ делать)",[5274,7745,7747],{"id":7746},"антипаттерн-1-негативные-инструкции","Антипаттерн 1: Негативные инструкции",[14,7749,7750],{},[36,7751,7752],{},"Плохо:",[1737,7754,7757],{"className":7755,"code":7756,"language":1742,"meta":1743},[1740],"Не используй устаревшие функции.\nНе забывай про обработку ошибок.\n",[1745,7758,7756],{"__ignoreMap":1743},[14,7760,7761],{},[36,7762,7763],{},"Хорошо:",[1737,7765,7768],{"className":7766,"code":7767,"language":1742,"meta":1743},[1740],"Используй только функции PHP 8.5+.\nДля каждой операции с БД добавляй try-catch с логированием.\n",[1745,7769,7767],{"__ignoreMap":1743},[14,7771,7772,7775],{},[36,7773,7774],{},"Почему:"," Модель плохо понимает отрицания. Она может сфокусироваться на \"устаревших функциях\" и начать их использовать. Позитивные инструкции работают надежнее.",[5274,7777,7779],{"id":7778},"антипаттерн-2-перегрузка-промпта","Антипаттерн 2: Перегрузка промпта",[14,7781,7782],{},[36,7783,7752],{},[1737,7785,7788],{"className":7786,"code":7787,"language":1742,"meta":1743},[1740],"Ты эксперт. Используй PSR-12. Пиши PHPDoc. Обрабатывай ошибки. \nИспользуй Clean Architecture. Добавь тесты. Оптимизируй производительность. \nСледуй SOLID. Используй dependency injection. Пиши комментарии. \nПроверяй входные данные. Логируй все действия. Используй кэширование.\n... \n(20+ требований в одном промпте)\n",[1745,7789,7787],{"__ignoreMap":1743},[14,7791,7792],{},[36,7793,7763],{},[1737,7795,7798],{"className":7796,"code":7797,"language":1742,"meta":1743},[1740],"Главные приоритеты (в порядке важности):\n1. Строгая типизация PHP 8.5\n2. Обработка ошибок через try-catch\n3. PHPDoc для публичных методов\n\nОстальное — по возможности.\n",[1745,7799,7797],{"__ignoreMap":1743},[14,7801,7802,7804],{},[36,7803,7774],{}," Модель теряет фокус при слишком длинных инструкциях. Приоритизация помогает ей понять, что критично, а что — опционально.",[5274,7806,7808],{"id":7807},"антипаттерн-3-отсутствие-примеров","Антипаттерн 3: Отсутствие примеров",[14,7810,7811],{},[36,7812,7752],{},[1737,7814,7817],{"className":7815,"code":7816,"language":1742,"meta":1743},[1740],"Верни результат в формате JSON.\n",[1745,7818,7816],{"__ignoreMap":1743},[14,7820,7821],{},[36,7822,7763],{},[1737,7824,7827],{"className":7825,"code":7826,"language":1742,"meta":1743},[1740],"Верни результат в формате JSON. Пример:\n{\n  \"status\": \"success\",\n  \"data\": {\n    \"user_id\": 123,\n    \"action\": \"created\"\n  }\n}\n",[1745,7828,7826],{"__ignoreMap":1743},[14,7830,7831,7833],{},[36,7832,7774],{}," Без примера модель может интерпретировать \"формат JSON\" по-своему (другие ключи, другая структура, вложенность).",[5274,7835,7837],{"id":7836},"антипаттерн-4-противоречивые-инструкции","Антипаттерн 4: Противоречивые инструкции",[14,7839,7840],{},[36,7841,7752],{},[1737,7843,7846],{"className":7844,"code":7845,"language":1742,"meta":1743},[1740],"Напиши максимально короткий код.\nДобавь подробные комментарии к каждой строке.\n",[1745,7847,7845],{"__ignoreMap":1743},[14,7849,7850],{},[36,7851,7763],{},[1737,7853,7856],{"className":7854,"code":7855,"language":1742,"meta":1743},[1740],"Напиши лаконичный код (без избыточных абстракций).\nДобавь PHPDoc только для публичных методов.\n",[1745,7857,7855],{"__ignoreMap":1743},[14,7859,7860,7862],{},[36,7861,7774],{}," Модель будет метаться между противоречиями и выдаст неоптимальный результат.",[5274,7864,7866],{"id":7865},"антипаттерн-5-ты-эксперт-без-конкретики","Антипаттерн 5: \"Ты эксперт\" без конкретики",[14,7868,7869],{},[36,7870,7752],{},[1737,7872,7875],{"className":7873,"code":7874,"language":1742,"meta":1743},[1740],"Ты эксперт по PHP.\n",[1745,7876,7874],{"__ignoreMap":1743},[14,7878,7879],{},[36,7880,7763],{},[1737,7882,7885],{"className":7883,"code":7884,"language":1742,"meta":1743},[1740],"Ты senior PHP-разработчик с 10-летним опытом в:\n- Laravel и Symfony\n- Clean Architecture и DDD\n- Оптимизации производительности\n- Безопасности веб-приложений\n\nТы следуешь принципам:\n- PSR-12 для стиля кода\n- SOLID для архитектуры\n- TDD для тестирования\n",[1745,7886,7884],{"__ignoreMap":1743},[14,7888,7889,7891],{},[36,7890,7774],{}," \"Эксперт\" — это размытое понятие. Конкретные навыки и принципы дают модели четкий контекст.",[5274,7893,7895],{"id":7894},"антипаттерн-6-игнорирование-формата-вывода","Антипаттерн 6: Игнорирование формата вывода",[14,7897,7898],{},[36,7899,7752],{},[1737,7901,7904],{"className":7902,"code":7903,"language":1742,"meta":1743},[1740],"Проанализируй этот код и скажи, есть ли баги.\n",[1745,7905,7903],{"__ignoreMap":1743},[14,7907,7908],{},"Модель вернет текст на 500 слов, который сложно распарсить.",[14,7910,7911],{},[36,7912,7763],{},[1737,7914,7917],{"className":7915,"code":7916,"language":1742,"meta":1743},[1740],"Проанализируй этот код. Верни результат СТРОГО в формате:\n{\n  \"has_bugs\": true\u002Ffalse,\n  \"bugs\": [\n    {\n      \"line\": номер_строки,\n      \"severity\": \"critical|warning|info\",\n      \"description\": \"описание\",\n      \"fix\": \"предложение по исправлению\"\n    }\n  ]\n}\n",[1745,7918,7916],{"__ignoreMap":1743},[14,7920,7921,7923],{},[36,7922,7774],{}," Без четкого формата вывод придется парсить вручную или писать сложный regex.",[123,7925,7927],{"id":7926},"чек-лист-хорошего-промпта","Чек-лист хорошего промпта",[14,7929,7930],{},"Перед отправкой запроса проверьте:",[1328,7932,7933,7944,7955,7966,7977,7988],{},[1331,7934,7935,7936],{},"Роль и контекст\n",[2016,7937,7938,7941],{},[1331,7939,7940],{},"Указана роль модели (кто она, какой опыт)",[1331,7942,7943],{},"Описан контекст задачи (зачем мы это делаем)",[1331,7945,7946,7947],{},"Четкая задача\n",[2016,7948,7949,7952],{},[1331,7950,7951],{},"Сформулирована одна конкретная задача (не \"сделай всё\")",[1331,7953,7954],{},"Использованы позитивные инструкции (\"делай X\", а не \"не делай Y\")",[1331,7956,7957,7958],{},"Требования\n",[2016,7959,7960,7963],{},[1331,7961,7962],{},"Приоритизированы (что критично, что опционально)",[1331,7964,7965],{},"Конкретны (PHP 8.5, а не \"современный PHP\")",[1331,7967,7968,7969],{},"Формат вывода\n",[2016,7970,7971,7974],{},[1331,7972,7973],{},"Указан точный формат (JSON, XML, Markdown)",[1331,7975,7976],{},"Дан пример ожидаемого ответа",[1331,7978,7979,7980],{},"Ограничения\n",[2016,7981,7982,7985],{},[1331,7983,7984],{},"Указаны лимиты (длина ответа, используемые библиотеки)",[1331,7986,7987],{},"Указано, что делать, если задача невыполнима (\"скажи 'не знаю'\")",[1331,7989,7990,7991],{},"Контекстные данные\n",[2016,7992,7993,7996],{},[1331,7994,7995],{},"Данные отделены от инструкций (XML-теги)",[1331,7997,7998],{},"Нет противоречий между инструкциями и данными",[123,8000,8002],{"id":8001},"практический-пример-от-плохого-к-идеальному-промпту","Практический пример: от плохого к идеальному промпту",[14,8004,8005,8008],{},[36,8006,8007],{},"Задача:"," Нужно написать PHP-класс для работы с кэшем.",[14,8010,8011],{},[36,8012,8013],{},"Уровень 1 — Плохо:",[1737,8015,8018],{"className":8016,"code":8017,"language":1742,"meta":1743},[1740],"Напиши класс для кэша на PHP.\n",[1745,8019,8017],{"__ignoreMap":1743},[14,8021,8022,8023,8026],{},"Результат: Простой класс с ",[1745,8024,8025],{},"file_put_contents",", без интерфейсов, без обработки ошибок.",[14,8028,8029],{},[36,8030,8031],{},"Уровень 2 — Лучше:",[1737,8033,8036],{"className":8034,"code":8035,"language":1742,"meta":1743},[1740],"Напиши класс Cache на PHP 8.5 для работы с файловым кэшем.\nИспользуй строгую типизацию. Добавь методы get, set, delete.\n",[1745,8037,8035],{"__ignoreMap":1743},[14,8039,8040],{},"Результат: Базовый класс с типизацией, но без интерфейсов, без TTL, без сериализации.",[14,8042,8043],{},[36,8044,8045],{},"Уровень 3 — Хорошо:",[1737,8047,8050],{"className":8048,"code":8049,"language":1742,"meta":1743},[1740],"Напиши систему кэширования на PHP 8.5:\n\n1. Интерфейс CacheInterface с методами:\n   - get(string $key, mixed $default = null): mixed\n   - set(string $key, mixed $value, int $ttl = 3600): bool\n   - delete(string $key): bool\n   - has(string $key): bool\n\n2. Реализация FileCache:\n   - Хранение в директории \u002Ftmp\u002Fcache\n   - Сериализация через serialize\u002Funserialize\n   - Автоматическая очистка истекших ключей при get()\n   - Обработка ошибок через CacheException\n\n3. Требования:\n   - declare(strict_types=1)\n   - PHPDoc для всех методов\n   - PSR-12\n   - Без внешних зависимостей\n",[1745,8051,8049],{"__ignoreMap":1743},[14,8053,8054],{},"Результат: Production-ready код с интерфейсом, реализацией, обработкой ошибок, документацией.",[14,8056,8057],{},[36,8058,8059],{},"Уровень 4 — Идеально (с CoT и примерами):",[1737,8061,8064],{"className":8062,"code":8063,"language":1742,"meta":1743},[1740],"Ты senior PHP-разработчик, специализирующийся на инфраструктурном коде.\n\nЗадача: Создать систему кэширования на PHP 8.5.\n\nШаг 1: Опиши, какие проблемы решает кэш (контекст)\nШаг 2: Спроектируй интерфейс CacheInterface\nШаг 3: Реализуй FileCache с учетом:\n  - Race conditions (два процесса пишут одновременно)\n  - Сериализации сложных объектов\n  - Атомарности операций\n  - Очистки истекших ключей\n\nТребования:\n- declare(strict_types=1)\n- PHPDoc для всех методов\n- PSR-12\n- Обработка ошибок через кастомные исключения\n\nПример использования:\n```php\n$cache = new FileCache('\u002Ftmp\u002Fcache');\n$cache->set('user:123', ['name' => 'Иван'], 3600);\n$user = $cache->get('user:123'); \u002F\u002F ['name' => 'Иван']\n``\n\nВерни результат в виде двух блоков кода: интерфейс и реализация.\n",[1745,8065,8063],{"__ignoreMap":1743},[14,8067,8068],{},"Результат: Архитектурно грамотный код с учетом edge cases, готовый к продакшену.",[123,8070,8072],{"id":8071},"для-менеджеров-как-формулировать-требования-для-llm-задач","Для менеджеров: как формулировать требования для LLM-задач",[14,8074,8075],{},"Если вы ставите задачу разработчику, который будет использовать LLM, включите в ТЗ:",[1328,8077,8078,8084,8090,8096,8102],{},[1331,8079,8080,8083],{},[36,8081,8082],{},"Входные данные:"," Что именно будет подаваться на вход модели? (текст, JSON, код, логи)",[1331,8085,8086,8089],{},[36,8087,8088],{},"Ожидаемый выход:"," В каком формате должен быть результат? (JSON с конкретной схемой, Markdown, PHP-код)",[1331,8091,8092,8095],{},[36,8093,8094],{},"Критерии качества:"," Что значит \"хороший результат\"? (валидный JSON, код без багов, ответ до 100 слов)",[1331,8097,8098,8101],{},[36,8099,8100],{},"Edge cases:"," Что делать, если задача невыполнима? (вернуть ошибку, сказать \"не знаю\", использовать fallback)",[1331,8103,8104,8107],{},[36,8105,8106],{},"Примеры:"," Дайте 2-3 примера \"вход → выход\".",[14,8109,8110],{},"Это сэкономит десятки итераций промптинга и ускорит разработку в разы.",[21,8112],{},[24,8114,8116],{"id":8115},"_7-эволюция-почему-простых-промптов-иногда-недостаточно-агенты-и-инструменты","7. Эволюция: Почему простых промптов иногда недостаточно (Агенты и Инструменты)",[14,8118,8119],{},"Но даже самые детальные промпты имеют ограничение. Модель видит только то, что вы написали в запросе.\nОна не видит ваш код, вашу базу данных, ваши файлы.",[14,8121,8122,8123,1052],{},"И здесь на сцену выходят ",[36,8124,8125],{},"агенты",[14,8127,8128],{},"В чем разница между простой LLM и агентом? Простая LLM — это мозг в банке.\nОна знает только свои веса и то, что вы написали в промпте.\nОна не видит ваш код, если вы его не скопировали (а скопировать весь проект невозможно — не влезет в контекст).",[14,8130,8131],{},"Агент — это LLM плюс инструменты. Это мозг с руками.\nАгент может принять решение вызвать функцию: прочитать файл, сделать запрос к базе данных, выполнить bash-команду.\nОн получает реальный результат и на его основе дает точный ответ.",[14,8133,8134,8135,8138,8139,8149],{},"Как это работает?\nМодель работает по циклу: видит задачу, понимает, что ей не хватает данных, и сама запрашивает инструмент.\nНапример: «",[17,8136,8137],{},"Мне нужно прочитать src\u002FConfig.php, чтобы дать совет","».\nОна возвращает структурированный запрос: «",[17,8140,8141,8142,8145,8146],{},"Вызови функцию ",[1745,8143,8144],{},"read_file"," с аргументом ",[1745,8147,8148],{},"src\u002FConfig.php","».\nВаш PHP-код перехватывает этот запрос, выполняет реальное чтение файла, возвращает результат обратно в модель.\nИ модель генерирует ответ на основе реального кода.",[14,8151,8152,8155],{},[36,8153,8154],{},"Эффект для разработчиков:"," Качество результата вырастает на порядок.\nВместо абстрактных советов по PHP вы получаете анализ вашего конкретного кода, потому что агент реально прочитал локальный файл через предоставленный ему инструмент.",[21,8157],{},[24,8159,8161],{"id":8160},"_8-заключение","8. Заключение",[14,8163,8164],{},"Подведем итоги.",[14,8166,8167],{},"LLM — это не магия, а управляемый вероятностный движок. Успех работы с ним зависит от трех факторов:",[1328,8169,8170,8176,8182],{},[1331,8171,8172,8175],{},[36,8173,8174],{},"Выбор модели:"," правильный размер и квантование под вашу задачу и ресурсы.",[1331,8177,8178,8181],{},[36,8179,8180],{},"Среда запуска:"," облако для скорости и мощности, локально для приватности и контроля.",[1331,8183,8184,8187],{},[36,8185,8186],{},"Структурированный промпт:"," использование XML-тегов, JSON Mode, детализация требований.",[14,8189,8190],{},"Чем лучше вы понимаете, как работает модель, тем предсказуемее результат.\nИ чем детальнее вы описываете задачу, тем точнее модель её решает.",[4595,8192,8193],{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sA_wV, html code.shiki .sA_wV{--shiki-default:#032F62;--shiki-dark:#DBEDFF}html pre.shiki code .snhLl, html code.shiki .snhLl{--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#85E89D;--shiki-dark-font-weight:bold}",{"title":1743,"searchDepth":3499,"depth":3499,"links":8195},[8196,8197,8204,8219,8220,8228,8248,8249],{"id":4654,"depth":3502,"text":4655},{"id":4678,"depth":3502,"text":4679,"children":8198},[8199,8200,8201,8202,8203],{"id":4702,"depth":3499,"text":4703},{"id":4737,"depth":3499,"text":4738},{"id":4784,"depth":3499,"text":4785},{"id":4857,"depth":3499,"text":4858},{"id":4905,"depth":3499,"text":4906},{"id":4940,"depth":3502,"text":4941,"children":8205},[8206,8207,8208,8209,8210,8211,8212,8218],{"id":4982,"depth":3499,"text":4983},{"id":5071,"depth":3499,"text":5072},{"id":5110,"depth":3499,"text":5111},{"id":5146,"depth":3499,"text":5147},{"id":5211,"depth":3499,"text":5212},{"id":5236,"depth":3499,"text":5237},{"id":5268,"depth":3499,"text":5269,"children":8213},[8214,8215,8216,8217],{"id":5276,"depth":3949,"text":5277},{"id":5315,"depth":3949,"text":5316},{"id":5353,"depth":3949,"text":5354},{"id":5377,"depth":3949,"text":5378},{"id":5410,"depth":3499,"text":5411},{"id":5565,"depth":3502,"text":5566},{"id":5595,"depth":3502,"text":5596,"children":8221},[8222],{"id":5605,"depth":3499,"text":5606,"children":8223},[8224,8225,8226,8227],{"id":5609,"depth":3949,"text":5610},{"id":5622,"depth":3949,"text":5623},{"id":5856,"depth":3949,"text":5857},{"id":7355,"depth":3949,"text":7356},{"id":7390,"depth":3502,"text":7391,"children":8229},[8230,8237,8245,8246,8247],{"id":7448,"depth":3499,"text":7449,"children":8231},[8232,8233,8234,8235,8236],{"id":7452,"depth":3949,"text":7453},{"id":7490,"depth":3949,"text":7491},{"id":7653,"depth":3949,"text":7654},{"id":7698,"depth":3949,"text":7699},{"id":7721,"depth":3949,"text":7722},{"id":7742,"depth":3499,"text":7743,"children":8238},[8239,8240,8241,8242,8243,8244],{"id":7746,"depth":3949,"text":7747},{"id":7778,"depth":3949,"text":7779},{"id":7807,"depth":3949,"text":7808},{"id":7836,"depth":3949,"text":7837},{"id":7865,"depth":3949,"text":7866},{"id":7894,"depth":3949,"text":7895},{"id":7926,"depth":3499,"text":7927},{"id":8001,"depth":3499,"text":8002},{"id":8071,"depth":3499,"text":8072},{"id":8115,"depth":3502,"text":8116},{"id":8160,"depth":3502,"text":8161},"AI","\u002Fcovers\u002Fllm-itself.webp","2026-07-23","Практическое руководство по большим языковым моделям: токены, температура, выбор модели, локальный и облачный запуск, форматы промптов и работа с агентами.",{},"\u002Fblog\u002Fllm-itself",{"title":4649,"description":8253},"blog\u002Fllm-itself",[3534,3535,8259,3900],"prompt","-dXCphS-6uU-LrCEXEV0ls9pH2CjEIfrAjquDXCoxoE",{"id":8262,"title":8263,"body":8264,"category":4635,"cover":9286,"date":9287,"description":9288,"draft":3525,"extension":3526,"meta":9289,"navigation":3528,"path":9290,"seo":9291,"stem":9292,"tags":9293,"updated":3536,"__hash__":9294},"blog\u002Fblog\u002Fclean-architecture.md","Универсальное руководство по Clean Architecture",{"type":8,"value":8265,"toc":9262},[8266,8270,8276,8282,8284,8288,8314,8316,8320,8323,8329,8331,8335,8342,8347,8388,8393,8451,8453,8457,8464,8468,8533,8537,8589,8591,8595,8602,8606,8673,8677,8720,8722,8726,8729,8733,8771,8775,8811,8813,8817,8821,8827,8831,8877,8879,8883,8887,8890,8917,8921,8924,8927,8952,8957,9080,9085,9132,9161,9165,9168,9170,9174,9178,9203,9207,9227,9229,9233,9236],[24,8267,8269],{"id":8268},"введение","Введение",[14,8271,8272,8275],{},[36,8273,8274],{},"Clean Architecture"," (Чистая Архитектура) — это архитектурный подход, предложенный Робертом Мартином (Uncle Bob), который объединяет идеи Hexagonal Architecture (Порты и Адаптеры), Onion Architecture и Screaming Architecture.",[14,8277,8278,8281],{},[36,8279,8280],{},"Главная цель:"," создание системы, которая независима от фреймворков, баз данных, UI и внешних сервисов. Бизнес-логика изолирована и является ядром системы.",[21,8283],{},[24,8285,8287],{"id":8286},"фундаментальные-принципы","📐 Фундаментальные принципы",[1328,8289,8290,8296,8302,8308],{},[1331,8291,8292,8295],{},[36,8293,8294],{},"Правило зависимостей (The Dependency Rule):"," Исходный код зависимостей может указывать только внутрь (к центру). Внутренние слои ничего не знают о внешних.",[1331,8297,8298,8301],{},[36,8299,8300],{},"Независимость от фреймворков:"," Фреймворки — это просто инструменты. Они не должны диктовать архитектуру.",[1331,8303,8304,8307],{},[36,8305,8306],{},"Тестируемость:"," Бизнес-логика может быть протестирована в изоляции, без базы данных, UI или внешних API.",[1331,8309,8310,8313],{},[36,8311,8312],{},"Независимость от UI и БД:"," Интерфейс пользователя и способ хранения данных — это внешние детали, которые можно заменить без изменения ядра.",[21,8315],{},[24,8317,8319],{"id":8318},"слои-архитектуры-и-структура-директорий","🧅 Слои Архитектуры и Структура Директорий",[14,8321,8322],{},"Архитектура состоит из четырех основных слоев. Рассмотрим их от центра к периферии.",[1737,8324,8327],{"className":8325,"code":8326,"language":1742,"meta":1743},[1740],"src\u002F\n │\n ├── Domain\u002F                              # 🧠 ЯДРО (Чистый PHP, ЗАПРЕЩЕНЫ зависимости от фреймворков)\n │   ├── DTO\u002F                             # Доменные DTO (передача данных между слоями)\n │   │   └── UserDTO.php                  # Пример: UserDTO (readonly)\n │   │\n │   ├── Entity\u002F                          # Бизнес-сущности с поведением (Rich Domain Model)\n │   │   ├── User.php                     # Пример: User с методами changeStatus(), block()\n │   │   └── Order.php                    # Не содержат аннотаций ORM!\n │   │\n │   ├── ValueObject\u002F                     # Неизменяемые объекты-значения (Readonly-классы)\n │   │   ├── Email.php                    # Пример: Email, Money, Address\n │   │   └── OrderStatus.php              # Описывают данные, сравниваются по значению\n │   │\n │   ├── Repository\u002F                      # ТОЛЬКО интерфейсы (Contracts) для доступа к данным\n │   │   ├── UserRepositoryInterface.php  # Пример: UserRepositoryInterface\n │   │   └── OrderRepositoryInterface.php # Напр.: save(), findById(), findAll()\n │   │\n │   ├── Service\u002F                         # Интерфейсы для внешних сервисов (если нужно в Domain)\n │   │   └── EmailSenderInterface.php     # Пример: EmailSenderInterface, PaymentGatewayInterface\n │   │\n │   ├── Event\u002F                           # Доменные события (Domain Events)\n │   │   └── UserCreatedEvent.php         # Пример: UserCreatedEvent, OrderPlacedEvent\n │   │\n │   └── Exception\u002F                       # Исключения бизнес-правил\n │       └── UserAlreadyExistsException.php # Пример: OutdatedDataException, InvalidOrderException\n │\n ├── Application\u002F                         # ⚙️ СЦЕНАРИИ ИСПОЛЬЗОВАНИЯ (Оркестрация, зависит от Domain)\n │   ├── Port\u002F                            # Общие интерфейсы Application-слоя (DeeplinkGeneratorInterface)\n │   ├── Common\u002F                          # Общие утилиты (Pagination, DateTime)\n │   │\n │   ├── Voting\u002F                          # Модуль по доменной области (bounded context)\n │   │   ├── Command\u002F                     # DTO команд (readonly)\n │   │   ├── CommandHandler\u002F              # Синхронные обработчики команд (__invoke)\n │   │   ├── Message\u002F                     # Асинхронные сообщения для Messenger\n │   │   ├── MessageHandler\u002F              # Consumer'ы очередей (#[AsMessageHandler])\n │   │   └── DTO\u002F                         # Выходные DTO модуля\n │   │\n │   ├── Season\u002F                          # Аналогичная структура для других модулей\n │   │   ├── Command\u002F\n │   │   ├── CommandHandler\u002F\n │   │   ├── Query\u002F\n │   │   ├── QueryHandler\u002F\n │   │   └── DTO\u002F\n │   │\n │   └── Bot\u002F\n │       ├── Command\u002F                     # (если есть CQRS-команды)\n │       ├── CommandHandler\u002F\n │       ├── Message\u002F\n │       ├── MessageHandler\u002F\n │       └── DTO\u002F\n │\n │   # ⚠️ Не используйте папки UseCase\u002F, Service\u002F для CQRS-обработчиков.\n │   # CommandHandler\u002F + QueryHandler\u002F — стандарт проекта.\n │\n ├── Infrastructure\u002F                      # 🔌 ДЕТАЛИ РЕАЛИЗАЦИИ (Здесь живет фреймворк, БД, API)\n │   ├── Persistence\u002F                     # Работа с базой данных\n │   │   ├── Model\u002F                       # ORM-сущности (Doctrine Models, Eloquent Models)\n │   │   │   ├── UserModel.php            # Пример: UserModel (содержит #[ORM\\Entity], #[ORM\\Column])\n │   │   │   └── OrderModel.php           # Не содержат бизнес-логики!\n │   │   │\n │   │   ├── Mapper\u002F                      # Мапперы между Domain Entity и Infrastructure Model\n │   │   │   ├── UserMapper.php           # Пример: UserMapper (toDomain(), toModel())\n │   │   │   └── OrderMapper.php          # Конвертирует Domain Entity ↔ ORM Model\n │   │   │\n │   │   └── Repository\u002F                  # Реализации интерфейсов из Domain\\Repository\n │   │       ├── DoctrineUserRepository.php  # Пример: DoctrineUserRepository (реализует UserRepositoryInterface)\n │   │       └── EloquentOrderRepository.php # Использует EntityManager, QueryBuilder\n │   │\n │   ├── Integration\u002F                     # Интеграция с внешними API и сервисами\n │   │   ├── Api\u002F                         # HTTP-клиенты для внешних API\n │   │   │   ├── SapClient.php            # Пример: SapClient, StripeClient, SlackClient\n │   │   │   └── StripeClient.php         # Использует Guzzle, Symfony HttpClient\n │   │   │\n │   │   └── Gateway\u002F                     # Реализации интерфейсов из Domain\\Service\n │   │       ├── SmtpEmailSender.php      # Пример: SmtpEmailSender (реализует EmailSenderInterface)\n │   │       └── StripePaymentGateway.php # Использует внешние SDK\n │   │\n │   ├── Messaging\u002F                       # Интеграция с очередями сообщений\n │   │   ├── Kafka\u002F                       # Apache Kafka \u002F Redpanda\n │   │   │   ├── Dto\u002F                     # DTO для парсинга JSON из Kafka\n │   │   │   │   └── EmployeeBatchDto.php # Пример: EmployeeBatchDto, OrderEventDto\n │   │   │   ├── Message\u002F                 # Обёртки для сырых сообщений\n │   │   │   │   └── KafkaRawMessage.php  # Пример: KafkaRawMessage\n │   │   │   ├── Serializer\u002F              # Кастомные сериализаторы\n │   │   │   │   └── KafkaRawMessageSerializer.php # Для Symfony Messenger\n │   │   │   └── Handler\u002F                 # Обработчики сообщений из Kafka\n │   │   │       └── EmployeeMessageHandler.php  # Парсят JSON, создают команды, диспатчат в MessageBus\n │   │   │\n │   │   └── RabbitMQ\u002F                    # RabbitMQ (если используется)\n │   │       └── Handler\u002F\n │   │           └── OrderEventHandler.php\n │   │\n │   ├── AutoMapper\u002F                      # Конфигурация автоматического маппинга объектов\n │   │   └── AutoMapperConfig.php         # Пример: AutoMapperConfig (для AutoMapperBundle)\n │   │\n │   ├── Serializer\u002F                      # Настройки сериализации\u002Fдесериализации\n │   │   └── SerializerConfig.php         # Пример: SerializerConfig (для Symfony Serializer)\n │   │\n │   ├── Validation\u002F                      # Валидаторы и правила валидации\n │   │   ├── Validator.php                # Пример: Validator (обёртка над Symfony Validator)\n │   │   └── Rules\u002F                       # Кастомные правила валидации\n │   │       └── UniqueEmailRule.php\n │   │\n │   ├── DI\u002F                              # Конфигурация контейнера внедрения зависимостей\n │   │   └── services.php                 # Пример: services.php (для Symfony DI, Slim)\n │   │\n │   ├── Console\u002F                         # Системные консольные команды (зависят от фреймворка)\n │   │   └── Command\u002F                     # Кастомные команды (если нужны)\n │   │       └── SyncDataCommand.php      # Пример: SyncDataCommand, ClearCacheCommand\n │   │\n │   └── EventListener\u002F                   # Обработчики событий фреймворка\n │       └── KernelRequestListener.php    # Пример: KernelRequestListener, ExceptionListener\n │\n └── Presentation\u002F                        # 🖥️ ТОЧКИ ВХОДА (HTTP, CLI. Зависит от Application)\n     ├── Http\u002F                            # Взаимодействие по HTTP\n     │   ├── Controller\u002F                  # HTTP контроллеры (REST, GraphQL)\n     │   │   ├── UserController.php       # Пример: UserController, OrderController\n     │   │   └── OrderController.php      # Принимают запросы, вызывают CommandHandlers\n     │   │\n     │   ├── Request\u002F                     # HTTP Request DTO (если нужны)\n     │   │   └── CreateUserRequest.php    # Пример: CreateUserRequest, UpdateOrderRequest\n     │   │\n     │   ├── Response\u002F                    # HTTP Response DTO\n     │   │   └── UserResponse.php         # Пример: UserResponse, OrderResponse\n     │   │\n     │   └── Middleware\u002F                  # Middleware (авторизация, логирование, CORS)\n     │       └── AuthMiddleware.php       # Пример: AuthMiddleware, CorsMiddleware\n     │\n     └── Console\u002F                         # Пользовательские CLI-команды (бизнес-ориентированные)\n         └── Command\u002F                     # Пример: ProcessOrdersCommand, GenerateReportCommand\n             └── ProcessOrdersCommand.php # Вызывают Application CommandHandlers\n",[1745,8328,8326],{"__ignoreMap":1743},[21,8330],{},[123,8332,8334],{"id":8333},"_1-domain-layer-ядро-сущности","🧠 1. Domain Layer (Ядро \u002F Сущности)",[14,8336,8337,8338,8341],{},"Самый внутренний слой. Содержит ",[36,8339,8340],{},"корпоративные бизнес-правила"," (Enterprise Business Rules). Это сердце приложения.",[14,8343,8344],{},[36,8345,8346],{},"Состав:",[2016,8348,8349,8355,8361,8367,8376,8382],{},[1331,8350,8351,8354],{},[1745,8352,8353],{},"Entity\u002F"," — Бизнес-сущности с поведением (Rich Domain Model). Содержат состояние и методы его изменения.",[1331,8356,8357,8360],{},[1745,8358,8359],{},"ValueObject\u002F"," — Объекты-значения (Value Objects). Не имеют идентификатора, неизменяемы (immutable), сравниваются по значению.",[1331,8362,8363,8366],{},[1745,8364,8365],{},"Repository\u002F"," — ТОЛЬКО интерфейсы (контракты) для доступа к данным.",[1331,8368,8369,90,8372,8375],{},[1745,8370,8371],{},"Service\u002F",[1745,8373,8374],{},"Gateway\u002F"," — Интерфейсы для взаимодействия с внешними системами (если их нельзя отнести к Application).",[1331,8377,8378,8381],{},[1745,8379,8380],{},"Event\u002F"," — Доменные события (Domain Events).",[1331,8383,8384,8387],{},[1745,8385,8386],{},"Exception\u002F"," — Исключения, отражающие нарушение бизнес-правил.",[14,8389,8390],{},[36,8391,8392],{},"📋 Правила:",[131,8394,8395,8406],{},[134,8396,8397],{},[137,8398,8399,8403],{},[140,8400,8402],{"align":8401},"left","✅ РАЗРЕШЕНО",[140,8404,8405],{"align":8401},"❌ ЗАПРЕЩЕНО",[147,8407,8408,8416,8424,8435,8443],{},[137,8409,8410,8413],{},[152,8411,8412],{"align":8401},"Чистый PHP (без зависимостей от фреймворков)",[152,8414,8415],{"align":8401},"Использовать аннотации ORM (Doctrine, Eloquent)",[137,8417,8418,8421],{},[152,8419,8420],{"align":8401},"Создание интерфейсов (контрактов)",[152,8422,8423],{"align":8401},"Зависеть от HTTP, CLI, Базы Данных",[137,8425,8426,8432],{},[152,8427,8428,8429,734],{"align":8401},"Использование независимых библиотек (напр., ",[1745,8430,8431],{},"ramsey\u002Fuuid",[152,8433,8434],{"align":8401},"Знать о существовании фреймворка (Symfony, Laravel)",[137,8436,8437,8440],{},[152,8438,8439],{"align":8401},"Реализация бизнес-логики и инвариантов",[152,8441,8442],{"align":8401},"Выполнять SQL-запросы или HTTP-вызовы",[137,8444,8445,8448],{},[152,8446,8447],{"align":8401},"Фабричные методы для создания сущностей",[152,8449,8450],{"align":8401},"Бизнес-логика в конструкторах",[21,8452],{},[123,8454,8456],{"id":8455},"️-2-application-layer-сценарии-использования","⚙️ 2. Application Layer (Сценарии использования)",[14,8458,8459,8460,8463],{},"Содержит ",[36,8461,8462],{},"бизнес-логику уровня приложения"," (Application Business Rules). Отвечает за как использовать Domain для выполнения конкретных сценариев (Use Cases).",[14,8465,8466],{},[36,8467,8346],{},[2016,8469,8470,8486,8494,8501,8510,8523,8528],{},[1331,8471,8472,8473,3821,8476,3821,8479,3821,8482,8485],{},"Модули по доменным областям (",[1745,8474,8475],{},"Voting\u002F",[1745,8477,8478],{},"Season\u002F",[1745,8480,8481],{},"Statistics\u002F",[1745,8483,8484],{},"Bot\u002F",") — каждый содержит свои Command, Query, Handler, DTO",[1331,8487,8488,8490,8491,8493],{},[1745,8489,3868],{}," + ",[1745,8492,3872],{}," — синхронные use case, изменяющие состояние",[1331,8495,8496,8490,8498,8500],{},[1745,8497,3878],{},[1745,8499,3881],{}," — операции чтения",[1331,8502,8503,8490,8506,8509],{},[1745,8504,8505],{},"Message\u002F",[1745,8507,8508],{},"MessageHandler\u002F"," — асинхронная обработка через Symfony Messenger (не путать с CQRS Handler!)",[1331,8511,8512,8515,8516,8519,8520,734],{},[1745,8513,8514],{},"Port\u002F"," — общие интерфейсы Application-слоя (имена ",[1745,8517,8518],{},"*Interface",", не ",[1745,8521,8522],{},"*Port",[1331,8524,8525,8527],{},[1745,8526,4533],{}," — выходные объекты модулей",[1331,8529,8530,8532],{},[1745,8531,8386],{}," — исключения уровня приложения (напр., EmployeeNotFoundException)",[14,8534,8535],{},[36,8536,8392],{},[131,8538,8539,8547],{},[134,8540,8541],{},[137,8542,8543,8545],{},[140,8544,8402],{"align":8401},[140,8546,8405],{"align":8401},[147,8548,8549,8557,8565,8573,8581],{},[137,8550,8551,8554],{},[152,8552,8553],{"align":8401},"Координировать работу Domain и Infrastructure",[152,8555,8556],{"align":8401},"Прямая работа с HTTP-запросами\u002Fответами",[137,8558,8559,8562],{},[152,8560,8561],{"align":8401},"Вызывать репозитории и сервисы через интерфейсы",[152,8563,8564],{"align":8401},"Прямые запросы к БД (SQL, DQL)",[137,8566,8567,8570],{},[152,8568,8569],{"align":8401},"Обрабатывать исключения и логировать контекст",[152,8571,8572],{"align":8401},"Содержать бизнес-логику вне UseCase\u002FHandler",[137,8574,8575,8578],{},[152,8576,8577],{"align":8401},"Использовать паттерны (Saga, CQRS, Mediator)",[152,8579,8580],{"align":8401},"Знать о деталях реализации (Doctrine, Kafka)",[137,8582,8583,8586],{},[152,8584,8585],{"align":8401},"Диспатчить команды в Message Bus",[152,8587,8588],{"align":8401},"Работать напрямую с очередями\u002Fброкерами",[21,8590],{},[123,8592,8594],{"id":8593},"_3-infrastructure-layer-детали-реализации","🔌 3. Infrastructure Layer (Детали реализации)",[14,8596,8597,8598,8601],{},"Самый внешний слой. Содержит ",[36,8599,8600],{},"всё, что касается технических деталей:"," базы данных, внешние API, очереди, фреймворки. Реализует интерфейсы, заданные в Domain и Application.",[14,8603,8604],{},[36,8605,8346],{},[2016,8607,8608,8614,8620,8626,8631,8640,8649,8655,8661,8667],{},[1331,8609,8610,8613],{},[1745,8611,8612],{},"Persistence\u002F"," — Работа с БД.",[1331,8615,8616,8619],{},[1745,8617,8618],{},"Model\u002F"," — ORM-сущности (Doctrine Models, Eloquent Models).",[1331,8621,8622,8625],{},[1745,8623,8624],{},"Mapper\u002F"," — Мапперы между Domain Entity и ORM Model.",[1331,8627,8628,8630],{},[1745,8629,8365],{}," — Реализации интерфейсов из Domain\\Repository.",[1331,8632,8633,90,8636,8639],{},[1745,8634,8635],{},"Integration\u002F",[1745,8637,8638],{},"Api\u002F"," — HTTP-клиенты для внешних API.",[1331,8641,8642,90,8645,8648],{},[1745,8643,8644],{},"Messaging\u002F",[1745,8646,8647],{},"Kafka\u002F"," — Интеграция с очередями (Kafka, RabbitMQ).",[1331,8650,8651,8654],{},[1745,8652,8653],{},"DI\u002F"," — Конфигурация контейнера внедрения зависимостей.",[1331,8656,8657,8660],{},[1745,8658,8659],{},"Serializer\u002F"," — Настройки сериализации\u002Fдесериализации.",[1331,8662,8663,8666],{},[1745,8664,8665],{},"Validation\u002F"," — Валидаторы и правила валидации.",[1331,8668,8669,8672],{},[1745,8670,8671],{},"Console\u002F"," — Системные консольные команды, зависящие от фреймворка.",[14,8674,8675],{},[36,8676,8392],{},[131,8678,8679,8687],{},[134,8680,8681],{},[137,8682,8683,8685],{},[140,8684,8402],{"align":8401},[140,8686,8405],{"align":8401},[147,8688,8689,8697,8705,8713],{},[137,8690,8691,8694],{},[152,8692,8693],{"align":8401},"Использовать Doctrine, Eloquent, PDO, Redis",[152,8695,8696],{"align":8401},"Содержать бизнес-логику (только техническая)",[137,8698,8699,8702],{},[152,8700,8701],{"align":8401},"Реализовывать интерфейсы из Domain\u002FApplication",[152,8703,8704],{"align":8401},"Вызываться напрямую из Presentation слоя",[137,8706,8707,8710],{},[152,8708,8709],{"align":8401},"Работать с HTTP-клиентами, Kafka, SMTP",[152,8711,8712],{"align":8401},"Зависеть от Application или Presentation слоев",[137,8714,8715,8718],{},[152,8716,8717],{"align":8401},"Конфигурировать фреймворк и DI-контейнер",[152,8719],{"align":8401},[21,8721],{},[123,8723,8725],{"id":8724},"️-4-presentation-layer-точки-входа","🖥️ 4. Presentation Layer (Точки входа)",[14,8727,8728],{},"Слой драйверов. Отвечает за доставку запросов от пользователя\u002Fвнешней системы в Application и возврат ответа. Должен быть максимально \"тонким\".",[14,8730,8731],{},[36,8732,8346],{},[2016,8734,8735,8741,8747,8753,8759,8765],{},[1331,8736,8737,8740],{},[1745,8738,8739],{},"Http\u002FController\u002F"," — HTTP контроллеры (REST, GraphQL).",[1331,8742,8743,8746],{},[1745,8744,8745],{},"Http\u002FFactory\u002F"," — маппинг Request DTO → Command\u002FQuery (для сложных случаев).",[1331,8748,8749,8752],{},[1745,8750,8751],{},"Http\u002FDTO\u002FRequest\u002F"," — HTTP Request DTO с Symfony Validator constraints.",[1331,8754,8755,8758],{},[1745,8756,8757],{},"Console\u002FCommand\u002F"," — CLI-команды (бизнес-ориентированные).",[1331,8760,8761,8764],{},[1745,8762,8763],{},"Listener\u002F"," — Обработчики событий фреймворка.",[1331,8766,8767,8770],{},[1745,8768,8769],{},"Middleware\u002F"," — Проверки авторизации, валидация запросов.",[14,8772,8773],{},[36,8774,8392],{},[131,8776,8777,8785],{},[134,8778,8779],{},[137,8780,8781,8783],{},[140,8782,8402],{"align":8401},[140,8784,8405],{"align":8401},[147,8786,8787,8795,8803],{},[137,8788,8789,8792],{},[152,8790,8791],{"align":8401},"Парсить HTTP-запросы, валидировать входные данные",[152,8793,8794],{"align":8401},"Содержать бизнес-логику или оркестрацию",[137,8796,8797,8800],{},[152,8798,8799],{"align":8401},"Создавать DTO\u002FCommand и передавать в Application",[152,8801,8802],{"align":8401},"Напрямую обращаться к Repository или БД",[137,8804,8805,8808],{},[152,8806,8807],{"align":8401},"Форматировать HTTP-ответы (JSON, XML, HTML)",[152,8809,8810],{"align":8401},"Знать о деталях Infrastructure",[21,8812],{},[123,8814,8816],{"id":8815},"поток-зависимостей-и-данных","🔄 Поток зависимостей и данных",[5274,8818,8820],{"id":8819},"граф-зависимостей-кто-от-кого-зависит","Граф зависимостей (Кто от кого зависит)",[1737,8822,8825],{"className":8823,"code":8824,"language":1742,"meta":1743},[1740]," ┌─────────────────────────────────────────────────┐\n │            Presentation Layer                   │\n │   (Controllers, CLI Commands, API Endpoints)    │\n └──────────────────────┬──────────────────────────┘\n                        │ вызывает\n                        ▼\n ┌─────────────────────────────────────────────────┐\n │            Application Layer                    │\n │   (UseCases, CommandHandlers, DTOs)             │\n └──────────────────────┬──────────────────────────┘\n                        │ использует интерфейсы\n                        ▼\n ┌─────────────────────────────────────────────────┐\n │              Domain Layer                       │\n │   (Entities, ValueObjects, Repository Contracts)│\n └───────────────────────▲─────────────────────────┘\n                         │ реализует\n ┌───────────────────────┴─────────────────────────┐\n │           Infrastructure Layer                  │\n │   (ORM Models, Mappers, Repo Implementations,   │\n │    HTTP Clients, Message Brokers, DI Config)    │\n └─────────────────────────────────────────────────┘\n",[1745,8826,8824],{"__ignoreMap":1743},[5274,8828,8830],{"id":8829},"поток-данных-на-примере-сохранения-сущности","Поток данных (На примере сохранения сущности)",[1328,8832,8833,8846,8855,8861],{},[1331,8834,8835,8838,8839,8842,8843,1052],{},[36,8836,8837],{},"Presentation:"," Принимает JSON, валидирует, создает ",[1745,8840,8841],{},"CreateUserCommand",", вызывает ",[1745,8844,8845],{},"CreateUserHandler",[1331,8847,8848,8851,8852,1052],{},[36,8849,8850],{},"Application:"," CreateUserHandler получает команду. Вызывает ",[1745,8853,8854],{},"UserRepositoryInterface->save($user)",[1331,8856,8857,8860],{},[36,8858,8859],{},"Domain:"," Ничего не знает о том, как данные уйдут в БД. Просто отдает сущность.",[1331,8862,8863,1941,8866,8869,8870,8873,8874,1052],{},[36,8864,8865],{},"Infrastructure:",[1745,8867,8868],{},"UserRepository"," (реализация интерфейса) принимает Domain-сущность, через UserMapper конвертирует её в ",[1745,8871,8872],{},"UserModel"," (ORM), сохраняет через ",[1745,8875,8876],{},"EntityManager",[21,8878],{},[24,8880,8882],{"id":8881},"ключевые-паттерны-и-концепции","💡 Ключевые паттерны и концепции",[123,8884,8886],{"id":8885},"_1-разделение-entity-и-model-orm","1. Разделение Entity и Model (ORM)",[14,8888,8889],{},"Это частая ошибка — использовать ORM-модели как бизнес-сущности.",[2016,8891,8892,8905,8911],{},[1331,8893,8894,8897,8898,8901,8902,1052],{},[36,8895,8896],{},"Domain Entity:"," Богатая модель, содержит бизнес-инварианты (например, ",[1745,8899,8900],{},"User->block()"," проверяет правила блокировки). Не имеет аннотаций ",[1745,8903,8904],{},"#[ORM\\Column]",[1331,8906,8907,8910],{},[36,8908,8909],{},"Infrastructure Model:"," \"Тупая\" модель (Anemic), нужна только для маппинга на таблицу в БД. Содержит только геттеры\u002Fсеттеры и ORM-аннотации.",[1331,8912,8913,8916],{},[36,8914,8915],{},"Mapper:"," Класс, который переводит Domain Entity ↔ Infrastructure Model.",[123,8918,8920],{"id":8919},"_2-порты-и-адаптеры-в-php-ports-and-adapters","2. Порты и Адаптеры в PHP (Ports and Adapters)",[14,8922,8923],{},"Архитектурный паттерн Ports and Adapters (Hexagonal Architecture) универсален, но PHP-сообщество исторически не использует слово Port в нейминге классов и директорий. Вместо этого применяются более описательные названия, отражающие суть контракта.",[14,8925,8926],{},"В PHP:",[2016,8928,8929,8943],{},[1331,8930,8931,8934,8935,8938,8939,8942],{},[36,8932,8933],{},"Порт (Port)"," — это ",[36,8936,8937],{},"Интерфейс"," (обычно с суффиксом ",[1745,8940,8941],{},"Interface","), описывающий контракт.",[1331,8944,8945,8934,8948,8951],{},[36,8946,8947],{},"Адаптер (Adapter)",[36,8949,8950],{},"конкретный класс",", реализующий интерфейс и использующий технологии (Doctrine, Guzzle, Redis).",[14,8953,8954],{},[36,8955,8956],{},"Таблица соответствий терминов",[131,8958,8959,8972],{},[134,8960,8961],{},[137,8962,8963,8966,8969],{},[140,8964,8965],{"align":8401},"Академический термин",[140,8967,8968],{"align":8401},"🐘 Идиоматичный PHP-нейминг",[140,8970,8971],{"align":8401},"Где размещается",[147,8973,8974,8991,9011,9028,9045,9063],{},[137,8975,8976,8981,8986],{},[152,8977,8978],{"align":8401},[1745,8979,8980],{},"UserRepositoryPort",[152,8982,8983],{"align":8401},[1745,8984,8985],{},"UserRepositoryInterface",[152,8987,8988],{"align":8401},[1745,8989,8990],{},"Domain\u002FRepository\u002F",[137,8992,8993,8998,9003],{},[152,8994,8995],{"align":8401},[1745,8996,8997],{},"PaymentGatewayPort",[152,8999,9000],{"align":8401},[1745,9001,9002],{},"PaymentGatewayInterface",[152,9004,9005,90,9008],{"align":8401},[1745,9006,9007],{},"Domain\u002FGateway\u002F",[1745,9009,9010],{},"Application\u002FService\u002F",[137,9012,9013,9018,9023],{},[152,9014,9015],{"align":8401},[1745,9016,9017],{},"EmailSenderPort",[152,9019,9020],{"align":8401},[1745,9021,9022],{},"EmailSenderInterface",[152,9024,9025],{"align":8401},[1745,9026,9027],{},"Domain\u002FService\u002F",[137,9029,9030,9035,9040],{},[152,9031,9032],{"align":8401},[1745,9033,9034],{},"ExternalApiClientPort",[152,9036,9037],{"align":8401},[1745,9038,9039],{},"SapClientInterface",[152,9041,9042],{"align":8401},[1745,9043,9044],{},"Infrastructure\u002FIntegration\u002F",[137,9046,9047,9053,9058],{},[152,9048,9049,9052],{"align":8401},[1745,9050,9051],{},"UserManagementPort"," (вход)",[152,9054,9055],{"align":8401},[1745,9056,9057],{},"CreateUserCommandHandler",[152,9059,9060],{"align":8401},[1745,9061,9062],{},"Application\u002FCommandHandler\u002F",[137,9064,9065,9070,9075],{},[152,9066,9067,9052],{"align":8401},[1745,9068,9069],{},"HttpApiPort",[152,9071,9072],{"align":8401},[1745,9073,9074],{},"UserController",[152,9076,9077],{"align":8401},[1745,9078,9079],{},"Presentation\u002FHttp\u002F",[14,9081,9082],{},[36,9083,9084],{},"Почему в PHP не используют слово \"Port\"?",[1328,9086,9087,9100,9118],{},[1331,9088,9089,9092,9093,9095,9096,9099],{},[36,9090,9091],{},"Слишком абстрактно."," PHP-разработчики предпочитают, чтобы имя класса сразу отвечало на вопрос \"что это делает?\". ",[1745,9094,9039],{}," говорит: \"это интерфейс для общения с SAP\". ",[1745,9097,9098],{},"SapPort"," заставляет думать.",[1331,9101,9102,9105,9106,3821,9108,3821,9111,3821,9114,9117],{},[36,9103,9104],{},"Влияние фреймворков."," Symfony и Laravel популяризировали термины ",[1745,9107,4328],{},[1745,9109,9110],{},"Gateway",[1745,9112,9113],{},"Client",[1745,9115,9116],{},"Handler",". Они прочно вошли в стандарт индустрии.",[1331,9119,9120,9123,9124,9127,9128,9131],{},[36,9121,9122],{},"Screaming Architecture."," Архитектура должна \"кричать\" о предметной области, а не о паттернах. Директория ",[1745,9125,9126],{},"Infrastructure\u002FPersistence\u002F"," кричит: \"тут работа с базой!\", а ",[1745,9129,9130],{},"Infrastructure\u002FAdapter\u002F"," — \"тут какой-то абстрактный адаптер\".",[14,9133,9134,9137,9138,1719,9140,9143,9144,3821,9146,3821,9148,3821,9151,3821,9154,3821,9157,3821,9159,1052],{},[36,9135,9136],{},"⚠️ Важно:"," Избегайте создания директорий ",[1745,9139,8514],{},[1745,9141,9142],{},"Adapter\u002F",". Используйте семантические имена: ",[1745,9145,8365],{},[1745,9147,8374],{},[1745,9149,9150],{},"Client\u002F",[1745,9152,9153],{},"Sender\u002F",[1745,9155,9156],{},"Publisher\u002F",[1745,9158,8635],{},[1745,9160,8612],{},[123,9162,9164],{"id":9163},"_3-иммутабельность-и-dto","3. Иммутабельность и DTO",[14,9166,9167],{},"Все объекты, передающие данные между слоями (Commands, DTOs), должны быть неизменяемыми (readonly). Это гарантирует, что данные не будут изменены по пути от Presentation к Application, и упрощает потоковую безопасность.",[21,9169],{},[24,9171,9173],{"id":9172},"️-плюсы-и-минусы-подхода","⚖️ Плюсы и Минусы подхода",[123,9175,9177],{"id":9176},"преимущества","✅ Преимущества",[2016,9179,9180,9185,9191,9197],{},[1331,9181,9182,9184],{},[36,9183,8306],{}," Ядро (Domain) покрывается юнит-тестами на 100% без моков БД и фреймворка.",[1331,9186,9187,9190],{},[36,9188,9189],{},"Поддерживаемость:"," Четкое разделение ответственности. Разработчик точно знает, где писать бизнес-логику, а где код для работы с БД.",[1331,9192,9193,9196],{},[36,9194,9195],{},"Гибкость:"," Легко заменить БД (MySQL → PostgreSQL), фреймворк (Symfony → Laravel) или способ доставки (REST → GraphQL), не трогая ядро.",[1331,9198,9199,9202],{},[36,9200,9201],{},"Независимость команд:"," Можно параллельно разрабатывать ядро и инфраструктуру.",[123,9204,9206],{"id":9205},"недостатки-и-компромиссы","❌ Недостатки и Компромиссы",[2016,9208,9209,9215,9221],{},[1331,9210,9211,9214],{},[36,9212,9213],{},"Boilerplate (много шаблонного кода):"," Создание Entity, Model, Mapper, Repository Interface, Repository Implementation для одной сущности требует времени.",[1331,9216,9217,9220],{},[36,9218,9219],{},"Порог входа:"," Команде нужно строго соблюдать правила. Новички часто пытаются \"срезать путь\" и нарушают границы слоев.",[1331,9222,9223,9226],{},[36,9224,9225],{},"Overkill для простых проектов:"," Для простого CRUD-приложения Clean Architecture будет избыточной (лучше использовать Active Record или простую Service-ориентированную архитектуру).",[21,9228],{},[24,9230,9232],{"id":9231},"️-чек-лист-для-code-review","🛡️ Чек-лист для Code Review",[14,9234,9235],{},"При ревью кода в проекте с Clean Architecture задавайте следующие вопросы:",[1328,9237,9238,9241,9244,9247,9250,9253,9256,9259],{},[1331,9239,9240],{},"Импортирует ли Domain слой что-либо из Symfony\u002FLaravel\u002FDoctrine? (Если да — ошибка)",[1331,9242,9243],{},"Есть ли бизнес-логика (условия if\u002Felse, расчеты) в Infrastructure или Presentation слоях? (Если да — перенести в Domain\u002FApplication)",[1331,9245,9246],{},"Обращается ли Presentation слой напрямую к Repository или БД? (Если да — перенести в Application UseCase)",[1331,9248,9249],{},"Содержит ли Domain Entity аннотации ORM или зависимости от внешних сервисов? (Если да — вынести в Infrastructure)",[1331,9251,9252],{},"Являются ли DTO и Command классы readonly?",[1331,9254,9255],{},"Используются ли семантические имена для интерфейсов (Repository, Client, Sender), а не абстрактные Port\u002FAdapter?",[1331,9257,9258],{},"Реализует ли Infrastructure слой интерфейсы из Domain\u002FApplication через DI-контейнер?",[1331,9260,9261],{},"Находится ли бизнес-логика внутри Entity\u002FValueObject\u002FCommandHandler, а не в конструкторах и контроллерах?",{"title":1743,"searchDepth":3499,"depth":3499,"links":9263},[9264,9265,9266,9276,9281,9285],{"id":8268,"depth":3502,"text":8269},{"id":8286,"depth":3502,"text":8287},{"id":8318,"depth":3502,"text":8319,"children":9267},[9268,9269,9270,9271,9272],{"id":8333,"depth":3499,"text":8334},{"id":8455,"depth":3499,"text":8456},{"id":8593,"depth":3499,"text":8594},{"id":8724,"depth":3499,"text":8725},{"id":8815,"depth":3499,"text":8816,"children":9273},[9274,9275],{"id":8819,"depth":3949,"text":8820},{"id":8829,"depth":3949,"text":8830},{"id":8881,"depth":3502,"text":8882,"children":9277},[9278,9279,9280],{"id":8885,"depth":3499,"text":8886},{"id":8919,"depth":3499,"text":8920},{"id":9163,"depth":3499,"text":9164},{"id":9172,"depth":3502,"text":9173,"children":9282},[9283,9284],{"id":9176,"depth":3499,"text":9177},{"id":9205,"depth":3499,"text":9206},{"id":9231,"depth":3502,"text":9232},"\u002Fcovers\u002Fclean-architecture.webp","2026-07-22","Главная цель Чистой архитектуры: создание системы, которая независима от фреймворков, баз данных, UI и внешних сервисов. Бизнес-логика изолирована и является ядром системы.",{},"\u002Fblog\u002Fclean-architecture",{"title":8263,"description":9288},"blog\u002Fclean-architecture",[4644,4645,3900],"3Tl5PCu_W6pu1XBdh2ZiQ86-MKSh9bX59oKlvLOttCU",1792405819829]