Вводные данные и муки выбора

Мой домашний сетап: NUC 64GB + RTX 3090 (24GB). Мне нужна была модель, которая станет основным помощником: быстро набросать скрипт для Proxmox, объяснить научный термин или вытащить данные из кучи документов (RAG).

Что я искал:

  1. Скорость: Читать 5 токенов в секунду – мучение. Хотелось «летающего» чата.

  2. Умный контекст: Чтобы модель не теряла нить разговора через пару страниц текста.

  3. Логика: Чтобы не приходилось перепроверять каждое слово за ней.

Что не подошло:

  • Qwen 3.5-35B: Просто не влез в память 3090-й с адекватным квантованием (особенно если оставлять место под контекст).

  • GGUF (Llama.cpp): Даже Q4 работал медленнее, чем хотелось бы. LM Studio удобно, но ощутимо медленнее.

  • NIM: “Родного” NIM с AWQ не нашел, а BF16 мне для дома перебор.

Мой выбор: stelterlab/Nemotron-Cascade-2-30B-A3B-AWQ.

Это гибридная архитектура (Mamba + MoE). За счет MoE (Mixture of Experts) она работает очень быстро, а Mamba-слои позволяют эффективно «переваривать» длинные запросы. Я запустил её через vLLM – это позволило использовать FP8 для KV-кэша и получить запредельный throughput.

Тесты

Методика тестирования

Чтобы проверить «мозги» модели, я попросил Gemini составить серию каверзных задач. Я прогонял их через AnythingLLM с подключенным vLLM.

Ниже – лог моих тестов. Для чистоты эксперимента я привожу исходный Вопрос, внутренние Размышления модели (Thinking) и финальный Ответ. В конце каждого блока – «разбор полетов» от Gemini.


Тест 1: Физика и термодинамика

Проверяем базовую логику и умение считать этапы процесса.

Вопрос

У нас есть 1 кг льда при температуре -10°C. Мы начинаем подводить тепло с постоянной мощностью 100 Вт. Опиши график изменения температуры во времени. Учти удельную теплоемкость льда (2100 Дж/кг·K) и удельную теплоту плавления (334 кДж/кг). Через какое время лед полностью превратится в воду?

Размышления модели (Thinking)

We need to answer in Russian likely. Provide description of temperature vs time graph: initially temperature rises from -10°C to 0°C with specific heat, then melting at 0°C (temperature constant) while latent heat absorbed, then after melting temperature rises above 0°C with water specific heat (but not given; maybe assume water specific heat 4186 J/kg·K). But question only asks time until ice fully becomes water. So need to compute time to melt: first heating ice from -10 to 0: Q1 = m * c_ice * ΔT = 1 kg * 2100 J/kgK * 10 K = 21000 J. Then latent heat: Q2 = m * L_f = 1 kg * 334000 J/kg = 334000 J. Total Q = 355000 J. Power = 100 W = 100 J/s. Time = Q / P = 355000 / 100 = 3550 s = about 59.2 minutes. If also consider heating water after melting? The question: “Через какое время лед полностью превратится в воду?” Means until all ice becomes water (i.e., after melting). At that moment temperature still 0°C (assuming no further heating). So time = 3550 s ≈ 59 min 10 s. Provide graph description: linear increase in temperature during heating phase, flat plateau during melting, then linear increase after melting (if continue). Provide equation: T(t) = -10 + (P/(m_c_ice)) t for 0 ≤ t ≤ t1, where t1 = 21000/100 = 210 s (3.5 min). Then constant at 0°C for t1 ≤ t ≤ t2, where t2 = (21000+334000)/100 = 3550 s. After t2, temperature rises as water warms: T(t) = (P/(m_c_water))(t - t2) + 0°C. Provide graph shape. Return answer.

Ответ модели

График температуры (T(t))

ПЕРИОД

ЧТО ПРОИСХОДИТ

УРАВНЕНИЕ ТЕМПЕРАТУРЫ

ДЛИТЕЛЬНОСТЬ

0 – (t_{1})

Нагрев твёрдого льда от (-10^{\circ}\text{C}) до (0^{\circ}\text{C}).

(\displaystyle T(t)= -10 + \frac{P}{m,c_{\text{ice}}},t) где (c_{\text{ice}}=2100;\text{Дж/(кг·K)}), (P=100;\text{Вт}), (m=1;\text{кг}).

(t_{1}= \dfrac{m,c_{\text{ice}}\Delta T}{P}= \dfrac{1\cdot2100\cdot10}{100}=210;\text{с}) (≈ 3 мин 30 с)

(t_{1}) – (t_{2})

Плавление льда при постоянной температуре (0^{\circ}\text{C}).

(T(t)=0^{\circ}\text{C}) (температура не меняется).

(t_{2}-t_{1}= \dfrac{mL_{\text{f}}}{P}= \dfrac{1\cdot334,000}{100}=3340;\text{с}) (≈ 55 мин 40 с)

(t_{2}) – …

После полного плавления начинается нагрев уже‑воды (если процесс продолжается).

(\displaystyle T(t)= \frac{P}{m,c_{\text{water}}}(t-t_{2})) где (c_{\text{water}}\approx 4186;\text{Дж/(кг·K)}).

После (t_{2}) температура начинает расти линейно.

График выглядит как прямая линия с наклоном в первом отрезке (нагрев льда), затем горизонтальная линия (плавление при 0 °C), после чего снова прямая линия с более мелким наклоном (нагрев уже‑воды).


Время, через которое лёд полностью превратится в воду

Полное превращение происходит в момент, когда закончится фаза плавления, т.е. в момент (t_{2}).

t_{2}=t_{1}+ \frac{mL_{\text{f}}}{P} =210;\text{с}+3340;\text{с}=3550;\text{с}. \boxed{t_{2}\approx 3.55\times10^{3}\ \text{с};\approx;59\ \text{минут};10\ \text{секунд}}

То есть при постоянной мощности 100 Вт весь лёд превратится в воду примерно через 59 минут.

(Если после полного плавления продолжать подачу тепла, температура воды начнёт расти, но «полностью превратившийся в воду» лёд уже будет в этот момент.)

Разбор полетов: Модель отработала на 10/10. Она не просто сложила цифры, а учла физику процесса: подметила, что после плавления наклон графика будет «более пологим», так как теплоемкость воды (4186\,Дж) выше, чем у льда, и она греется медленнее при той же мощности.


Тест 2: Биология и логика синтеза

Проверка на внимательность к деталям и соблюдение направлений цепей (5’-3’).

Вопрос

Дана матричная цепь ДНК: 3’-ТЦА-ГГА-АЦЦ-АТГ-5’. Построй на её основе иРНК (укажи 5’ и 3’). Используя справочные данные (АЦЦ – Тре, АУГ – Мет, ГГА – Гли, ГГУ – Гли, УЦА – Сер), напиши последовательность аминокислот. В ДНК произошла мутация: во втором кодоне (ГГА) последний А заменился на Т. Как изменится белок и как называется такая мутация?

Размышления модели (Thinking)

We need to answer in Russian, as the user wrote Russian. Provide the tRNA (actually mRNA) sequence derived from given DNA template (the given is “матричная цепь ДНК: 3’-ТЦА-ГГА-АЦЦ-АТГ-5’”. Need to produce the mRNA (informational RNA) and indicate 5’ and 3’ directions. Then using reference data, write the amino acid sequence. Then consider a mutation: in the second codon (ГГА) last nucleotide A changes to T. So original codon in DNA? Wait: The given DNA is the “матричная цепь” (template strand?) Usually the coding strand (sense) is given 5’ to 3’ as DNA, but they gave 3’ to 5’ orientation: 3’-ТЦА-ГГА-АЦЦ-АТГ-5’. The “Т” stands for T (thymine), “Ц” for C (cytosine), “А” for A, “Г” for G. So the sequence is 3’-T C A - G G A - A C C - A T G-5’. They ask to build the mRNA (informational RNA) based on it. The mRNA is complementary to the template strand (which is given 3’ to 5’), and same as coding strand (except T->U). So we need to reverse orientation to 5’ to 3’ for mRNA. Let’s interpret.

Given DNA template (non-coding) 3’ to 5’: 3’-T C A - G G A - A C C - A T G-5’. The mRNA is synthesized 5’ to 3’ complementary to template (i.e., same as coding strand but with U instead of T). So we need to find the complementary bases: DNA template (3’ to 5’) -> mRNA (5’ to 3’) is complementary: For each base in template (reading 3’ to 5’), the mRNA base is the complement (A->U, T->A, C->G, G->C). But also orientation: mRNA will be 5’ to 3’ opposite direction. Let’s write template 3’->5’: T C A G G A A C C A T G (grouped in codons). Actually it’s 12 nucleotides: T C A G G A A C C A T G. The mRNA will be 5’ to 3’ reading the complementary: For each base, complement: T (DNA) -> A (RNA), C -> G, A -> U, G -> C, G -> C, A -> U, A -> U, C -> G, C -> G, A -> U, T -> A, G -> C. So mRNA sequence (5’ to 3’) = A U G C C U U G G U A C? Wait need to check grouping: Let’s do stepwise.

Template (3’ to 5’): 1 T 2 C 3 A 4 G 5 G 6 A 7 A 8 C 9 C 10 A 11 T 12 G

Now complement (RNA) (5’ to 3’): 1 complement of T = A 2 complement of C = G 3 complement of A = U 4 complement of G = C 5 complement of G = C 6 complement of A = U 7 complement of A = U 8 complement of C = G 9 complement of C = G 10 complement of A = U 11 complement of T = A 12 complement of G = C

Thus mRNA 5’->3’: A U G C C U U G G U A C. Group into codons (triplets) from 5’ end: AUG CCU UGG UAC. That’s 4 codons (12 nucleotides). The original DNA had 4 codons (triplets) as well: TCA GGA ACC ATG (but note orientation). The mRNA codons: AUG (Met), CCU (Pro? Actually CCU codes for Proline), UGG (Trp), UAC (Tyr). But reference data given: They list codons and amino acids: AЦЦ — Тре (Треонин) (i.e., AC C? Wait AЦЦ is “АЦЦ”? They use Ц for C? Actually they wrote “АЦЦ — Тре (Треонин)”. In RNA, codon AC C? They wrote “АЦЦ” meaning “ACC”? In RNA, ACC would be “ACC”. But they wrote “АЦЦ”. Might be a typo: “АЦЦ” stands for “ACC”? In RNA, ACC codes for Threonine (Thr). Indeed ACC is a codon for threonine. They also have “АУГ — Мет (Метионин)” which is AUG (Met). “ГГА — Гли (Глицин)” which is GGA (Gly). “ГГУ — Гли (Глицин)” which is G GU (Gly). “УЦА — Сер (Серин)” which is UCA (Ser). “АГТ — (ошибка, в иРНК нет Т)” meaning AGT is not a valid RNA codon (since T not present). So reference data includes codons: ACC (Thr), AUG (Met), GGA (Gly), GGU (Gly), UCA (Ser). Good.

Our derived mRNA codons: AUG (Met), CCU (Pro), UGG (Trp), UAC (Tyr). But reference data does not have CCU (Pro) nor UAC (Tyr). However we can still map using standard genetic code: CCU = Pro (Proline), UGG = Trp, UAC = Tyr. But reference data only gave some codons; we can still answer using standard code. However maybe we mis-assigned orientation: The given DNA might be coding strand (5’ to 3’)? They said “матричная цепь ДНК: 3’-ТЦА-ГГА-АЦЦ-АТГ-5’”. Usually the coding strand is written 5’ to 3’, but they gave 3’ to 5’. Could be they gave the template strand (complementary). The mRNA is same as coding strand (except T->U). So we need to reverse orientation to 5’ to 3’ for mRNA. The coding strand would be the reverse complement of given template. The given is 3’ to 5’, so the coding strand (5’ to 3’) would be the reverse of given (i.e., 5’ to 3’): 5’-G T A C C G G A C T A? Wait need to compute.

Given template (3’ to 5’): T C A G G A A C C A T G. The coding strand (5’ to 3’) is the reverse complement: reading from 5’ to 3’ of coding: G T A C C G G A C T A? Let’s compute: The coding strand is complementary to template and same orientation as mRNA (except T). So we can take the template sequence and find its complement (DNA) but reversed order. The complement of each base: T->A, C->G, A->T, G->C, G->C, A->T, A->T, C->G, C->G, A->T, T->A, G->C. So complement (DNA) = A G T C C T T G G T A C. Now reverse to get 5’ to 3’ orientation: C A T G G A A C C G T A? Wait we need to reverse the complement: The complement string (5’ to 3’? Actually we wrote complement in same order as template (3’ to 5’)? Let’s be systematic.

Template (3’ to 5’): positions 1-12 as above. The coding strand (5’ to 3’) is the reverse of the complement (since template is 3’ to 5’). So we can take the complement (DNA) in same order as template (3’ to 5’) then reverse to get coding 5’ to 3’. Complement (DNA) in same order: A G T C C T T G G T A C (reading from position 1 to 12). Reverse this string: C A T G G A A C C G T A? Let’s reverse: original complement list: [A, G, T, C, C, T, T, G, G, T, A, C]. Reverse order: C, A, T, G, G, A, T, T, C, C, G, T? Wait need to be careful.

Let’s write complement string: positions: 1 A 2 G 3 T 4 C 5 C 6 T 7 T 8 G 9 G 10 T 11 A 12 C

Now reverse order (12 to 1): C, A, T, G, G, A, T, T, C, C, G, T? Actually reading: position12 C, 11 A, 10 T, 9 G, 8 G, 7 T, 6 T, 5 C, 4 C, 3 T, 2 G, 1 A. That yields: C A T G G T T C C T G A? Wait we have mismatch. Let’s recompute: I think we made mistake earlier. Let’s do step by step using python mental? Might be easier to just compute mRNA directly by taking complement of template and then reverse orientation.

But maybe simpler: The mRNA sequence we derived earlier (A U G C C U U G G U A C) seems plausible. Let’s verify using standard transcription: Template (3’ to 5’) = T C A G G A A C C A T G. The mRNA is synthesized 5’ to 3’ using base pairing: A (template) pairs with U, T with A, C with G, G with C. So reading template 3’->5’, we produce mRNA 5’->3’ as: A (for T), G (for C), U (for A), C (for G), C (for G), U (for A), U (for A), G (for C), G (for C), U (for A), A (for T), C (for G). That’s exactly what we got: A U G C C U U G G U A C. Good.

Now group into codons: AUG CCU UGG UAC. So mRNA codons: AUG (Met), CCU (Pro), UGG (Trp), UAC (Tyr). According to reference data, they gave ACC (Thr) not CCU (Pro). But note that ACC is DNA coding strand codon for Thr; in mRNA it’s ACC (RNA) which is also Thr? Wait ACC in RNA codes for Threonine (Thr). Indeed ACC (RNA) codes for Thr. But we have CCU (RNA) which codes for Pro. So there is a discrepancy. Maybe we mis-assigned which strand is template. Perhaps the given DNA is actually the coding strand (5’ to 3’) but they wrote 3’ to 5’ orientation incorrectly. Let’s test: If the given DNA is coding strand (5’ to 3’) but they wrote 3’ to 5’? The coding strand would be 5’ to 3’: T C A G G A A C C A T G (but they wrote 3’ to 5’). If that is coding strand, then mRNA would be same sequence but with U instead of T: 5’ to 3’ mRNA: U C A C C G G A C C A U? Wait replace T with U: T->U, C->C, A->A, G->G, G->G, A->A, A->A, C->C, C->C, A->A, T->U, G->G. So mRNA would be: U C A C C G G A C C A U G? Actually we need to keep order: original DNA (5’ to 3’) = T C A G G A A C C A T G. Replace T with U: U C A C C G G A C C A U G. That’s 12 nucleotides: UCA CCG GACC AU G? Group: UCA (Ser), CCG (Pro), GAC (Asp), CAU (His), G? Wait we have 12 nucleotides, groups of 3: UCA, CCG, GAC, CAU, G? Actually we have 12, so 4 codons: UCA, CCG, GAC, CAU, G? Wait we have 12 nucleotides, that’s 4 codons: UCA (Ser), CCG (Pro), GAC (Asp), CAU (His), and leftover G? Let’s count: U C A C C G G A C C A U G = 13? Let’s count: U(1) C2 A3 C4 C5 G6 G7 A8 C9 C10 A11 U12 G13. That’s 13 nucleotides, not 12. Something off. The original DNA had 12 nucleotides (4 codons). But after replacement we got 13 because we added extra? Actually we mis-copied: original DNA: T C A G G A A C C A T G (12). Replace T with U: U C A C C G G A C C A U G? Wait we have 12 nucleotides: positions: 1 T->U, 2 C, 3 A, 4 G, 5 G, 6 A, 7 A, 8 C, 9 C, 10 A, 11 T, 12 G. So mRNA: U C A G G A A C C A U G? Wait we need to replace each T with U, but keep other letters same. So sequence: 1 U, 2 C, 3 A, 4 G, 5 G, 6 A, 7 A, 8 C, 9 C, 10 A, 11 U, 12 G. That’s: U C A G G A A C C A U G. Group into codons: UCA (Ser), GGA (Gly), ACC (Thr), AUG (Met). That’s 4 codons: UCA, GGA, ACC, AUG. This matches reference data: they gave ACC (Thr), AUG (Met), GGA (Gly), and also UCA (Ser). Indeed reference data includes ACC (Thr), AUG (Met), GGA (Gly), UCA (Ser). So the coding strand is given as 3’ to 5’? Actually they gave 3’-ТЦА-ГГА-АЦЦ-АТГ-5’. If we read 3’ to 5’, the sequence is T C A G G A A C C A T G. That’s exactly the coding strand but written 3’ to 5’ orientation. So the coding strand is 3’ to 5’? That’s unusual but okay. The mRNA is same as coding strand (except T->U) and orientation 5’ to 3’ would be the reverse of that: 5’ to 3’ mRNA = U C A G G A A C C A U G? Wait we need to reverse orientation because coding strand is given 3’ to 5’, but mRNA is synthesized 5’ to 3’ using coding strand as template? Actually mRNA is same as coding strand (except T->U) and orientation is 5’ to 3’ same as coding strand orientation (5’ to 3’). Since coding strand is given 3’ to 5’, we need to reverse it to get 5’ to 3’ orientation. So the mRNA 5’ to 3’ would be the reverse of the coding strand (since coding strand is given 3’ to 5’). So we need to reverse the sequence: coding strand (3’ to 5’) = T C A G G A A C C A T G. Reverse order (5’ to 3’) = G T A C C G G A C C A T? Wait reverse: positions: 12 G, 11 T, 10 A, 9 C, 8 C, 7 A, 6 G, 5 G, 4 A, 3 C, 2 T, 1? Actually we need to be careful. Let’s just reverse the string: original: T C A G G A A C C A T G. Reverse: G T A C C G G A C C A T? Let’s write: original index: 1 T,2 C,3 A,4 G,5 G,6 A,7 A,8 C,9 C,10 T,11 G? Wait we have 12 nucleotides: T(1) C(2) A(3) G(4) G(5) A(6) A(7) C(8) C(9) A(10) T(11) G(12). Reverse order: G(12), T(11), A(10), C(9), C(8), A(7), A(6), G(5), G(4), A(3), C(2), T(1). That yields: G T A C C A A G G A C T? Wait we have: G T A C C A A G G A C T? Let’s list: 12 G, 11 T, 10 A, 9 C, 8 C, 7 A, 6 A, 5 G, 4 G, 3 A, 2 C, 1 T. So reversed string: G T A C C A A G G A C T. That’s 12 nucleotides. Replace T with U to get mRNA: G U A C C A A G G A C U? Wait T at position 11 becomes U, but we have T at position 12? Actually we have T at position 12? Let’s see: reversed string: G T A C C A A G G A C T. Replace T with U: G U A C C A A G G A C U. That’s mRNA 5’ to 3’: G U A C C A A G G A C U. Group into codons: GUA (Val), CCA (Pro), AGA (Arg), C U? Wait we have 12 nucleotides, groups: GUA, CCA, AGG, ACU? Actually we have 12: G U A C C A A G G A C U. Group: GUA (Val), CCA (Pro), AGG (Arg), ACU (Thr). That’s different from earlier. But reference data includes ACC (Thr), AUG (Met), GGA (Gly), UCA (Ser). Not matching.

Thus the correct approach is to treat given DNA as template (non-coding) 3’ to 5’, and mRNA is complementary (as we first did) giving AUG CCU UGG UAC. However reference data includes ACC (Thr) not CCU (Pro). But maybe they purposely gave reference codons that correspond to the mRNA we will get after mutation? Let’s see: The original mRNA codons we derived: AUG (Met), CCU (Pro), UGG (Trp), UAC (Tyr). The reference data includes ACC (Thr) which is not present. However maybe we mis-assigned which codon is which because we need to read the mRNA in the same reading frame as the original DNA codons (which were given as codons in DNA: TCA, GGA, ACC, ATG?). Actually the DNA given is 3’-ТЦА-ГГА-АЦЦ-АТГ-5’. If we read it as codons (triplets) in the same orientation (3’ to 5’), we have codons: TCA, GGA, ACC, ATG. Those are DNA codons (template?). The corresponding mRNA codons (using complement) would be: for TCA (DNA template) -> AUG (mRNA). For GGA -> CCU (mRNA). For ACC -> UGG (mRNA). For ATG -> UAC (mRNA). Indeed that matches our earlier mRNA codons: AUG, CCU, UGG, UAC. So the reference data includes ACC (Thr) as a DNA codon? Wait reference data lists codons in RNA: AЦЦ — Тре (Треонин). That is ACC (RNA) codes for Thr. Indeed ACC is a codon for Thr. In our mRNA we have CCU (Pro) not ACC. But note that ACC (RNA) is the complement of DNA TGG? Actually DNA ACC (coding) corresponds to mRNA ACC (Thr). In our mRNA we have CCU (Pro). So the reference data includes ACC (Thr) which is not in our mRNA. However the reference data also includes AUG (Met), GGA (Gly), GGU (Gly), UCA (Ser). Those correspond to DNA codons: ATG (Met), CCA (Pro?), GGA (Gly), UCA (Ser). Wait reference data includes ACC (Thr) which is DNA? Actually they said “АЦЦ — Тре (Треонин)”. In RNA, ACC codes for Thr. So they gave ACC as a codon in RNA. In our mRNA we have ACC? No we have CCU. So maybe we mis-assigned which strand is template. Let’s try alternative: Suppose the given DNA is the coding strand (5’ to 3’) but they wrote 3’ to 5’ orientation incorrectly. The coding strand would be 5’ to 3’: T C A G G A A C C A T G (same as given but orientation reversed). The mRNA would be same as coding strand (except T->U) and orientation 5’ to 3’ would be U C A G G A A C C A U G (as we computed earlier). Group into codons: UCA (Ser), GGA (Gly), ACC (Thr), AUG (Met). That matches reference data: UCA (Ser), GGA (Gly), ACC (Thr), AUG (Met). Indeed reference data includes ACC (Thr), AUG (Met), GGA (Gly), UCA (Ser). Perfect! So the correct interpretation: The given DNA sequence is the coding strand (but written 3’ to 5’), and the mRNA sequence (5’ to 3’) is the reverse of it with T->U. So we need to present mRNA as 5’ to 3’ direction: 5’-U C A G G A A C C A U G-3’? Wait we need to reverse orientation: The given DNA is 3’ to 5’, so to get mRNA 5’ to 3’, we reverse the sequence and replace T with U. So the mRNA sequence is 5’-U C A G G A A C C A U G-3’? Let’s verify: Original DNA (3’ to 5’): T C A G G A A C C A T G. Reverse order (5’ to 3’): G T A C C A A G G A C T? Wait we need to be careful: The coding strand is given 3’ to 5’, but we want mRNA 5’ to 3’ which is same as coding strand but with U instead of T and orientation 5’ to 3’. Since coding strand is given 3’ to 5’, we need to reverse it to get 5’ to 3’. So we reverse the string: original: T C A G G A A C C A T G. Reverse: G T A C C A A G G A C T? Wait we need to write correctly: Let’s write indices:

1 T 2 C 3 A 4 G 5 G 6 A 7 A 8 C 9 C 10 A 11 T 12 G

Reverse order (12 to 1): G, T, A, C, C, A, A, G, G, A, C, T. So reversed string: G T A C C A A G G A C T. Now replace T with U: G U A C C A A G G A C U. That’s the mRNA 5’ to 3’ we got earlier (G U A C C A A G G A C U). But earlier we thought the mRNA should be U C A G G A A C C A U G. Which is correct? Let’s compare: Our earlier derived mRNA (U C A G G A A C C A U G) is the reverse of this? Let’s reverse that: U C A G G A A C C A U G reversed = G U A C C A A G G A C U. Indeed that’s the same as we just got! So both are same but orientation reversed. So the correct mRNA 5’ to 3’ is G U A C C A A G G A C U. However earlier we thought the mRNA should be U C A G G A A C C A U G (starting with U). Which is correct? Let’s check using the concept: coding strand (5’ to 3’) would be the reverse of given (since given is 3’ to 5’). The coding strand 5’ to 3’ is G T A C C A A G G A C T (as we computed). Replace T with U gives G U A C C A A G G A C U. So that is the mRNA 5’ to 3’. So the mRNA sequence is G U A C C A A G G A C U. Group into codons: GUA (Val), CCA (Pro), AGG (Arg), ACU (Thr). But reference data says codons: ACC (Thr), AUG (Met), GGA (Gly), UCA (Ser). That’s different. Something is inconsistent.

Let’s re-evaluate: The reference data likely corresponds to the mRNA codons we should get from the given DNA. The given DNA codons (in DNA) are: TCA, GGA, ACC, ATG (reading 3’ to 5’? Actually they are written as 3’-ТЦА-ГГА-АЦЦ-АТГ-5’, which if we read left to right is 3’ to 5’ orientation. The corresponding mRNA codons (reading 5’ to 3’) would be: for TCA (DNA) -> AUG (mRNA). For GGA -> CCU (mRNA). For ACC -> UGG (mRNA). For ATG -> UAC (mRNA). That yields mRNA: AUG CCU UGG UAC. This matches earlier. But reference data includes ACC (Thr) which is not in that list. However reference data includes ACC (Thr) which is the DNA codon? Wait ACC in DNA codes for Thr? Actually DNA codon ACC (coding strand) corresponds to mRNA ACC (Thr). In our mRNA we have UGG (Trp) not ACC. So reference data seems to be about DNA codons? Let’s map: They gave codons in RNA: AЦЦ — Тре (Треонин). In RNA, ACC codes for Thr. So they gave ACC as an RNA codon. In our mRNA we have ACC? No we have CCU, not ACC. But note that ACC and CCU are reverse complements? Actually ACC (RNA) is complementary to UGG (RNA). Indeed ACC (RNA) pairs with UGG (RNA) in double-stranded RNA. So maybe they gave reference codons for the opposite strand? This is confusing.

Given the confusion, we need to produce answer that aligns with the question’s expectation. The question likely expects the student to:

  1. Write the mRNA sequence (5’ to 3’) derived from given DNA template (3’ to 5’): 5’-U C A G G A A C C A U G-3’? Or maybe 5’-A U G C C U U G G U A C-3’? Which one is correct? Let’s see typical textbook: If DNA template is 3’->5’ as given, the mRNA is synthesized 5’->3’ complementary: So we would get mRNA 5’->3’ = A U G C C U U G G U A C (as we first derived). Many textbooks present that. The reference data includes codons: AUG (Met), ACC (Thr), GGA (Gly), GGU (Gly), UCA (Ser). The mRNA we have (AUG CCU UGG UAC) includes AUG (Met) which matches reference. It also includes CCU (Pro) not in reference, but reference includes ACC (Thr) which is not present. However maybe they want to map each codon to amino acid using reference data: AUG -> Met, CCU ->? Not listed, but maybe they expect to use standard code: CCU -> Pro (Proline). UGG -> Trp (not listed), UAC -> Tyr (not listed). But reference data includes UCA (Ser) which is not in our list. So maybe we mis-assigned which codon corresponds to which. Let’s try to map the given DNA codons to mRNA codons using the reference data: The DNA codons (in DNA) are: TCA, GGA, ACC, ATG. The corresponding mRNA codons (same as DNA but T->U) would be: UCA, GGA, ACC, AUG (if we treat DNA as coding strand). That matches reference data: UCA (Ser), GGA (Gly), ACC (Thr), AUG (Met). Indeed reference data includes those codons! So the correct interpretation is that the given DNA is the coding strand (5’ to 3’) but they wrote it 3’ to 5’ for some reason. The mRNA sequence (5’ to 3’) is the same as the coding strand but with U instead of T, and orientation 5’ to 3’ is the reverse of the given (since given is 3’ to 5’). So the mRNA sequence is 5’-U C A G G A A C C A U G-3’? Wait we need to reverse the given: given 3’ to 5’ = T C A G G A A C C A T G. Reverse to 5’ to 3’ = G T A C C A A G G A C T. Replace T with U: G U A C C A A G G A C U. That’s not UCA GGA ACC AUG. So which is correct? Let’s check: If we treat given as coding strand but written 3’ to 5’, then the coding strand 5’ to 3’ is the reverse of given: G T A C C A A G G A C T. Replace T with U: G U A C C A A G G A C U. That’s the mRNA we got earlier (G U A C C A A G G A C U). But reference data expects mRNA: UCA GGA ACC AUG (which is different). So maybe we should not reverse; maybe the given is actually the coding strand but written 3’ to 5’ meaning the leftmost base is 3’ end, rightmost is 5’ end. In that case, the coding strand 5’ to 3’ would be reading from right to left: A T G A C C G G A C A T? Wait let’s write given as 3’ to 5’: 3’-T C A G G A A C C A T G-5’. The rightmost base (G) is the 5’ end. So the coding strand 5’ to 3’ is G T A C C A A G G A C T? Actually reading from rightmost to leftmost: G (position12), T (11), A (10), C (9), C (8), A (7), A (6), G (5), G (4), A (3), C (2), T (1). That yields: G T A C C A A G G A C T. That’s the same as before. So coding strand 5’ to 3’ is GTACC AAGG ACT? Wait we have GTACC AAGG ACT? Actually it’s GTACC AAGG ACT? Let’s group: GTACC AAGG ACT? That’s 12 nucleotides: GTACC AAGG ACT? That’s GTACC AAGG ACT? The sequence: G T A C C A A G G A C T. Group into codons: GTA (Val), CCA (Pro), AGG (Arg), ACT (Thr). Replace T with U: G U A C C A A G G A C U (same as before). So mRNA would be G U A C C A A G G A C U. That does not match reference data.

Thus the reference data suggests that the coding strand is actually the given sequence read left to right as 5’ to 3’ (i.e., they gave the coding strand but wrote 3’ to 5’ incorrectly). If we treat the given as coding strand 5’ to 3’ (i.e., the leftmost base is 5’ end), then the sequence would be 5’-T C A G G A A C C A T G-3’. Then mRNA would be same but T->U: U C A G G A A C C A U G (5’ to 3’). That matches reference data: UCA (Ser), GGA (Gly), ACC (Thr), AUG (Met). Indeed reference data includes those codons. So the correct answer likely expects mRNA: 5’-U C A G G A A C C A U G-3’ (or written as UCAGGAACC AUG?). They also ask to indicate directions 5’ and 3’. So we should present mRNA as 5’->3’ sequence: 5’-U C A G G A A C C A U G-3’. And note that the template strand (given) is 3’->5’.

Thus the answer: mRNA sequence: 5’‑U C A G G A A C C A U G‑3’. Codons: UCA (Ser), GGA (Gly), ACC (Thr), AUG (Met). Amino acid sequence: Ser‑Gly‑Thr‑Met.

Now mutation: In the second codon (ГГА) last nucleotide A replaced by T. The second codon in DNA is ГГА (GGA). In DNA coding strand, the codon is GGA (DNA). The last nucleotide A becomes T, so codon becomes GGT (DNA). In mRNA, GGT (DNA) becomes GGU (RNA). So the codon changes from GGA (Gly) to GGU (Gly). According to reference data, both GGA and GGU code for Gly (glycine). So the amino acid remains Gly (glycine). The type of mutation: silent (synonymous) because amino acid does not change. It is not missense (missense changes amino acid) nor nonsense (creates stop). So it’s a silent (synonymous) mutation.

Thus answer: sequence unchanged (still Gly), mutation is silent (synonymous). Provide explanation.

Now produce final answer in Russian, include mRNA sequence, direction, amino acid sequence, mutated codon, new amino acid, type of mutation.

Let’s craft answer.

Ответ модели

Много букв спрятал

1. Информационная РНК (мРНК), построенная по заданной цепи ДНК

Данная цепь ДНК указана в виде 3’‑ТЦА‑ГГА‑АЦЦ‑АТГ‑5’.
Если считать её «кодирующей» (т.е. её последовательность совпадает с последовательностью мРНК, только вместо Т – У), то для получения мРНК нужно просто заменить все Т на У и записать её в направлении 5’→3’ (т.к. в условии цепочка написана 3’→5’).

DNA (3'→5') :  Т  Ц  А  Г  Г  А  А  Ц  Ц  А  Т  Г
               |  |  |  |  |  |  |  |  |  |  |  |
mRNA (5'→3') :  У  Ц  А  Г  Г  А  А  Ц  Ц  А  У  Г
               = 5'‑U C A G G A A C C A U G‑3'

Кодирующие (транскрибированные) кодоны мРНК

Кодон (мРНК)

Аминокислота (по справочным данным)

UCA

Серин (Ser)

GGA

Глицин (Gly)

ACC

Треонин (Thr)

AUG

Мет (Met)

Итак, последовательность аминокислот в получившемся пептиде — Ser‑Gly‑Thr‑Met.

2. Мутация во втором кодоне (ГГА → ГГТ)

Во втором кодоне ДНК (в оригинальном виде) был кодон ГГА.
Мутация: последний нуклеотид А → Т → получаем кодон ГГТ (в ДНК).

Транскрибируется в мРНК как GGU (т.к. Т заменяется на У).

Кодон (мРНК)

Аминокислота

GGA

Глицин (Gly)

GGU

Глицин (Gly)

Изменение последовательности аминокислот:
‑ Аминокислота в этом месте остаётся глицин (не меняется).

Тип мутации:
‑ Поскольку замена нуклеотида не привела к переходу на другой кодон, кодирующий другую аминокислоту, а просто заменил один глицин‑кодон другим, такая мутация называется сигнальная (сильная) «силентная» (synonymous) мутация – более точно «сильная» или «сильная (silent) мутация».
Она не является миссенс‑ (изменяющей аминокислоту) и не является нонсенс‑ (создающей стоп‑кодон) мутацией.

(а эту часть не стал прятать)

Кратко

Параметр

Ответ

мРНК (5’→3’)

5’‑U C A G G A A C C A U G‑3’

Кодирующие кодоны

UCA – Ser, GGA – Gly, ACC – Thr, AUG – Met

Последовательность аминокислот

Ser‑Gly‑Thr‑Met

Мутация в 2‑м кодоне

ГГА → ГГТ (в мРНК: GGU)

Изменение аминокислоты

Глицин → Глицин (без изменения)

Название мутации

Сильентная (synonymous) мутация

Если нужны дополнительные пояснения – дайте знать!

Разбор полетов: Это был самый показательный момент. В «размышлениях» видно, как модель сначала запуталась в ориентации цепей, но сама себя перепроверила по справочным данным и исправила логику «на лету». Без активного Thinking она бы этот тест провалила, как и многие модели поменьше.


Тест 3: Python и векторизация

Проверяем умение писать эффективный код, а не просто циклы.

Вопрос

Напиши функцию на Python (numpy), которая рассчитывает уникальные углы дифракции \theta для кубического кристалла по формуле n\lambda = 2d \sin(\theta), где d = a / \sqrt{h^2+k^2+l^2}.

Размышления модели (Thinking)

We need to write a Python function per spec, using numpy, compute angles for given lambda, a, max index. Return list of unique angles in degrees. Should iterate over all combos (h,k,l) from 0? Typically Miller indices start from 1? But could include zero? Usually (h,k,l) integers, not all zero. We’ll consider range 1…max inclusive? Might include zero? We’ll include 0 to max, but skip (0,0,0). Compute d = a / sqrt(h^2+k^2+l^2). Then sinθ = nλ/(2d). n is order? Usually n integer, but we can assume n=1 (first order) unless otherwise. The problem statement: “рассчитывает углы, под которыми наблюдаются максимумы дифракции рентгеновских лучей” and formula nλ = 2d sinθ. Usually n is integer order. Could assume n=1 for simplicity. We’ll implement with n=1. Check sinθ <=1. Compute θ = arcsin(…). Convert to degrees. Collect unique angles (within tolerance). Return sorted list.

Add comment about why increasing Miller indices leads to larger θ: because larger indices correspond to smaller d (spacing), thus sinθ = λ/(2d) larger, so θ larger up to 90°.

Write code with numpy.

Return list of floats.

Let’s craft answer in Russian as user wrote Russian. Provide function definition and explanation.

Ответ модели

Код

import numpy as np

def bragg_angles(lambda_nm: float,
                a_nm: float,
                hkl_max: int,
                n: int = 1,
                 tol: float = 1e-9) -> list:
    """
    Вычисляет углы θ (в градусах), при которых наблюдаются максимумы
    дифракции рентгеновских лучей на кубическом кристалле
    по закону Брэгга  n·λ = 2·d·sinθ.

    Параметры
    ----------
    lambda_nm : float
        Длина волны λ (нм).
    a_nm : float
        Параметр решетки куба a (нм).
    hkl_max : int
        Максимальное значение индексов Миллера (h, k, l).  
        Индексы перебираются в диапазоне [0, hkl_max] (исключая (0,0,0)).
    n : int, optional
        Порядок дифракции (по умолчанию 1).
    tol : float, optional
        Точность при проверке уникальности углов.

    Возвращает
    ----------
    list[float]
        Отсортированный список уникальных углов θ в градусах.
    """
    # массив индексов от 0 до hkl_max включительно
    idx = np.arange(hkl_max + 1, dtype=int)
    # построим сетку всех комбинаций (h,k,l)
    h, k, l = np.meshgrid(idx, idx, idx, indexing='ij')
    # «плоская» версия массивов
    h = h.ravel()
    k = k.ravel()
    l = l.ravel()

    # исключаем нулевой набор (0,0,0) – такой плоскости нет
    mask = (h != 0) | (k != 0) | (l != 0)
    h, k, l = h[mask], k[mask], l[mask]

    # межплоскостное расстояние d = a / sqrt(h²+k²+l²)
    d = a_nm / np.sqrt(h**2 + k**2 + l**2)

    # sinθ = n·λ / (2·d)
    sin_theta = n * lambda_nm / (2.0 * d)

    # оставляем только физически допустимые значения (sinθ ≤ 1)
    valid = sin_theta <= 1.0 + 1e-12   # небольшая погрешность
    sin_theta = sin_theta[valid]

    # вычисляем угол в радианах, затем переводим в градусы
    theta_rad = np.arcsin(np.clip(sin_theta, -1.0, 1.0))
    theta_deg = np.degrees(theta_rad)

    # уникальные углы (с учётом числовой погрешности)
    theta_unique = np.unique(np.round(theta_deg, int(-np.log10(tol))))

    return theta_unique.tolist()

Как работает функция

  1. Перебор индексов – создаём все тройки ((h,k,l)) от 0 до hkl_max.
    Комбинация ((0,0,0)) физически не имеет смысла, поэтому она отбрасывается.

  2. Вычисление межплоскостного расстояния
    [ d = \frac{a}{\sqrt{h^{2}+k^{2}+l^{2}}} ]
    При росте индексов (|h|,|k|,|l|) знаменатель увеличивается, а значит (d) уменьшается.

  3. Закон Брэгга
    [ \sin\theta = \frac{n\lambda}{2d} ]
    При меньшем (d) (то есть при больших индексах) правая часть становится больше, поэтому (\sin\theta) растёт, а угол (\theta) сдвигается к более высоким значениям (до предела (\theta = 90^{\circ}), когда (\sin\theta = 1)). Это объясняет, почему «плоскости» с большими индексами дают более «широкие» дифракционные пятна.

  4. Фильтрация – оставляем только те (\sin\theta), которые не превышают 1 (иначе угол невозможен).

  5. Уникальные углы – из всех найденных углов отбрасываем дубли, округляя их до заданной точности (tol) и сортируем.

Пример использования

# λ = 1.54 Å (Cu Kα), a = 3.60 Å, индексы до 3
angles = bragg_angles(lambda_nm=1.54, a_nm=3.60, hkl_max=3)
print(angles)
# → [19.47, 28.66, 33.33, 43.73, 53.13, 61.87, 70.53, 76.66, 82.85, 87.13]

Полученный список содержит все углы (\theta) (в градусах), при которых при данных параметрах наблюдаются максимумы дифракции рентгеновских лучей на кубическом кристалле.

Разбор полетов: Модель отказалась от медленных вложенных циклов в пользу векторных операций numpy. Она также предусмотрела обработку числовой погрешности (round), понимая, что в физике плоскости (1,0,0) и (0,1,0) должны давать один и тот же результат, несмотря на микро-ошибки float при вычислениях.


Тест 4 - использование Playwright MCP

Тоже в AnythingLLM.

Ощутимо медленнее просто вопросов (без агентов). Но по идее с агентами и другие ощутимо тормозят.

Вопрос

@agent Перейди на https://thehackernews.com/ и выдай заголовки первых трех новостей

Размышления агента (Thinking)
Agent @agent invoked. Swapping over to agent chat. Type /exit to exit agent execution loop early.

<think> We need to follow instruction: pick a function if appropriate. The user asks to navigate to a site and output headers of first three news. This requires navigating to site, maybe need to use browser functions: navigate, then possibly click, etc., then maybe read headers. The instruction set: There are functions like Browser_search-browser_navigate, etc. The user request: "Перейди на https://thehackernews.com/ и выдай заголовки первых трех новостей". We can interpret that we need to navigate to URL then perhaps read page content. Possibly the appropriate function is Browser_search-browser_navigate to go to URL, then perhaps Browser_search-browser_file_upload? No. Perhaps we need to navigate then maybe use browser_evaluate or something to extract text. But the prompt says we should output JSON with function name and arguments, no additional text, just one function. But we also have the rule: "DO NOT HAVE TO PICK A FUNCTION IF IT WILL NOT HELP ANSWER OR FULFILL THE USER'S QUERY." We need to pick a single function that we will use to call. But the whole user query is to 'navigate to URL and output the headlines of first three news'. We have browser functions to navigate, get information, etc. There is also document-summarizer or rag-memory but those are for local docs, not relevant. The appropriate step is to navigate to the given site, then maybe run code to extract headers. The function we could call is Browser_search-browser_navigate to go to the site. However, after navigation, we would need to parse the page, which may need more functions (browser_evaluate, etc). But the instruction says we should pick a single function to call if any seem useful or relevant. We might need to first navigate, but perhaps we can combine navigation and code extraction in one function call: Browser_search-browser_evaluate can run code to extract headlines? Actually it's to evaluate JavaScript expression, can be used to navigate? Browser_search-browser_run_code appears to be "Run Playwright code snippet" which allows you to navigate and extract content all at once. It takes a code snippet that can do actions like go to URL, query selectors, etc. That could be used in one step: run code like `async (page) => { await page.goto('https://thehackernews.com/'); const headlines = await page.$$eval('h2, h3, .post-title a, ...', nodes => ...); return headlines.slice(0,3); }` Possibly. But the simpler approach: Use Browser_navigate? The function maybe just navigates and returns something? But navigate just returns nothing, presumably just navigates page. The user expects output with headlines. However we can pick several function calls sequentially but instructions limit to one function for now. The typical pattern: They want us to call Browser_action to navigate first. Then next turn we could extract. But we could also call Browser_run_code that does both navigation and extraction. The function definition: Browser_search-browser_run_code has code param: a string of Playwright code to be executed. That is appropriate: we can provide code that navigates to URL, extracts first three headlines, and returns them. That would fulfill user's request in one function call. Thus we should output JSON with name "Browser_search-browser_run_code" and arguments code: something. The user wants the output of three headlines. So we can write code that extracts them. Example: `async (page) => { await page.goto('https://thehackernews.com/'); const titles = await page.$$eval('article h2 a, .river h2, .post-title a', els => els.map(el => el.textContent.trim())); return titles.slice(0,3); }` But needs to be Playwright code snippet that returns value. Should be string. Thus output JSON as: { "name": "Browser_search-browser_run_code", "arguments": { "code": "async (page) => { await page.goto('https://thehackernews.com/'); const titles = await page.$$eval('a.entry-link, h2.post-title, h3.post-title', els => els.map(el => el.textContent.trim()).filter(Boolean); return titles.slice(0,3); }" } } Make sure proper quoting and escaping. In JSON, need to escape newline? Actually we can just present multi-line string? But we can embed as a string. Use appropriate escaping. Better to phrase: "code":"async (page) => { await page.goto('https://thehackernews.com/'); const items = await page.$$eval('h2, .post-title__link', els => els.map(e => e.textContent.trim()).filter(t => t); return items.slice(0,3); }". Might need correct path. Let's craft final answer: Provide JSON. </think> { "name": "Browser_search-browser_run_code", "arguments": { "code": "async (page) => {\n await page.goto('https://thehackernews.com/');\n const titles = await page.$$eval('h2, .post-title, .river h2, .post-title__link', elts => {\n return elts.map(el => el.textContent.trim()).filter(t => t);\n });\n return titles.slice(0, 3);\n}" } }

Parsed Tool Call: Browser_search-browser_run_code({"code":"async (page) => { await page.goto('https://thehackernews.com/'); const titles = await page.$$eval('a.entry-link, h2.post-title, h3.post-title', els => els.map(el => el.textContent.trim()).filter(Boolean); return titles.slice(0,3); }"})

@agent is executing `Browser_search-browser_run_code` tool { "code": "async (page) => { await page.goto('https://thehackernews.com/'); const titles = await page.$$eval('a.entry-link, h2.post-title, h3.post-title', els => els.map(el => el.textContent.trim()).filter(Boolean); return titles.slice(0,3); }" }

Executing MCP server: Browser_search with { "code": "async (page) => { await page.goto('https://thehackernews.com/'); const titles = await page.$$eval('a.entry-link, h2.post-title, h3.post-title', els => els.map(el => el.textContent.trim()).filter(Boolean); return titles.slice(0,3); }" }

MCP server: Browser_search:browser_run_code completed successfully

Done thinking.
Размышления модели (Thinking)
 Okay, let's see. The user is asking to transition to https://thehackernews.com/ and output the first three news headlines.

Wait, the previous context shows a Playwright code that navigated to the site and got a snapshot. The result shows an error in the code, but then there's a detailed snapshot of the page.

Looking at the snapshot, under the "main" section, there's a list of items under "navigation". The first three list items under "list" (probably the main news items) are:

"Citrix NetScaler Under Active Recon for CVE-2026-3055 (CVSS 9.3) Memory Overread Bug"
"2026 Annual Threat Report: A Defender's Playbook From the Front Lines"
"CISA Adds CVE-2025-53521 to KEV After Active F5 BIG-IP APM Exploitation"
Wait, but the user asked for the first three news headlines. Let me check the exact order.

In the snapshot, under the navigation section's list, the list items are:

Home
Vulnerabilities
Cyber Attacks
Expert Insights
Awards
Wait, no. Wait, the "navigation" part has a link "Cyber Attacks" and then the main content under "main" has a list of news items. The actual news items are under the main section's "generic [ref=e45]".

Looking at the snapshot, the first news item is about Citrix NetScaler, then the next one is about the 2026 Annual Threat Report, then the one about CISA adding CVE-2025-53521 to KEV. Those are the first three news headlines.

Wait, the titles under the main content:

-"Citrix NetScaler Under Active Recon for CVE-2026-3055 (CVSS 9.3) Memory Overread Bug" -"2026 Annual Threat Report: A Defender's Playbook From the Front Lines" -"CISA Adds CVE-2025-53521 to KEV After Active F5 BIG-IP APM Exploitation"

Yes, those are the first three. The user wants the titles of the first three news stories on the homepage.

So the answer should list these three titles. But the user is asking to "выдать заголовки первых трех новостей" which translates to "output the headlines of the first three news stories".

So I need to provide those three titles as the answer.

Wait, but the user's instruction says "Перейди на https://thehackernews.com/ и выдай заголовки первых трех новостей" which means "Go to https://thehackernews.com/ and output the headlines of the first three news stories."

In the provided context, the snapshot shows those three titles as the first three news items. The evidence shows that in the "main" section, the first three list items under the generic [ref=e45] etc. are the three headlines.

So the correct answer is to list those three headlines. The three are:

Citrix NetScaler Under Active Recon for CVE-2026-3055 (CVSS 9.3) Memory Overread Bug
2026 Annual Threat Report: A Defender's Playbook From the Front Lines
CISA Adds CVE-2025-53521 to KEV After Active F5 BIG-IP APM Exploitation
So the answer should be these three, probably in order.

Ответ модели

  • Citrix NetScaler Under Active Recon for CVE-2026-3055 (CVSS 9.3) Memory Overread Bug

  • 2026 Annual Threat Report: A Defender’s Playbook From the Front Lines

  • CISA Adds CVE-2025-53521 to KEV After Active F5 BIG-IP APM Exploitation


Тест 5 - использование агентов, встроенных в AnythingLLM

Повтор эксперимента, но Playwright остановил, а “родные” web scrape/search включил.

По ощущениям быстрее предыдущего. Может просто потому что в этот раз меньше размышлений генерировала. И не уверен насчет кеширования. Запрос-то точно у нее в голове оставался.

Вопрос

@agent Перейди на https://thehackernews.com/ и выдай заголовки первых трех новостей

Размышления агента (Thinking)
Agent @agent invoked. Swapping over to agent chat. Type /exit to exit agent execution loop early.
Agent is thinking...

Не успел поймать подробности, пропали после выдачи финального ответа.
Размышления модели (Thinking)
We need to answer: "Перейди на https://thehackernews.com/ и выдай заголовки первых трёх новостей". The user asks to go to site and output the headlines of the first three news items. The system gave us a snapshot showing the page content with many elements. The first three news entries likely correspond to the top three articles in the main feed.

From the snapshot, after the navigation menu, the "main" area shows generic -> list of items. The first few are "Citrix NetScaler Under Active Recon for CVE-2026-3055", "CISA Adds CVE-2025-53521 to KEV", and "2026 Annual Threat Report..."? Actually the snapshot shows many links with headings. The first visible "link [ref=e53]" is the Citrix article. Next is "CISA Adds CVE-2025-53521 to KEV..." (e62). Then "cyber security 2026 Annual Threat Report: A Defender's Playbook..." (e71). Those are probably the first three news headlines on the homepage. Let's extract their titles as displayed.

First: "Citrix NetScaler Under Active Recon for CVE-2026-3055 (CVSS 9.3) Memory Overread Bug". Second: "CISA Adds CVE-2025-53521 to KEV After Active F5 BIG-IP APM Exploitation". Third: "2026 Annual Threat Report: A Defender's Playbook From the Front Lines Learn how modern attackers bypass MFA, exploit gaps, weaponize automation, run 8-phase intrusions, and more."

Thus answer in Russian, list three headlines. Provide as bullet list. Ensure to comply.

Ответ модели

Первые три заголовка на главной странице The Hacker News (https://thehackernews.com/):

  1. Citrix NetScaler Under Active Recon for CVE-2026-3055 (CVSS 9.3) Memory Overread Bug

  2. CISA Adds CVE‑2025‑53521 to KEV After Active F5 BIG‑IP APM Exploitation

  3. 2026 Annual Threat Report: A Defender’s Playbook From the Front Lines – Learn how modern attackers bypass MFA, exploit gaps, weaponize automation, run 8‑phase intrusions, and more

Эти заголовки находятся в верхней части ленты новостей на главной странице сайта.


Технические грабли: Проблема “Thinking”

В процессе настройки я столкнулся с интересной проблемой: при использовании «агентов» в AnythingLLM (например, для выхода в интернет через Playwright) модель иногда теряет теги размышлений или путает форматы ответов.

Я пробовал отключать рассуждения через параметры vLLM (enable_thinking: false), надеясь ускорить вывод и упростить жизнь парсеру.

Результат: Не делайте так. Модель мгновенно «глупеет». Если в задаче про лед она еще держится на заученных формулах, то в биологии начинает нести полную чушь, путая буквы в цепях ДНК и теряя логику мутаций.

Решение: Оставлять рассуждения включенными. Чтобы AnythingLLM не “давился” ими, мы с Gemini написали простую проксю на Python, которая выхватывает блок think и добавляет его в начало ответа. Если вы знаете более элегантный способ прокидывать блоки размышлений в AnythingLLM через OpenAI-совместимый API – буду рад советам в комментариях!

Update: Всего лишь нужно было добавить --reasoning-parser deepseek_r1 к параметрам vLLM. Обновил запускающий скрипт внизу. Никакие прокси не нужны.

Если еще и Claude Code на такое получится натравить – вообще буду рад :)

Итог

Nemotron-Cascade-2-30B на RTX 3090 выдает честные 120-150 токенов в секунду (generation throughput) и до 210+ t/s с учетом размышлений. Для домашнего сервера это «золотая середина»: она достаточно компактная, чтобы влезть в 24ГБ с приличным контекстом, и достаточно умная, чтобы реально помогать в работе, а не просто выдавать похожий на правду текст.

“–enforce-eager” в дополнительных параметрах vLLM позволяет еще увеличить контекст, но скорость настолько падает, что проще уж LM Studio использовать.

Так что я остановился на Nemotron-Cascade-2 и пока другое искать не планирую. Вряд ли что-то лучше мои хотелки удовлетворит при таких вводных и ожиданиях.

Запускаю так:

Скрипт запуска
#!/bin/bash
N=nemotron-30b
MODEL_ID="stelterlab/Nemotron-Cascade-2-30B-A3B-AWQ"

# ВЫБОР РЕЖИМА: "BALANCE" или "MAX_CONTEXT"
MODE="BALANCE"
#MODE="MAX_CONTEXT"

if [ "$MODE" == "BALANCE" ]; then
    GPU_UTIL=0.9
    EAGER_FLAG=""
    MAX_LEN=32768
else
    # MAX_CONTEXT режим
    GPU_UTIL=0.9
    EAGER_FLAG="--enforce-eager"
    # Без графов можно пробовать 32k+, так как AWQ сильно экономит веса
    MAX_LEN=32768
fi

echo "🚀 Launching in $MODE mode (Util: $GPU_UTIL, MaxLen: $MAX_LEN)..."

docker rm -f vllm_$N
docker run -d -it --name vllm_$N \
  --runtime=nvidia --gpus all --shm-size=16g \
  -e CUDA_DEVICE_ORDER=PCI_BUS_ID \
  -e CUDA_VISIBLE_DEVICES=1 \
  -v /opt/.cache/huggingface:/root/.cache/huggingface \
  -p 8003:8000 \
  --restart unless-stopped \
  vllm/vllm-openai:latest \
  $MODEL_ID \
  --trust-remote-code \
  --served-model-name $N \
  --gpu-memory-utilization $GPU_UTIL \
  --max-model-len $MAX_LEN \
  --kv-cache-dtype fp8 \
  $EAGER_FLAG \
  --reasoning-parser deepseek_r1 \
  --enable-auto-tool-choice \
  --tool-call-parser llama3_json