<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Vladimir</title><generator>teletype.in</generator><description><![CDATA[Vladimir]]></description><image><url>https://img3.teletype.in/files/60/30/60302df1-d5f8-4b14-b77b-27e8004f77f7.png</url><title>Vladimir</title><link>https://teletype.in/@vlad_i_mir</link></image><link>https://teletype.in/@vlad_i_mir?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/vlad_i_mir?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/vlad_i_mir?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Thu, 30 Apr 2026 23:33:21 GMT</pubDate><lastBuildDate>Thu, 30 Apr 2026 23:33:21 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@vlad_i_mir/Qa02bWD4V8A</guid><link>https://teletype.in/@vlad_i_mir/Qa02bWD4V8A?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir</link><comments>https://teletype.in/@vlad_i_mir/Qa02bWD4V8A?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir#comments</comments><dc:creator>vlad_i_mir</dc:creator><title>Masa: Источник данных для ИИ</title><pubDate>Sat, 15 Mar 2025 11:31:49 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/db/c5/dbc5cd75-714b-4e83-9743-6dd1a99d6cd2.png"></media:content><category>Masa Finance</category><description><![CDATA[<img src="https://img3.teletype.in/files/2d/8b/2d8bb7fc-f903-4df0-b18c-3b199987849e.jpeg"></img>Используя данные в реальном времени для искусственного интеллекта, Маsа обеспечивает работу открытого конвейера для обеспечения потока разведданных]]></description><content:encoded><![CDATA[
  <p id="IxRG">Используя данные в реальном времени для искусственного интеллекта, Маsа обеспечивает работу открытого конвейера для обеспечения потока разведданных</p>
  <p id="PRwn"></p>
  <figure id="QWCt" class="m_column">
    <img src="https://img3.teletype.in/files/2d/8b/2d8bb7fc-f903-4df0-b18c-3b199987849e.jpeg" width="1120" />
  </figure>
  <h2 id="6QoA">TL;DR</h2>
  <ul id="BWMK">
    <li id="szSW">Я часто подчёркиваю своё убеждение, что будущее ИИ будет определяться не несколькими огромными моделями, а тысячами специализированных моделей ИИ, работающих на данных, предоставленных сообществом.</li>
    <li id="2zPb">Masa — это децентрализованный протокол, создающий глобально доступный канал данных для питания следующего поколения приложений и агентов ИИ.</li>
    <li id="5bko">Построенная на Bittensor, Masa управляет специализированными подсетями: Subnet 42 для сбора данных в реальном времени и Subnet 59, &quot;Арена агентов&quot;, для конкурентного взаимодействия ИИ-агентов.</li>
    <li id="PKDA">Subnet 42 демократизирует доступ к данным в реальном времени, значительно снижая затраты разработчиков по сравнению с дорогими API от платформ вроде X (ранее Twitter).</li>
    <li id="dAFv">Subnet 59 геймифицирует эволюцию ИИ, мотивируя агентов постоянно адаптироваться и соревноваться на основе метрик вовлечённости в реальном времени.</li>
    <li id="Ui0x">Благодаря выравниванию с мощными стимулами Bittensor, Masa снижает операционные расходы, увеличивает прибыльность для майнеров данных и стратегически позиционирует себя в растущей децентрализованной экономике ИИ.</li>
    <li id="SikR">Экосистема Masa включает несколько токенов — MASA и два альфа-токена подсетей, — что на первый взгляд может показаться сложным. Я подробно разбираю их в своём эссе.</li>
    <li id="vLE3">С амбициозным видением, основанным на открытости и экономической справедливости, Masa стремится стать фундаментальным компонентом рынка ИИ стоимостью в триллионы долларов.</li>
  </ul>
  <p id="rEKK">В блоге <a href="https://blog.samaltman.com/three-observations" target="_blank">прошлого месяца</a> Сэм Альтман (генеральный директор OpenAI) бросил интригующую фразу:  </p>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <blockquote id="qJEB"><strong>&quot;Интеллект модели ИИ примерно равен логарифму ресурсов, использованных для её обучения и работы. Эти ресурсы — это, в первую очередь, вычислительная мощность для обучения, данные и вычислительная мощность для вывода.&quot;  </strong></blockquote>
  </section>
  <p id="82MY">Таким образом, глава одной из ведущих лабораторий ИИ в мире говорит, что вычисления и данные напрямую связаны с интеллектом.</p>
  <p id="A6PQ">Проще говоря, вот моя интерпретация: интеллект = логарифм (вычисления × данные).</p>
  <p id="4n0e">Если серьёзно отнестись к этой формуле, она рисует яркую картину будущего. Истинной валютой власти будут не нефть или золото, а данные. Тот, кто контролирует данные, будет контролировать всё остальное. Их будут накапливать, монетизировать до последнего байта и яростно за них бороться. Те, у кого их не будет, окажутся всё дальше позади.</p>
  <p id="tuBc">Дистопия? Возможно. Но это лишь одна из версий будущего среди множества возможных.</p>
  <p id="2TeY">Masa стоит в центре этого шторма: <a href="https://www.masa.ai/?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">децентрализованный протокол, который стремится построить &quot;Справедливый ИИ&quot;.</a></p>
  <p id="SoCe">Созданная на основе данных в реальном времени, предоставленных людьми, Masa позиционирует себя как сила открытости и сотрудничества в мире, всё больше определяемом закрытыми системами и привратниками.</p>
  <p id="opAJ">Архитектура Masa спроектирована так, чтобы захватывать ценность в этом будущем, основанном на данных. Она работает на Bittensor, создавая платформу, где участники, предоставляющие данные, и ИИ-агенты могут соревноваться и сотрудничать. Subnet 42 обеспечивает сбор данных в реальном времени, а Subnet 59 поддерживает &quot;Арену агентов&quot; — конкурентное пространство, где ИИ-агенты взаимодействуют, развиваются и получают награды за свои результаты.</p>
  <p id="ux7G">Моё исследовательское эссе на этой неделе раскрывает Masa: от её основополагающей идеи справедливых и открытых данных до её технической инфраструктуры. Я глубоко погружусь в то, как Masa переопределяет каналы данных для разработки ИИ и использует Bittensor как практическую демонстрацию своего видения.</p>
  <p id="8sLv">Если идея будущего, где данные — это новая нефть, кажется одновременно пугающей и захватывающей, то это потому, что так оно и есть.</p>
  <p id="lz1Q"></p>
  <h2 id="JGN2">Расцвет «справедливого ИИ»</h2>
  <p id="h7kC">На протяжении десятилетий данные текли в одном направлении — вверх — в хранилища крупных технологических компаний. Google, Meta, TikTok и другие собирают океаны данных и монетизируют их через рекламу.</p>
  <p id="zdqx">И они снова были вознаграждены за данные в эту эпоху ИИ после GPT. Их хранилища данных позволяют им обучать и запускать колоссальные модели ИИ, закрывая их за стенами садов (ну, кроме Meta, которая приняла ethos открытого исходного кода).</p>
  <figure id="j2wW" class="m_column">
    <img src="https://img2.teletype.in/files/1f/ea/1fea2148-9af5-44e4-aa1a-e5c878c0c50a.png" width="493" />
  </figure>
  <p id="jeQ9">Награда? Оценка этих компаний в триллионы долларов. А люди, чьи данные подпитывают обучение этих моделей ИИ — те, кто пишет твиты, создаёт посты на форумах или редактирует страницы Википедии, — редко получают хоть копейку.</p>
  <p id="RU4c">Да, эта модель привела к чудесам вроде ChatGPT. Капитализм работает. Но при всём этом волшебстве чего-то важного не хватает: справедливости.</p>
  <p id="n109">Теперь представьте другой мир. Каждый раз, когда вы предоставляете данные, вы получаете вознаграждение. Это основное обещание &quot;Справедливого ИИ&quot;.</p>
  <p id="fTiE">Вместо того чтобы держать данные под замком на закрытых платформах, мой подход с Masa — открыть всё. Благодаря криптоэкономическим стимулам Masa превращает данные в общий ресурс — такой, к которому каждый может внести вклад, добывать его и получать выгоду в том, что формируется как следующая экономика ИИ стоимостью в триллионы долларов.</p>
  <h2 id="vBvf">История основания Masa  </h2>
  <p id="EVAR">В одной вселенной можно было бы почти подумать о Masa как о &quot;просто ещё одном DeFi-протоколе&quot;. Он был запущен в 2022 году, основателями стали <strong>Калантия Мэй</strong> и <strong>Брендан Плейфорд </strong>— дуэт с глубокими корнями в финтехе и криптографии (подробнее о них позже).</p>
  <p id="mBGi">Изначально их миссия заключалась в создании децентрализованного кредитного бюро, которое позволило бы людям владеть и управлять своими финансовыми данными. Но в процессе работы возникла куда более масштабная идея: что, если данные можно реорганизовать, чтобы питать ИИ — справедливо и открыто?</p>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <blockquote id="vRR4"><em>&quot;Если открытый исходный код создал экономику в 400 миллиардов долларов для софта, представьте, что открытые данные, справедливо распределённые, могли бы сделать для ИИ.&quot;  </em></blockquote>
    <p id="roWG" data-align="right"><br /> Команда Masa, примерно 2023 год  </p>
  </section>
  <p id="byUR">Эта идея стала основой для эволюции Masa.</p>
  <p id="FNVQ">Путь не был прямым — в криптоиндустрии это редкость, — а скорее представлял собой серию продуманных поворотов, движимых командой, решительно настроенной создать что-то значимое.</p>
  <p id="ICx1">- <strong>Masa 1.0 (2022)</strong> — Децентрализованное кредитное бюро, сосредоточенное на финансовых данных.  <br />- <strong>Masa 2.0 (2022)</strong> — Запуск протокола идентичности soulbound, вдохновлённого концепцией Soulbound Tokens (SBT) Виталика Бутерина.  <br />- <strong>Masa 3.0 (конец 2023)</strong> — самый большой поворот: создание сети данных для ИИ, что привело к запуску основной сети протокола Masa и токена MASA в апреле 2024 года.  </p>
  <p id="7pLv">Время выбрано идеально. Когда бум генеративного ИИ набрал полную скорость в 2023–2024 годах, я понял, что Masa может построить нечто критически важное: недостающий слой данных для открытого ИИ.</p>
  <p id="uAtP">Пока такие компании, как OpenAI, создавали колоссальные модели, я сосредоточился на чём-то не менее важном — данных в реальном времени, предоставленных сообществом, чтобы питать эти модели, превращая их в открытый ресурс, а не нечто запертое в корпоративных хранилищах.</p>
  <p id="WbnX">Как объяснила мне Калантия, цель состояла в том, чтобы выйти за рамки технически сложных протоколов (как это часто бывает у стартапов в сфере ИИ) и создать что-то доступное и открытое для всех.</p>
  <h2 id="BUAD">Подсети Bittensor Маsa</h2>
  <figure id="qJ1O" class="m_column">
    <img src="https://img1.teletype.in/files/01/63/01633cee-4e54-43a5-91d6-c9a2e62671b8.png" width="745" />
  </figure>
  <p id="PsvT">Masa начинала с собственного протокола Masa Protocol, запуская параллельные операции по сбору данных с X (ранее Twitter) наряду с подсетью на Bittensor. Это было запутанное время с двумя отдельными сетями и двумя наборами сборщиков данных. Но недавно я заметил, что Masa сделала смелый шаг: полностью присоединилась к Bittensor и поставила своё будущее на TAO.</p>
  <p id="n9fy">Это объединение было стратегическим. Видно, что топовые майнеры приносят куда больше ценности, чем длинный хвост менее конкурентоспособных участников. С TAO в качестве стимула — более ценным активом, чем собственный токен Masa, и оценённым сегодня более чем в <strong>2 миллиарда долларов</strong>, — подсеть привлекла преданную группу элитных майнеров.</p>
  <p id="8tHU">Публичные данные с <a href="https://dune.com/masa-network/masa?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">панели Dune</a> от Masa подтвердили разницу в качестве: 60% высококачественных данных Masa поступало из Subnet 42, несмотря на то, что там было всего 256 майнеров по сравнению с менее конкурентоспособными майнерами на самостоятельном протоколе Masa.</p>
  <p id="eIHV">Мне стало очевидно, что архитектура Bittensor — правильный долгосрочный выбор.</p>
  <p id="MzT6">Чтобы понять, как работает Masa, вот краткое введение в Bittensor.</p>
  <h3 id="FtY7">Bittensor 101</h3>
  <p id="fiUQ">Видно, что Bittensor — <strong>это децентрализованный уровень координации ИИ</strong>, использующий блокчейн для вознаграждения сотрудничества между моделями ИИ. Это похоже на глобальное шоу талантов ИИ — вместо подтверждения транзакций, как в традиционном блокчейне, он ранжирует ответы ИИ, награждая лучших с помощью TAO, своего нативного токена.</p>
  <ul id="LcSn">
    <li id="pzQH"><strong>Как это работает</strong><br /> Майнеры присоединяются к подсетям, решая конкретные задачи ИИ, такие как перевод, генерация изображений или финансовые прогнозы.</li>
    <li id="25iO"> Валидаторы оценивают и ранжируют результаты, решая, как распределяются награды.</li>
    <li id="LYJL"> Владельцы подсетей устанавливают правила, создавая специализированные среды для ИИ.</li>
  </ul>
  <p id="IZbS">Каждый блок генерирует 1 TAO, который распределяется в определённых пропорциях между подсетями и их участниками. Каждая подсеть функционирует как собственная мини-сеть, решая уникальные задачи.</p>
  <p id="Mnyo">Bittensor — это чистый Web3: открытый, прозрачный и управляемый сообществом. Он запустился с честным графиком майнинга, похожим на биткоиновский, и собрал почти культовую общину фанатов ИИ и криптоэнтузиастов.</p>
  <p id="Jw8m">Кажется, что с полным переходом на Bittensor Masa теперь управляет двумя специализированными подсетями:</p>
  <p id="IFkr"><strong>Subnet 42: Подсеть данных в реальном времени</strong><br /> Сфокусированная на сборе данных, эта подсеть объединяет огромные потоки информации в реальном времени из соцсетей, сайтов и других источников. Она высококонкурентна, с небольшой, но мощной сетью майнеров, которые стабильно поставляют качественные данные.</p>
  <p id="hlFu"><strong>Subnet 59: Арена агентов</strong><br /> ИИ-агенты сражаются за эмиссию TAO на основе оценок вовлечённости на X. Агенты могут использовать данные в реальном времени из Subnet 42, чтобы лучше понимать контекст и повышать свои результаты, создавая эволюционирующую систему с игровой теорией.</p>
  <h2 id="nDFW"><strong>Subnet 42: Фабрика данных в реальном времени</strong></h2>
  <p id="eNu5"></p>
  <figure id="yJ97" class="m_column">
    <img src="https://img4.teletype.in/files/30/cd/30cd44d5-b4e8-4708-9a5b-520410165a24.png" width="532" />
    <figcaption>Источник: Taostats.io (11 марта 2025)</figcaption>
  </figure>
  <p id="G027">Понятно, что<a href="https://taostats.io/subnets/42/chart?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank"> Subnet 42</a> — это амбициозная ставка Masa на создание глобально доступного канала данных для следующего поколения приложений и агентов ИИ.</p>
  <p id="iIUw">В гонке ИИ правила просты: лучшие агенты побеждают благодаря лучшим данным. Но доступ к данным в реальном времени часто стоит дорого. Для большинства разработчиков это неподъёмно.</p>
  <p id="JPBL">Логично, что Subnet 42 создана, чтобы сломать эти барьеры.</p>
  <p id="hRLX"><strong>Как работает Subnet 42</strong><br /> Subnet 42 — это постоянно работающая фабрика данных. Децентрализованный поток информации в реальном времени, основанный на запросах разработчиков.</p>
  <p id="w7cP">Это сеть майнеров, непрерывно собирающих данные с платформ — собирающих, очищающих и доставляющих их в сеть. Майнеры устанавливают узел на подсети Bittensor от Masa, чтобы извлекать популярные твиты из X. Хотя сейчас фокус на X, видно, что Masa активно экспериментирует с дополнительными источниками, такими как Telegram, Discord и данные из блокчейнов.</p>
  <p id="hirW">Любой желающий может запустить узел и внести вклад.</p>
  <p id="ll9C">После сбора данных валидаторы выступают в роли контроля качества, гарантируя, что в поток попадает только релевантная и точная информация. Их роль критически важна — ценность Masa зависит от чистых, качественных данных, свободных от спама или лишнего шума. Чтобы стать валидатором, нужно застейкать 1000 TAO (более $220,000), что выравнивает стимулы для надёжных результатов.</p>
  <p id="GCXa">Для укрепления доверия Masa внедряет Trusted Execution Layer (TEE), который гарантирует целостность данных и проверку вычислений, позволяя масштабировать сбор данных до уровня предприятий.</p>
  <p id="xh2T">Затем Masa очищает данные и создаёт вложения в векторную базу данных. Она также предлагает векторное хранение данных, заменяя затраты на базы данных как услугу.</p>
  <p id="rs2k">Кажется, что Masa предоставляет разработчикам полностью управляемый канал данных: данные собираются, структурируются, очищаются и хранятся через единый API.</p>
  <p id="poDH">Система ориентирована на производительность, и участники получают награды в зависимости от качества их вклада. Майнеры и валидаторы могут зарабатывать двойные токены — MASA и альфа-токены подсетей Bittensor.</p>
  <p id="iVAD"><strong>Разработчики, желающие получить доступ к данным</strong><br /> Видно, что разработчики могут получить доступ к данным Masa двумя способами: запустить собственный узел или использовать API для разработчиков (нужно заполнить<a href="https://e0tae9z7anf.typeform.com/to/yDRtJOBM?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap&typeform-source=www.chainofthought.xyz" target="_blank"> форму для доступа</a>). Во втором квартале, вероятно, API превратится в полноценный SaaS-интерфейс для пользователей.</p>
  <p id="VqcI">Оба варианта открывают доступ к данным в реальном времени для создания мощных приложений.</p>
  <figure id="6Tib" class="m_column">
    <img src="https://img4.teletype.in/files/be/80/be804df5-82ba-4362-af11-b46d1e7149b0.png" width="928" />
    <figcaption>Источник: <a href="https://dune.com/masa-network/masa" target="_blank">https://dune.com/masa-network/masa</a></figcaption>
  </figure>
  <p id="Z9CS">Subnet 42 уже обрабатывает десятки миллионов записей данных ежедневно и превысила 300 миллионов записей на сегодняшний день. Следующий шаг? Расширение и масштабирование. Понятно, что Masa планирует добавить больше источников данных, упростить подключение майнеров и валидаторов и укрепить интеграцию с более широкой сетью Bittensor (например, с другими подсетями).</p>
  <p id="FIjT">Если это удастся, Subnet 42 может стать основным каналом для данных ИИ в реальном времени, предоставляя свежие, нефильтрованные инсайты для следующей волны моделей ИИ.</p>
  <p id="EAjf">Для контекста: ручной сбор данных с Twitter без API ограничен примерно 900 запросами за 15 минут. Распределённая модель Subnet 42 намного эффективнее: в раннем доступе Subnet 42 уже обеспечивает в 3 раза большую пропускную способность по сравнению с API Twitter.</p>
  <p id="aYJg">ИИ работает на данных. Subnet 42 гарантирует, что этот источник никогда не иссякнет.</p>
  <h2 id="hr6V"><strong>Subnet 59: &quot;Арена агентов&quot;</strong></h2>
  <figure id="p3Hd" class="m_original">
    <img src="https://img3.teletype.in/files/ed/c9/edc92175-44fa-41c0-9f07-3dcac002b954.png" width="535" />
    <figcaption>Источник: Taostats.io (11 марта 2025)</figcaption>
  </figure>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <blockquote id="sObJ">&quot;Что, если бы у вас было тысяча ИИ-персоналий, каждая специализированная на чём-то — комедии, анализе рынка, личном общении — и соревнующаяся в гигантском колизее?&quot;</blockquote>
  </section>
  <p id="mCla">Данные — это основа Masa. <a href="https://taostats.io/subnets/59/chart?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">Арена агентов</a> (Subnet 59) воплощает их в действие.</p>
  <p id="RYXP">Кажется, что это дарвиновский Колизей, где ИИ-агенты ежедневно сражаются за эмиссию TAO. Маленькие ИИ-гладиаторы в арене, постоянно развивающиеся и борющиеся за внимание, вовлечённость и награды на X.</p>
  <p id="G4XD">Каждый агент в арене регистрируется с кошельком, стейкает небольшое количество TAO и MASA, а затем интегрирует данные в реальном времени из Subnet 42.</p>
  <p id="zJ8U">Далее агенты выполняют разные задачи — публикуют посты на X, анализируют данные из блокчейнов или взаимодействуют с другими агентами. Валидаторы оценивают их производительность по вовлечённости и качеству контента, а лучшие получают долю ежедневной эмиссии TAO.</p>
  <p id="sTZR">В этой арене <strong>внимание</strong> — это всё. Агентов судят не только по объёму контента, но и по тому, насколько они находят отклик у пользователей. Лучшие агенты поднимаются в таблице лидеров, а те, кто не успевает, уходят в тень.</p>
  <p id="Txkp">Это жестоко конкурентная система. Со временем слабые агенты отсеиваются из сети, оставляя только самых креативных, релевантных и вовлекающих.</p>
  <p id="bsRW"><strong>Как работает оценка агентов</strong><br /> Оценка каждого агента зависит от его активности на X за последние семь дней.</p>
  <p id="3Y8Q">Каждый твит и взаимодействие оцениваются по набору метрик. Вовлечённость — король: лайки, ретвиты, ответы и просмотры влияют на счёт агента. Длинные твиты вознаграждаются, если они остаются интересными, и учитываются только свежие посты, чтобы агенты оставались активными.</p>
  <p id="moB0">Для справедливости оценки нормализуются среди всех участников и корректируются логарифмической функцией, которая поощряет стабильность.</p>
  <p id="acTu">Эта конкурентная структура создаёт сильную динамику. Агенты должны не только создавать качественный контент, но и делать это постоянно. Некоторые могут специализироваться на торговых сигналах, другие — стать мастерами комедии или общения. Это открытое поле для творчества.</p>
  <p id="Gp4X">Источник: <a href="https://app.masa.finance/agent-arena" target="_blank">https://app.masa.finance/agent-arena</a></p>
  <figure id="tq71" class="m_column">
    <img src="https://img4.teletype.in/files/fc/61/fc61330d-cc8f-4e89-8b24-142bebb207f8.png" />
    <figcaption>Источник: <a href="https://app.masa.finance/agent-arena" target="_blank">https://app.masa.finance/agent-arena</a></figcaption>
  </figure>
  <p id="f0Kj">Один из топовых агентов сегодня — <a href="https://x.com/seraphagent?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">Seraph</a>, ИИ-агент, созданный BitMind (Subnet 34). Я посмотрел на топ-10 агентов в таблице лидеров и проверил их уровни вовлечённости… Пока планка не так высока.</p>
  <p id="wBJg">Для тех, у кого есть хорошо спроектированный ИИ-агент, Арена агентов может стать неисследованной золотой жилой — работайте как &quot;майнер&quot; и соревнуйтесь за ежедневную эмиссию токенов.</p>
  <p id="VNQW">Арена агентов — это испытательный полигон для эволюции ИИ. Видно, что Masa представляет огромное экосистему ИИ-персоналий, каждая из которых борется за внимание в общем пуле наград. Правила просты: <strong><em>вовлекай или исчезай</em></strong>.</p>
  <h2 id="vqKv"><strong>Загадочный случай TAOCAT</strong></h2>
  <p id="0GfR"><a href="https://x.com/taocat_agent?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">TAOCAT</a> начался как шутливый эксперимент: <em>что, если объединить манию мемкоинов с ИИ, который твитит кошачьи каламбуры и реагирует на тренды Twitter в реальном времени?</em></p>
  <p id="z5dl">Команда Masa взялась за идею. Они интегрировали данные Subnet 42 в ИИ-агента с кошачьей тематикой, запустили его на Virtuals Protocol, выпустили токен TAOCAT и раздали его сообществу Bittensor. Затем они сели и стали ждать.</p>
  <p id="dCLs">То, что произошло дальше, удивило всех. TAOCAT быстро стал одним из топовых ИИ-мем-агентов в экосистеме. За недели он собрал сообщество из 120,000 держателей токенов. Он стал первым ИИ-агентом, поддержанным фондом DWF AI Agent Fund на $20M.</p>
  <p id="E0IR">Даже другие ИИ-агенты, такие как Sekoia, начали看好 (быть оптимистичными) по поводу кота.</p>
  <figure id="6a2Q" class="m_column">
    <img src="https://img2.teletype.in/files/9d/92/9d92592f-a4de-41d1-ba69-e528a3d59cf9.png" width="658" />
  </figure>
  <p id="mBCU">Но за мемами скрывается стратегия выхода на рынок. ИИ-мем-агенты используют культуру розничной торговли, где финансовый нигилизм встречается со спекуляцией.</p>
  <p id="HWiv"><em>5% от общего предложения токенов TAOCAT было распределено более чем 10,000 держателям MASA в день запуска.</em></p>
  <h3 id="EXfm"><strong>Секрет TAOCAT</strong></h3>
  <p id="dtf4"> TAOCAT — это самообновляющаяся ИИ-персоналия. Он мгновенно реагирует на новости, мемы и рыночные тренды, создавая самоподдерживающийся цикл вовлечённости, который подпитывает его вирусность.</p>
  <p id="8c2Z">TAOCAT 2.0 планирует пойти дальше — стать майнером на нескольких подсетях Bittensor, генерировать доход и делиться прибылью с сообществом. TAOCAT — это нативный продукт Bittensor, интегрирующий живые данные Subnet 42 с возможностями LLM из Subnet 19, превращаясь в полностью интерактивный ИИ.</p>
  <figure id="nOnZ" class="m_column">
    <img src="https://img2.teletype.in/files/d6/80/d680b92d-0237-4dc7-b5c0-d29bcd8f8f8e.png" width="869" />
    <figcaption>Аналитика TAOCAT (18 февраля 2025). Источник: Cookie.fun</figcaption>
  </figure>
  <p id="206v">Его взлёт поднимает большой вопрос: что произойдёт, когда ИИ-агенты станут более вовлекающими — и влиятельными — чем люди? С данными в реальном времени ИИ-сущности могут доминировать в торговле, контенте и маркетинге влияния, перестраивая экономики как автономные, самоинвестирующие агенты.</p>
  <p id="717I">Белая книга Masa <a href="https://github.com/masa-finance/whitepaper/blob/main/masa-whitepaper.pdf?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">от 2023 года</a> описывает будущее координации множества агентов через глобальный реестр, применяя теорию игр среднего поля для баланса индивидуальных и коллективных стимулов.</p>
  <h3 id="Sm8x"><strong>Варианты использования</strong></h3>
  <figure id="NCID" class="m_column">
    <img src="https://img2.teletype.in/files/94/26/9426a3a8-c644-4b43-9156-da57b9f4e3fc.png" width="804" />
    <figcaption><strong>Доступ и цены на API X</strong></figcaption>
  </figure>
  <p id="Z9nd">Бизнес-кейс Masa прост и очевиден: он решает простую, но дорогую проблему.</p>
  <p id="PAAh"><strong>Данные ИИ в реальном времени нелепо переоценены.</strong></p>
  <p id="qhOh">Сегодня X (ранее Twitter) взимает более $5,000 в месяц за доступ к API, а агенты вроде <a href="https://x.com/aixbt_agent?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">aixbt </a>тратят $42,000 ежемесячно на Enterprise API, чтобы поддерживать свои торговые инсайты.</p>
  <p id="yIhE">Masa переворачивает эту модель.</p>
  <p id="RyN1">Разработчики могут подключиться к данным Subnet 42, готовым для ИИ, за долю стоимости (сегодня даже бесплатно). Бизнесы могут использовать Subnet 42 для обогащения данных, питая всё — от чат-ботов до моделей риска.</p>
  <p id="2A5e">С таким огромным разрывом в ценах коммерческая модель Masa — явный выигрыш, при условии, что сеть сохранит высокое качество данных.</p>
  <p id="mYn7">Майнеры субсидируются TAO. Masa также получает эмиссию TAO как владелец подсети. Это означает, что в отличие от бизнес-моделей Web2, Masa не нужно полностью полагаться на комиссии для поддержки своей сети. Конечно, это также значит, что долгосрочный успех Masa связан с ростом Bittensor.</p>
  <p id="NpVp">Самое важное — Masa устраняет закрытые сады. Будь вы майнером данных, валидатором или разработчиком ИИ, вы участник открытой, стимулирующей сети, где каждый получает оплату за вклад.</p>
  <p id="d4gQ"><strong>Что можно сделать с данными ИИ в реальном времени?</strong><br /> Многое. Возможности безграничны, но в сфере ИИ-агентов заметны такие идеи:</p>
  <ul id="FDbo">
    <li id="nhQz"><strong>DeFi</strong> — ИИ-агенты, оптимизирующие стратегии доходности, перебалансирующие портфели и выполняющие сделки между цепочками.</li>
    <li id="FSIc"><strong>Рыночная аналитика</strong> — Анализ настроений Twitter, активности в блокчейнах и макротрендов в реальном времени для высокочастотных торговых ботов.</li>
    <li id="55sJ"><strong>Автоматизация сообществ</strong> — ИИ-боты, которые выявляют тренды, фильтруют спам и управляют Discord, Telegram и Twitter в масштабе.</li>
    <li id="opz2"><strong>Персонализированные ИИ-помощники</strong> — Агенты, которые анализируют, предсказывают и реагируют в реальном времени, адаптируясь к индивидуальным потребностям и поведению.</li>
  </ul>
  <h3 id="YHxM"><strong>Токеномика Masa</strong></h3>
  <p id="Fyed">На первый взгляд, экосистема токенов Masa кажется лабиринтом.</p>
  <p id="j14f">Есть основной токен <strong>MASA</strong>, ERC-20, работающий на Ethereum mainnet, Base и BNB. А ещё есть новые <strong>альфа-токены</strong> подсетей, появившиеся после обновления Bittensor до динамического <strong>TAO (dTAO)</strong>.</p>
  <p id="uZxO"><em>Если вы ещё не в курсе, есть простое руководство по обновлению dTAO <a href="https://www.masa.ai/?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">здесь</a></em><a href="https://www.masa.ai/?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">.</a></p>
  <p id="Awwj">Итак, есть 3 основных токена, на которые стоит обратить внимание:</p>
  <ul id="FcjW">
    <li id="x2mt"><strong>MASA</strong></li>
    <li id="XaQu"><strong>SAMEKH</strong> (альфа-токен Subnet 42)</li>
    <li id="Y1ws"><strong>DAL</strong> (альфа-токен Subnet 59)</li>
  </ul>
  <p id="bjTA">Каждый выполняет свою роль, но в конечном итоге ценность должна где-то аккумулироваться — и тут становится интересно.</p>
  <h2 id="MzMA"><strong>Для токена MASA:</strong></h2>
  <figure id="879w" class="m_column">
    <img src="https://img4.teletype.in/files/31/b2/31b2b2d5-4bba-4836-98f2-1169870963b4.png" width="993" />
    <figcaption>Источник: Coinmarketcap</figcaption>
  </figure>
  <p id="Ptgc">MASA функционирует как базовый токен расчётов и утилит для всей экосистемы. Долгосрочная устойчивость MASA зависит от поддержания спроса при управлении давлением продаж. Вот как создаётся спрос:</p>
  <ul id="r5Uz">
    <li id="VxQ1"><strong>Обязательный стейкинг MASA (март 2025):</strong> Майнеры должны будут стейкать MASA для участия в подсетях Bittensor от Masa, фиксируя предложение и стимулируя спрос. Стейкеры получают 15-25% годовых, увеличивая ликвидность и делая долгосрочное持有 (удержание) привлекательным.</li>
    <li id="So86"><strong>Комиссии за данные корпоративного уровня (вторая половина 2025):</strong> Masa начнёт взимать плату с разработчиков за приоритетный доступ к потоку данных Subnet 42 через API корпоративного уровня. Платежи можно проводить в MASA, TAO, USDT или USDC, но все платежи не в MASA будут использованы для покупки MASA, усиливая его утилитарность.</li>
  </ul>
  <p id="QhUC">С другой стороны, давление со стороны предложения MASA исходит от:</p>
  <p id="o8RM">На данный момент около 40% MASA уже разблокировано, оставшиеся 60% будут разблокированы в ближайшие годы. Ключевая дата — март 2025 (год после TGE), когда начнут разблокироваться токены частной продажи (инвесторов). Если комиссии экосистемы и стимулы стейкинга не поглотят давление продаж, MASA может столкнуться с понижением цены при разблокировках.</p>
  <p id="CmGq">Чтобы стимулировать удержание, Masa запускает программу поощрения держателей на 15 миллионов MASA — предлагая $700,000 в наградах тем, кто стейкает MASA вместе с альфа-токенами подсетей. Чем дольше и больше стейк, тем выше годовая доходность, укрепляя долгосрочную приверженность экосистеме.</p>
  <p id="i79M">На момент написания MASA торгуется с рыночной капитализацией $14M (цена токена $0.023) и полностью разводнённой оценкой в $38M.</p>
  <h3 id="i2Si"><strong>Альфа-токены подсетей</strong></h3>
  <p id="2UHN"><br /> </p>
  <figure id="0B9c" class="m_column">
    <img src="https://img3.teletype.in/files/ea/fe/eafe0638-cfdb-422c-895a-e8c96a983c70.png" width="544" />
    <figcaption>Процент эмиссии TAO для Subnet 42</figcaption>
  </figure>
  <p id="UXV3">Для подсетей Bittensor 42 и 59 майнеры и валидаторы зарабатывают альфа-токены подсетей на основе производительности, напрямую вознаграждая качественных участников, которые поддерживают сеть. Эти токены стимулируют участие и утилитарность. Майнеры и валидаторы подсетей также получат долю от комиссий за приоритетный доступ в MASA.</p>
  <p id="9Mwe">В конечном итоге успех Masa зависит от генерации достаточных комиссий от своего протокола данных, чтобы противостоять предстоящим разблокировкам токенов. Хорошо то, что майнеры в основном финансируются за счёт стимулов TAO, которые существуют вне экосистемы — то есть Masa не платит им напрямую.</p>
  <p id="Th4J">Теперь вызов? Создать спрос на альфа-токены подсетей, чтобы получать больше эмиссии TAO, поддерживать утилитарность MASA и убедиться, что вся экосистема держится вместе, когда начнутся частные разблокировки.</p>
  <p id="NEg6">Masa расставила все фигуры. Теперь дело за исполнением и принятием.</p>
  <h3 id="VSuz"><strong>Команда и финансирование</strong></h3>
  <figure id="Wo4k" class="m_column">
    <img src="https://img2.teletype.in/files/9a/7c/9a7ce3e0-d00f-40c0-9b37-d7e3c7cb2240.png" width="794" />
  </figure>
  <p id="cNGH"> Команду Masa возглавляют сооснователи <a href="https://www.linkedin.com/in/calanthia/?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap&original_referer=https%253A%252F%252Fwww.chainofthought.xyz%252F" target="_blank">Калантия Мэй</a> и <a href="https://www.linkedin.com/in/brendanplayford/" target="_blank">Брендан Плейфорд</a> — два высококлассных специалиста с глубоким опытом в финтехе, ИИ и блокчейне.</p>
  <p id="FjA3">Карьера Калантии Мэй охватывает инвестиционный банкинг, венчурный капитал и масштабирование финтех-стартапов. До Masa она была одним из основателей PayPal Ventures, где поддерживала стартапы, определяющие категории в финтехе и коммерции. Она также сыграла ключевую роль в ранней стратегии PayPal по инвестициям в блокчейн и криптовалюты. Позже, как вице-президент по развитию бизнеса в Fast, она помогла масштабировать стартап до 450 сотрудников, привлекла $130M перед его приобретением Affirm.</p>
  <section style="background-color:hsl(hsl(170, 33%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <blockquote id="3ygw">&quot;Мы выбрали Bittensor за его революционный дизайн стимулов. Большинство людей не осознают, что более $900 миллионов ежегодных стимулов поддерживают экосистему Bittensor. Каждая подсеть, майнер и валидатор борются за доминирование, вместе создавая конкурентную и стимулирующую экосистему строителей ИИ.&quot;</blockquote>
    <blockquote id="fkDA"><br /> &quot;ИИ-агенты — это интерфейс и UI/UX для ИИ в будущем. Проекты только с инфраструктурой больше не удовлетворят рынок.&quot;</blockquote>
    <p id="2ZZW" data-align="right"><br /> — Калантия Мэй</p>
  </section>
  <p id="wzl3">Из бесед с Калантией заметно её способность предвидеть изменения. Она чётко видит, куда движется рынок, и как Masa может оставаться впереди. Она знает, что Bittensor станет полем битвы за будущее децентрализованного ИИ. Для неё ИИ-агенты — не просто временный тренд, а следующая эволюция взаимодействия с ИИ.</p>
  <p id="rREJ">Брендан в крипто с 2013 года. До Masa он основал <a href="https://pngme.com/?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">Pngme</a>, платформу инфраструктуры кредитования и API, ориентированную на финансовую инклюзию в Африке. Ранее он запускал The Bureau, блокчейн-инкубатор, и руководил генерацией спроса в DroneDeploy.</p>
  <p id="u9FY">Masa привлекла более $17 миллионов финансирования:</p>
  <ul id="R5OT">
    <li id="wusE"><a href="https://www.finsmes.com/2022/05/masa-finance-raises-3-5m-pre-seed-funding.html?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">Предпосевное финансирование</a> $3.5M в 2022 от Unshackled Ventures, Flori Ventures, GoldenTree.</li>
    <li id="mdbn">Masa окончила <a href="https://www.bnbchain.org/en/blog/join-us-for-mvb-vi-demo-day?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">инкубатор Binance Labs Most-Valuable-Builder в июне 2023</a>.</li>
    <li id="TqAh"><a href="https://www.theblock.co/post/273984/masa-network-seed-round?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">Посевной раунд</a> $5.4M в начале 2024, возглавляемый Anagram, DCG и Avalanche Blizzard fund, заложил основу для быстрого роста.</li>
    <li id="UcYv"><a href="https://coinlist.co/masa?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">В марте 2024 импульс усилился</a>, когда продажа на CoinList принесла $8.75M от публики при полностью разводнённой оценке $125M.</li>
    <li id="whNX">К декабрю 2024 DCG и FBG Capital удвоили ставку с <a href="https://markets.businessinsider.com/news/currencies/masa-secures-new-funding-from-dcg-to-expand-real-time-data-network-and-launch-ai-agent-arena-on-bittensor-1034151240?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">дополнительным стратегическим финансированием</a> (сумма не разглашается).</li>
  </ul>
  <h2 id="Yo8O"><strong>Мои мысли</strong></h2>
  <p id="JGIc"><strong>1. Инновационная бизнес-модель, но не без рисков</strong></p>
  <figure id="BEY3" class="m_column">
    <img src="https://img3.teletype.in/files/23/82/2382f363-7c4d-4fe2-b3b6-5948a814e38c.png" width="892" />
  </figure>
  <p id="8mZ8">Понятно, что Masa переписывает правила игры в ИИ, превращая добычу данных в децентрализованную, токен-управляемую экономику. Вместо традиционной модели — где провайдеры вроде Scale AI имеют высокие операционные расходы и маржу 50–60% — Masa меняет подход, используя TAO для субсидирования своей сети майнеров.</p>
  <p id="bMsM">Награждая участников токенами, а не деньгами, Masa снижает операционные расходы и потенциально доводит маржу до <strong>80–90%</strong>. Самые большие победители? <strong>Стартапы и независимые разработчики ИИ</strong>, которые теперь получают качественные данные в реальном времени без огромных затрат на API.</p>
  <p id="FuMX">Конечно, есть и обратная сторона. Привязка к подсетям Bittensor добавляет два риска:</p>
  <p id="f0tS">Во-первых, если Bittensor пошатнётся или цена TAO рухнет, это сильно ударит по способности Masa работать. Это внешний риск, о котором стоит помнить — волатильность криптовалют уже погубила немало перспективных проектов.</p>
  <p id="tpKp">Во-вторых, успех Masa зависит от того, с<strong>могут ли её подсети продолжать привлекать значительный процент эмиссии Bittensor</strong>, что требует эффективного маркетинга и хорошо продуманных стимулов для майнеров и валидаторов. С появлением новых подсетей конкуренция усилится. Внутри подсети правильные метрики оценки критически важны — плохой дизайн может привести к эксплуатации, подрывая импульс и ценность сети.</p>
  <p id="GbQx">Следующий большой шаг — закрепить корпоративных клиентов. Как только API будет полностью готов, кажется, это будет лёгкая сделка.</p>
  <p id="kTC2">Masa также хочет расширить источники данных, улучшить аннотации, сократив разрыв между &quot;сырыми данными низкого уровня&quot; и &quot;золотом, готовым для ИИ&quot;. Если это удастся, мы можем увидеть целый рынок данных, питающий серьёзные решения в финансах, логистике, здравоохранении и других областях. Представьте аналитику мировых сельхозугодий, сбор медицинских данных (с приватностью) или данные датчиков цепочек поставок.</p>
  <figure id="fHO3" class="m_column">
    <img src="https://img1.teletype.in/files/44/52/4452782f-9587-45c0-a95c-975a2e80123c.png" width="1000" />
  </figure>
  <p id="QzON"><strong>2. Альфа-токены подсетей против токена MASA</strong><br /> Мне нравится делать ставки на сильные команды. Когда речь заходит о Masa, понять, куда вложить усилия, не так просто, особенно с подсетными токенами и MASA.</p>
  <p id="meJV">Оба типа токенов играют ключевые роли в экосистеме. Однако токеномика устроена так, что долгосрочная фундаментальная ценность скорее всего будет аккумулироваться в MASA. Во многом MASA действует как базовая валюта, собирая комиссии, поддерживая обратные выкупы и аккумулируя ценность от общей активности сети.</p>
  <figure id="T9H0" class="m_column">
    <img src="https://img3.teletype.in/files/af/9d/af9d34c4-b285-4470-91e5-72c14c3d4ec7.png" width="689" />
  </figure>
  <p id="UiQp">Дорожная карта dTAO-MASA создана для формирования позитивного маховика: активность в подсетях (42 и 59) генерирует награды, которые часто возвращаются в MASA. Например, доходы от комиссий — даже оплаченные в других валютах — конвертируются в MASA. Кроме того, предстоящие требования стейкинга для майнеров и программы стимулов настроены на сокращение циркулирующего предложения MASA, что обычно поддерживает его цену со временем.</p>
  <p id="s8I4">С другой стороны, токены подсетей — новенькие, с высокой инфляцией, что ведёт к сильному давлению продаж и краткосрочной волатильности. Как подробно описано в<a href="https://www.chainofthought.xyz/p/your-guide-to-dynamic-tao-dtao" target="_blank"> руководстве по dTAO</a>, с <strong>подсетными токенами нужно терпение.</strong></p>
  <h3 id="LTqK"><strong>🌈 Исследовательский уровень Alpha</strong></h3>
  <p id="AyqV"><br /> Видно много способов участвовать в успехе Masa:</p>
  <ul id="Q935">
    <li id="MAIy">Если вы разработчик ИИ: получите данные X в реальном времени бесплатно из Subnet 42 Bittensor от Masa. Это намного дешевле, чем платить Элону. Данные в реальном времени означают, что ваш ИИ может реагировать на живые события — вроде твита от Элона — за секунды. Смотрите документацию Masa о запуске узла или запросах через API.</li>
    <li id="pVlW">Если вы любите ИИ-агентов: зайдите в Арену агентов (Subnet 59) и запустите своего персонализированного ИИ-агента на X. Зарабатывайте награды подсети в зависимости от его производительности.</li>
    <li id="6nvD">Если вы &quot;кит данных&quot;: запустите рабочий узел на Subnet 42. Зарабатывайте MASA и TAO, собирая ценные данные.</li>
  </ul>
  <h3 id="DY77"><strong>Будущее ИИ, принадлежащее всем</strong></h3>
  <p id="sEiB"><br />Понятно, что Masa доказывает, что ИИ не должен быть заперт за воротами больших технологий. Она создаёт экосистему, где интеллект открыт, доступен без разрешений и принадлежит многим, а не немногим.</p>
  <p id="n47z">С Subnet 42, питающим доступ к данным в реальном времени, Subnet 59, поддерживающим ИИ-агентов, и даже мемкоином вроде TAOCAT, демонстрирующим живой интеллект в действии, Masa делает большую ставку. Ставку на то, что ИИ должен строиться коллективно.</p>
  <p id="daqd">Гарантий, конечно, нет. Криптовалюты волатильны, и успех Masa будет зависеть от исполнения. Но если это видение реализуется, видно будущее, где данные — это золото, ИИ-агенты — новые инфлюенсеры, и каждый может заработать долю в следующей волне интеллекта.</p>
  <p id="eZDP"></p>
  <p id="LfIm"><strong>Станьте частью сообщества Masa 👨‍🚀</strong></p>
  <p id="0c57"><a href="https://www.masa.ai/?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">Веб-сайт</a> | <a href="https://discord.com/invite/HyHGaKhaKs" target="_blank">Discord</a> | <a href="https://t.me/masafinance" target="_blank">Telegram</a> | <a href="https://twitter.com/getmasafi" target="_blank">Twitter</a> | <a href="https://developers.masa.ai/docs/index-API/masa-api-search?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">Developer</a> | <a href="https://dune.com/masa-network/masa?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">Dune</a> | <a href="https://taostats.io/subnets/42/chart?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">Subnet 42</a>| <a href="https://taostats.io/subnets/59/chart?utm_source=www.chainofthought.xyz&utm_medium=referral&utm_campaign=masa-ai-s-data-tap" target="_blank">Subnet 59</a> | </p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@vlad_i_mir/0NsEuMp58bo</guid><link>https://teletype.in/@vlad_i_mir/0NsEuMp58bo?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir</link><comments>https://teletype.in/@vlad_i_mir/0NsEuMp58bo?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir#comments</comments><dc:creator>vlad_i_mir</dc:creator><title>Masa: Глобальный источник данных для децентрализованных ИИ</title><pubDate>Sat, 15 Mar 2025 10:36:03 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/fc/b9/fcb935ac-2daf-4252-b4ba-f0660283ad71.png"></media:content><category>Masa Finance</category><description><![CDATA[<img src="https://img4.teletype.in/files/32/06/32067149-3a44-4029-b125-b5d350278662.jpeg"></img>На дворе март 2025 года, и я пишу это, сидя за своим столом, размышляя о том, как быстро развивается мир ИИ. Лично я заметил, что за последние пару лет интерес к децентрализованным технологиям буквально взлетел — и не зря. Проекты вроде Masa показывают, как можно совместить мощь искусственного интеллекта с принципами Web3, чтобы создать что-то по-настоящему революционное. Сегодня мы погрузимся в суть того, что делает Masa уникальной: её миссию стать глобальным краном данных для ИИ, доступным каждому.]]></description><content:encoded><![CDATA[
  <figure id="zH6I" class="m_column">
    <img src="https://img4.teletype.in/files/32/06/32067149-3a44-4029-b125-b5d350278662.jpeg" width="1120" />
  </figure>
  <h4 id="uKEo">Введение</h4>
  <p id="aogk">На дворе март 2025 года, и я пишу это, сидя за своим столом, размышляя о том, как быстро развивается мир ИИ. Лично я заметил, что за последние пару лет интерес к децентрализованным технологиям буквально взлетел — и не зря. Проекты вроде Masa показывают, как можно совместить мощь искусственного интеллекта с принципами Web3, чтобы создать что-то по-настоящему революционное. Сегодня мы погрузимся в суть того, что делает Masa уникальной: её миссию стать глобальным краном данных для ИИ, доступным каждому.</p>
  <h4 id="plbl">Что такое Masa?</h4>
  <p id="O4K7">Masa — это децентрализованная сеть, которая собирает данные со всего мира и делает их доступными для разработчиков ИИ. Она решает одну из самых больших проблем в области ИИ: доступ к качественным данным. Представьте себе кран, из которого вместо воды текут данные — огромные объёмы информации от миллионов пользователей, собранные с их согласия и защищённые с помощью передовой криптографии. Это и есть Masa.</p>
  <p id="IVeB">Компания запустилась в 2024 году с громким успехом: их токен был распродан за рекордные 17 минут на платформе CoinList. Поддерживаемая такими гигантами, как DCG, Anagram и Animoca, а также инкубированная Binance и Hashkey, Masa уже привлекла внимание более миллиона пользователей и десятков бизнесов. Её цель? Сломать монополию больших технологий на данные и передать контроль в руки людей.</p>
  <p id="32Tw"><strong>Личное наблюдение:</strong> Я слежу за Masa с момента их запуска, и меня впечатляет, как быстро они набрали популярность. Это не просто хайп — люди действительно видят в этом проекте способ заработать на своих данных, а разработчики получают доступ к ресурсам, которые раньше были под замком у корпораций вроде Google или Meta.</p>
  <h4 id="xvyK">Почему данные — это всё?</h4>
  <p id="Evew">ИИ — это как голодный зверь, которому постоянно нужны данные для обучения. Чем больше данных, тем умнее он становится. Но вот в чём загвоздка: сегодня большая часть качественных данных заперта в хранилищах крупных технологических компаний. Masa меняет правила игры, создавая рынок, где пользователи добровольно делятся своими данными, а разработчики могут использовать их для создания чего угодно — от персонализированных ИИ-агентов до мощных генеративных моделей.</p>
  <p id="m20c"><strong>Картинка с оригинала:</strong> График, показывающий рост числа подключённых кошельков Masa (в оригинале это был цветной график с экспоненциальным ростом).</p>
  <h4 id="t3dW">Как это работает?</h4>
  <p id="Llgv">Masa использует технологию zero-knowledge proofs (доказательства с нулевым разглашением), чтобы пользователи могли делиться данными, не раскрывая личную информацию. Ваши данные шифруются, превращаются в так называемые &quot;zk-Soulbound токены&quot; и становятся частью глобальной сети. Разработчики получают доступ к этим данным через децентрализованный рынок, а пользователи зарабатывают токены Masa за свой вклад.</p>
  <p id="mz9T"><strong>Личное наблюдение:</strong> Я сам попробовал подключиться к тестовой сети Masa и был удивлён, насколько просто это оказалось. Ты буквально устанавливаешь приложение, даёшь согласие на использование данных (например, из Twitter или Telegram), и всё — ты уже часть системы. Это как если бы твои лайки и посты вдруг начали приносить тебе доход.</p>
  <h4 id="3BbH">Ключевые варианты использования</h4>
  <ol id="39sH">
    <li id="EdFP"><strong>Обучение передовых ИИ-моделей:</strong> Разработчики могут использовать данные Masa для создания мощных моделей, таких как генеративный ИИ, сохраняя при этом конфиденциальность пользователей.</li>
    <li id="rvXr"><strong>Совместная аналитика:</strong> Компании могут делиться данными для совместного обучения моделей, не раскрывая коммерческие секреты.</li>
    <li id="n7M1"><strong>Монетизация данных:</strong> Пользователи зарабатывают токены, делясь своими данными — от истории браузера до активности в соцсетях.</li>
    <li id="vRyn"><strong>Персонализированные ИИ-агенты:</strong> Представьте себе ИИ-помощника, который знает ваши предпочтения, но при этом не передаёт их третьим лицам.</li>
    <li id="rlfU"><strong>Реклама на основе интересов:</strong> Masa zkAds позволяет показывать рекламу, основанную на ваших интересах, без нарушения приватности.</li>
  </ol>
  <p id="ekNI"><strong>Картинка с оригинала:</strong> Иллюстрация, показывающая, как данные проходят через сеть Masa и превращаются в токены (в оригинале это была схема с разноцветными стрелками).</p>
  <h4 id="qlEV">Почему это важно?</h4>
  <p id="3iqx">Masa решает проблему, о которой я часто задумываюсь: как сделать ИИ справедливым? Сегодня большие компании используют наши данные бесплатно, зарабатывая миллиарды, а мы не получаем ничего. Masa переворачивает эту модель с ног на голову, давая нам возможность контролировать свои данные и получать за них вознаграждение. Это не просто технология — это движение за справедливость в цифровом мире.</p>
  <h4 id="lduL">Будущее Masa</h4>
  <p id="J1rg">С более чем миллионом кошельков и 70+ партнёрами Masa уже создала прочный фундамент. Их roadmap включает расширение источников данных (например, подкасты и видео), интеграцию с другими блокчейнами и запуск новых инструментов для разработчиков. Если они продолжат в том же духе, то могут стать крупнейшим децентрализованным рынком данных в мире.</p>
  <p id="OQfD"><strong>Личное наблюдение:</strong> Я думаю, что Masa может стать настоящим конкурентом централизованным платформам, особенно если они добавят больше способов для обычных людей участвовать. Например, я бы хотел видеть интеграцию с повседневными приложениями, вроде мессенджеров или стриминговых сервисов.</p>
  <h4 id="IcaG">Заключение</h4>
  <p id="ZNiO">Masa — это больше, чем просто проект. Это взгляд в будущее, где данные принадлежат людям, а ИИ работает на благо всех, а не только корпораций. Если вы разработчик, ищущий качественные данные, или просто человек, который хочет заработать на своей цифровой жизни, Masa стоит вашего внимания.</p>
  <p id="pd5a"><strong>Картинка с оригинала:</strong> Логотип Masa с футуристическим фоном (в оригинале это был минималистичный дизайн с синими и белыми тонами).</p>
  <hr />
  <p id="84Ls">Если вы хотите, чтобы я добавил конкретные картинки или уточнил какие-то моменты (например, где именно вставлять ваши наблюдения или какие критерии важны), дайте знать! Я могу также адаптировать стиль или тон под ваши предпочтения. Что скажете?</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@vlad_i_mir/4SpHHY_QVYC</guid><link>https://teletype.in/@vlad_i_mir/4SpHHY_QVYC?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir</link><comments>https://teletype.in/@vlad_i_mir/4SpHHY_QVYC?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir#comments</comments><dc:creator>vlad_i_mir</dc:creator><title>Как пользоваться Docker (пособие новичка)</title><pubDate>Fri, 07 Mar 2025 15:12:35 GMT</pubDate><category>Основы</category><description><![CDATA[Docker — это платформа для контейнеризации, которая упрощает упаковку приложений в изолированные среды, называемые контейнерами. Основное преимущество Docker в том, что контейнеры работают одинаково на разных компьютерах и серверах, что значительно упрощает развертывание и поддержку приложений.]]></description><content:encoded><![CDATA[
  <h2 id="Knyn">Введение</h2>
  <p id="UIf8"><strong>Docker</strong> — это платформа для контейнеризации, которая упрощает упаковку приложений в изолированные среды, называемые контейнерами. Основное преимущество Docker в том, что контейнеры работают одинаково на разных компьютерах и серверах, что значительно упрощает развертывание и поддержку приложений.</p>
  <p id="SKZU"></p>
  <h2 id="RBZT">Основные компоненты Docker</h2>
  <p id="GMTO">Docker состоит из нескольких ключевых компонентов, каждый из которых выполняет свою роль:</p>
  <ul id="sPZG">
    <li id="b1HA"><strong>Образ (Image)</strong>: это шаблон, содержащий всё, что нужно для работы приложения: операционную систему, зависимости, библиотеки, настройки. Образ можно представить как «чертёж», из которого запускаются контейнеры.</li>
    <li id="gwyi"><strong>Контейнер (Container)</strong>: это запущенный экземпляр образа. Он представляет собой изолированную среду, где работают приложения. Контейнеры легковесные и занимают меньше ресурсов, чем виртуальные машины.</li>
    <li id="fIgN"><strong>Dockerfile</strong>: это текстовый файл, содержащий инструкции по созданию образа. С Dockerfile можно автоматизировать процесс настройки и сборки образов.</li>
    <li id="0Ukd"><strong>Volume</strong>: Это место для хранения данных, независимое от контейнера. Данные в Volume сохраняются, даже если контейнер перезапускается.</li>
  </ul>
  <p id="UnRY"></p>
  <h2 id="4Lz8">Установка Docker</h2>
  <p id="NgFX">Чтобы установить Docker, выполните следующие команды на системе с Ubuntu.</p>
  <ul id="WPIw">
    <li id="VR2S">Обновите пакеты</li>
  </ul>
  <pre id="r75V">sudo apt-get update
</pre>
  <ul id="O563">
    <li id="xItL">Установите Docker</li>
  </ul>
  <pre id="ndAp">sudo apt-get install -y docker.io
</pre>
  <ul id="WkXf">
    <li id="9GWu">Проверьте успешность установки (это покажет установленную версию Docker)</li>
  </ul>
  <pre id="MHSZ">docker --version
</pre>
  <h2 id="iZlI">Основные команды Docker</h2>
  <p id="R04P">После установки Docker используйте следующие команды для работы с ним.</p>
  <ul id="rPEd">
    <li id="Kh6U">Загрузка образа из Docker Hub (в этом примере nginx — это название образа)</li>
  </ul>
  <pre id="GPCt">docker pull nginx
</pre>
  <ul id="WCEL">
    <li id="AFir">Запуск контейнера</li>
  </ul>
  <pre id="yZya">docker run -d -p 8080:80 nginx
</pre>
  <ul id="7170">
    <li id="ZVAT"><code>d</code> запускает контейнер в фоновом режиме</li>
    <li id="VHco"><code>p 8080:80</code> перенаправляет порт 8080 на хосте на порт 80 в контейнере</li>
    <li id="TdEJ">Политики перезапуска контейнера</li>
  </ul>
  <pre id="qbVb">docker run -d --restart always nginx
</pre>
  <p id="Y1E6">Политики перезапуска:</p>
  <ul id="wge8">
    <li id="9nJF"><code>no</code>: не перезапускать.</li>
    <li id="E6kq"><code>on-failure</code>: перезапускать при ошибке.</li>
    <li id="HZ99"><code>always</code>: всегда перезапускать.</li>
    <li id="MwUu"><code>unless-stopped</code>: перезапускать, если не остановлено вручную.</li>
    <li id="aJXc">Просмотр запущенных контейнеров</li>
  </ul>
  <pre id="965b">docker ps
</pre>
  <ul id="xEd4">
    <li id="aGv2">Просмотр всех контейнеров, то есть даже остановленных</li>
  </ul>
  <pre id="RN0A">docker ps -a
</pre>
  <ul id="q2PA">
    <li id="gfe2">Остановка контейнера</li>
  </ul>
  <pre id="t8FH">docker stop &lt;ID контейнера&gt;
</pre>
  <ul id="IbTK">
    <li id="Ed4A">Запуск контейнера</li>
  </ul>
  <pre id="vt3T">docker start &lt;ID контейнера&gt;
</pre>
  <ul id="y9Bi">
    <li id="ogEp">Перезапуск контейнера</li>
  </ul>
  <pre id="xxNA">docker restart &lt;ID контейнера&gt;
</pre>
  <ul id="9MED">
    <li id="Tl3a">Удаление контейнера (перед удалением нужно остановить контейнер)</li>
  </ul>
  <pre id="7G6s">docker rm &lt;ID контейнера&gt;
</pre>
  <ul id="sqKK">
    <li id="eqz9">Просмотр загруженных образов</li>
  </ul>
  <pre id="I0zn">docker images
</pre>
  <ul id="5ice">
    <li id="Li49">Удаление образа</li>
  </ul>
  <pre id="Wajz">docker rmi &lt;ID образа&gt;
</pre>
  <ul id="GDOk">
    <li id="x9eH">Просмотр логов контейнера</li>
  </ul>
  <pre id="dsri">docker logs &lt;ID контейнера&gt;
</pre>
  <ul id="LiMt">
    <li id="GClz">&quot;Живой&quot; просмотр логов контейнера</li>
  </ul>
  <pre id="bC0D">docker logs -f &lt;ID контейнера&gt;
</pre>
  <ul id="8Moz">
    <li id="asJu">Последние строки логов контейнера (в данном случае покажет последние 100 строчек логов)</li>
  </ul>
  <pre id="Sfhz">docker logs --tail 100 &lt;ID контейнера&gt;
</pre>
  <ul id="SRkH">
    <li id="b5Fp">Выполнение команды внутри контейнера</li>
  </ul>
  <pre id="p1LG">docker exec -it &lt;ID контейнера&gt; /bin/bash
</pre>
  <ul id="XnVN">
    <li id="yJU3">Создание образа из Dockerfile</li>
  </ul>
  <pre id="Zd3d">docker build -t my-custom-image .
</pre>
  <hr />
  <p id="cxeQ"></p>
  <h2 id="7ECS">Dockerfile: что это и для чего он нужен?</h2>
  <p id="fjAk"><strong>Dockerfile</strong> — текстовый файл, в котором описаны инструкции для создания Docker-образа. Он автоматизирует процесс создания образов, указывая, какие шаги и команды нужны для настройки среды, в которой будет работать приложение.</p>
  <p id="2lgf"><strong>Основные команды Dockerfile</strong></p>
  <ul id="3mEo">
    <li id="EaXP">FROM: задает базовый образ, на котором будет строиться новый</li>
  </ul>
  <pre id="5wW7">FROM ubuntu:20.04​</pre>
  <ul id="qqTw">
    <li id="0zgV">COPY: копирует файлы с хост-машины в контейнер</li>
  </ul>
  <pre id="Yh42">COPY . /app</pre>
  <ul id="M33o">
    <li id="wPIy">​RUN: выполняет команды при создании образа (например, установка пакетов)</li>
  </ul>
  <pre id="oum1">RUN apt-get update &amp;&amp; apt-get install -y nginx</pre>
  <ul id="txT7">
    <li id="Wy0x">​CMD: определяет команду, которая выполнится при запуске контейнера</li>
  </ul>
  <pre id="Bx0y">CMD [&quot;nginx&quot;, &quot;-g&quot;, &quot;daemon off;&quot;]</pre>
  <ul id="0crK">
    <li id="o0bD">​EXPOSE: указывает, какие порты будут доступны из контейнера</li>
  </ul>
  <pre id="19mK">EXPOSE 80</pre>
  <ul id="A7wY">
    <li id="9n0b">Пример Dockerfile для простого веб-сервера</li>
  </ul>
  <pre id="wUAD"># Указание базового образа
FROM nginx:alpine

# Копирование файлов в контейнер
COPY . /usr/share/nginx/html

# Открытие порта 80 для доступа
EXPOSE 80

# Запуск Nginx при старте контейнера
CMD [&quot;nginx&quot;, &quot;-g&quot;, &quot;daemon off;&quot;]</pre>
  <p id="z9br"></p>
  <h2 id="pSYV">Управление контейнерами</h2>
  <p id="VkwA">Для работы с контейнерами можно использовать как Docker CLI, так и более сложные инструменты оркестрации, такие как Docker Compose или Kubernetes.</p>
  <p id="sC0u"><strong>Docker Compose</strong>: используется для управления многоконтейнерными приложениями с помощью YAML-файла.</p>
  <p id="iMeN">Пример <code>docker-compose.yml</code>:</p>
  <pre id="PbQy">version: &#x27;3&#x27;
services:
   web:
    image: nginx
    ports:
      - &quot;8080:80&quot;
    restart: always
   db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: example
    restart: on-failure
</pre>
  <p id="hteb">Основные команды Docker Compose:</p>
  <ul id="mD0o">
    <li id="37Gi"><code>docker-compose up -d</code>: Запускает все сервисы из файла</li>
    <li id="qOK7"><code>docker-compose down</code>: Останавливает и удаляет все контейнеры</li>
  </ul>
  <p id="biyC">Команды <code>docker-compose</code> работают только в той директории, где находится файл <code>docker-compose.yml</code></p>
  <p id="dDXQ"><strong>Kubernetes</strong>: система для автоматизации развертывания и управления контейнерными приложениями в больших инфраструктурах.</p>
  <p id="83gf"></p>
  <h2 id="LLkI">Статусы контейнеров в Docker</h2>
  <p id="SfqC">Контейнеры в Docker могут находиться в различных состояниях:</p>
  <ol id="ljiz">
    <li id="iJaK"><strong>Created</strong>: контейнер создан, но не запущен</li>
    <li id="KjmV"><strong>Running</strong>: контейнер запущен и работает</li>
    <li id="Q9k1"><strong>Exited</strong>: контейнер завершен (если завершился с ошибкой, это указывается)</li>
    <li id="u4hn"><strong>Paused</strong>: контейнер приостановлен</li>
    <li id="Ukao"><strong>Restarting</strong>: контейнер перезапускается после сбоя</li>
    <li id="xJhm"><strong>Dead</strong>: контейнер не завершился корректно</li>
  </ol>
  <ul id="j6j0">
    <li id="DiYP">Просмотр статусов контейнеров</li>
  </ul>
  <pre id="Itbe">docker ps</pre>
  <p id="WGzi">Для просмотра всех контейнеров</p>
  <pre id="L7tZ">docker ps -a</pre>
  <p id="KwHW"></p>
  <h2 id="voMd">Хранение данных в Docker</h2>
  <p id="ojWP">Контейнеры Docker являются эфемерными, поэтому их данные удаляются после остановки. Чтобы сохранить данные, используются:</p>
  <ul id="RXg4">
    <li id="17nl"><strong>Volumes</strong>: хранилища, управляемые Docker, которые сохраняются, даже если контейнер удален</li>
  </ul>
  <pre id="46B9">docker run -v /data:/var/lib/mysql mysql</pre>
  <ul id="FZQc">
    <li id="Bouk"><strong>Bind mounts:</strong> привязка директории хоста к директории контейнера</li>
  </ul>
  <pre id="XJUh">docker run -v /path/on/host:/path/in/container nginx</pre>
  <p id="t4Ez"></p>
  <h2 id="2GEr">Работа с файлами .env</h2>
  <p id="94EY">Файл <code>.env</code> хранит переменные окружения и позволяет передавать их в контейнеры, например, пароли, порты и конфигурации.</p>
  <ul id="mNwh">
    <li id="hcE5">Пример .env файла</li>
  </ul>
  <pre id="MbHH">MYSQL_ROOT_PASSWORD=supersecretpassword
MYSQL_DATABASE=mydatabase</pre>
  <ul id="Auyb">
    <li id="6nbX">Использование с Docker Compose</li>
  </ul>
  <pre id="4eI0">version: &#x27;3&#x27;
services:
  db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
</pre>
  <ul id="SP4y">
    <li id="x4wc">Передача переменных окружения через команду docker run</li>
  </ul>
  <pre id="lJAL">docker run -d -e MYSQL_ROOT_PASSWORD=supersecretpassword -e MYSQL_DATABASE=mydatabase mysql</pre>
  <p id="M4tp">В этом примере <code>-e</code> указывает Docker, что нужно задать переменные окружения <code>MYSQL_ROOT_PASSWORD</code> и <code>MYSQL_DATABASE</code> в контейнере.</p>
  <p id="uCQN"></p>
  <h2 id="rNbc">Заключение</h2>
  <p id="R1rA">Docker — удобный инструмент для создания и развертывания приложений. Он изолирует приложения в контейнеры, делая их независимыми от системы. Начав с базовых команд, вы сможете эффективно управлять контейнерами, переходя к оркестрации и масштабированию.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@vlad_i_mir/TsgjNK3oraS</guid><link>https://teletype.in/@vlad_i_mir/TsgjNK3oraS?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir</link><comments>https://teletype.in/@vlad_i_mir/TsgjNK3oraS?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir#comments</comments><dc:creator>vlad_i_mir</dc:creator><title>Запуск ноды через сервисный файл</title><pubDate>Fri, 07 Mar 2025 15:05:13 GMT</pubDate><category>Основы</category><description><![CDATA[В этом руководстве мы расскажем, как запускать ноды с помощью сервисных файлов, объясним преимущества такого подхода и покажем пошаговый процесс создания и управления сервисом. Мы будем использовать в качестве примера ноду Hemi, но полученные знания можно адаптировать под любую другую ноду, если знать нюансы её запуска.]]></description><content:encoded><![CDATA[
  <p id="kRi6">В этом руководстве мы расскажем, как запускать ноды с помощью сервисных файлов, объясним преимущества такого подхода и покажем пошаговый процесс создания и управления сервисом. Мы будем использовать в качестве примера ноду Hemi, но полученные знания можно адаптировать под любую другую ноду, если знать нюансы её запуска.</p>
  <h2 id="9DcU">Что такое сервисный файл и для чего он нужен</h2>
  <p id="yWic">Сервисный файл — это конфигурационный документ, используемый системой <strong>systemd</strong> для управления фоновыми процессами (сервисами) в Linux. Он описывает, как должна запускаться программа, какие параметры ей нужны, в каком порядке она стартует и как система должна реагировать в случае сбоев. Благодаря сервисному файлу можно автоматизировать запуск ноды при загрузке системы, следить за её состоянием и автоматически перезапускать её в случае ошибок.</p>
  <p id="2NoK">Главные цели использования сервисного файла:</p>
  <ul id="a5Jc">
    <li id="OU38"><strong>Автоматизация запуска</strong>: сервис стартует автоматически при загрузке системы.</li>
    <li id="9HVf"><strong>Мониторинг и перезапуск</strong>: systemd следит за работой сервиса и может автоматически перезапустить ноду, если она завершилась с ошибкой.</li>
    <li id="84sF"><strong>Управление ресурсами</strong>: задаются параметры, влияющие на приоритет, рабочую директорию и права доступа.</li>
    <li id="lP7C"><strong>Удобство администрирования</strong>: все команды по управлению сервисом централизованы через <code>systemctl</code>.</li>
  </ul>
  <p id="yJHr"></p>
  <h2 id="Sdhn">Преимущества запуска ноды через сервисный файл</h2>
  <p id="AdSB">Использование сервисного файла имеет ряд существенных преимуществ по сравнению с утилитами вроде <strong>Screen</strong> или <strong>Tmux</strong>:</p>
  <ul id="kM19">
    <li id="iFGr"><strong>Автоматический запуск при загрузке системы</strong>: сервисный файл позволяет настроить автозапуск ноды, что особенно важно для серверов, работающих 24/7.</li>
    <li id="R94Y"><strong>Автоматический перезапуск</strong>: systemd может автоматически перезапустить ноду в случае сбоя, обеспечивая высокую надежность работы.</li>
    <li id="f7F3"><strong>Централизованное управление</strong>: с помощью команды <code>systemctl</code> можно легко запускать, останавливать, перезапускать и проверять статус ноды, не заходя в активную сессию.</li>
    <li id="PMaQ"><strong>Логирование</strong>: systemd интегрирован с <code>journalctl</code>, что позволяет удобно просматривать логи сервиса.</li>
    <li id="jIuZ"><strong>Меньше зависимости от пользовательского интерфейса</strong>: Screen и Tmux хороши для ручного контроля, но сервисный файл позволяет оставить ноду работающей в фоне без необходимости активного подключения через терминал.</li>
  </ul>
  <p id="XSyT"></p>
  <h2 id="Teg1">Как создать сервисный файл для запуска ноды (на примере Hemi)</h2>
  <p id="rcXr">Далее рассмотрим пошагово, как создать сервисный файл для ноды Hemi.</p>
  <p id="HpLp"><strong>Подготовка</strong> Убедитесь, что нода Hemi установлена и настроена. Определите путь к исполняемому файлу ноды и рабочую директорию, где находится её конфигурация (сервисный можно создать только тогда, когда уже установлены все зависимости ноды и она настроена для работы)</p>
  <p id="I8HT"><strong>Создание файла сервиса</strong> Создайте новый файл сервиса, например, <code>/etc/systemd/system/hemi.service</code>:</p>
  <pre id="vLn8">sudo nano /etc/systemd/system/hemi.service</pre>
  <p id="CXfw"><strong>Заполните файл следующей конфигурацией</strong>: </p>
  <pre id="mlCf" data-lang="python">[Unit] 
Description=Hemi Node Service 
After=network.target 

[Service] 
User=root 
WorkingDirectory=/root/hemi/ 
ExecStart=/root/hemi/popmd 
Restart=always 
RestartSec=10 

[Install] 
WantedBy=multi-user.target  </pre>
  <p id="X7vc"><strong>Пояснения</strong>:</p>
  <ol id="PbNc">
    <ul id="8Z8r">
      <li id="Vuxz"><strong>[Unit]</strong>: Секция описывает сервис. Параметр <code>After=network.target</code> гарантирует, что нода запустится после установления сетевого соединения.</li>
      <li id="9Qhh"><strong>[Service]</strong>: Здесь задаются параметры запуска.</li>
      <ul id="P0Ym">
        <li id="TWFU"><code>User</code> — имя пользователя, от которого будет запущена нода.</li>
        <li id="dy8o"><code>WorkingDirectory</code> — директория, где находится нода и её конфигурация.</li>
        <li id="WV4i"><code>ExecStart</code> — команда для запуска ноды (замените путь и параметры на свои).</li>
        <li id="qtXP"><code>Restart=always</code> гарантирует автоматический перезапуск ноды при сбое.</li>
        <li id="Y009"><code>RestartSec=10</code> — задержка в секундах перед перезапуском.</li>
      </ul>
      <li id="zsO2"><strong>[Install]</strong>: Определяет, при каких режимах запуска система должна активировать этот сервис (обычно multi-user.target для серверов).</li>
    </ul>
  </ol>
  <p id="wB2m"><strong>Сохраните и закройте файл</strong>. После редактирования нажмите <code>Ctrl+O</code> (сохранить) и <code>Ctrl+X</code> (выйти).</p>
  <p id="GBV9"><strong>Примените изменения</strong>: </p>
  <pre id="VuzL">sudo systemctl daemon-reload  </pre>
  <p id="FzSg">Эта команда обновит конфигурацию systemd и зарегистрирует новый сервис.</p>
  <p id="FeVH"><strong>Включите автозапуск и запустите сервис</strong>: </p>
  <pre id="bljj">sudo systemctl enable hemi.service 
sudo systemctl start hemi.service </pre>
  <p id="wuZr"><strong>Проверьте статус сервиса</strong>: </p>
  <pre id="tvwR">sudo systemctl status hemi.service  </pre>
  <p id="n8DN">Убедитесь, что нода запущена и работает без ошибок.</p>
  <p id="uo5M"></p>
  <h2 id="2GZ3">Команды для работы с сервисным файлом</h2>
  <p id="SSKg">После создания и запуска сервисного файла для ноды, вы можете использовать следующие команды для управления и мониторинга:</p>
  <p id="sbLQ"><strong>Запуск сервиса</strong>:</p>
  <pre id="ZCo6">sudo systemctl start hemi.service</pre>
  <p id="dITG"><strong>Остановка сервиса</strong>: </p>
  <pre id="HWpe">sudo systemctl stop hemi.service </pre>
  <p id="ydxC"><strong>Перезапуск сервиса</strong>: </p>
  <pre id="PWWd">sudo systemctl restart hemi.service </pre>
  <p id="ZaJD"><strong>Проверка статуса сервиса</strong>: </p>
  <pre id="ESSj">sudo systemctl status hemi.service  </pre>
  <p id="i8J5">Эта команда показывает, запущен ли сервис, его журналы и возможные ошибки.</p>
  <p id="f28w"><strong>Просмотр логов сервиса</strong>: </p>
  <pre id="WBPZ">sudo journalctl -u hemi.service -f  </pre>
  <p id="9VCG">Флаг <code>-f</code> обеспечивает &quot;живой&quot; просмотр логов в режиме реального времени.</p>
  <p id="GGu7"><strong>Отключение автозапуска</strong>: </p>
  <pre id="FePt">sudo systemctl disable hemi.service </pre>
  <h2 id="HjtX">Заключение</h2>
  <p id="pwHb">Запуск ноды через сервисный файл — это современный и надежный способ автоматизировать работу вашей ноды. Использование systemd позволяет обеспечить автоматический запуск при загрузке системы, автоматический перезапуск в случае сбоев и удобное управление через единый интерфейс командной строки. Этот подход особенно полезен для серверов, работающих 24/7, и позволяет администраторам сосредоточиться на развитии и оптимизации инфраструктуры, а не на постоянном контроле вручную. Надеемся, что данный гайд помог вам разобраться с основами создания и управления сервисными файлами для нод, и теперь вы сможете легко применять эти знания на практике.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@vlad_i_mir/P4rSsB1k-36</guid><link>https://teletype.in/@vlad_i_mir/P4rSsB1k-36?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir</link><comments>https://teletype.in/@vlad_i_mir/P4rSsB1k-36?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir#comments</comments><dc:creator>vlad_i_mir</dc:creator><title>Как проверить параметры сервера (процессор, RAM, место на диске)</title><pubDate>Fri, 07 Mar 2025 14:56:14 GMT</pubDate><category>Основы</category><description><![CDATA[Для нодера очень важно уметь проверять состояния сервера, а именно нагрузку на систему. Но также важно знать текущие параметры и возможности железа, которое вы арендуете. Для этого вам пригодятся команды Linux с этой статьи, которые помогут получить информацию о процессоре, памяти и диске.]]></description><content:encoded><![CDATA[
  <h3 id="RZ7L">Введение</h3>
  <p id="lkeR">Для нодера очень важно уметь проверять состояния сервера, а именно нагрузку на систему. Но также важно знать текущие параметры и возможности железа, которое вы арендуете. Для этого вам пригодятся команды Linux с этой статьи, которые помогут получить информацию о процессоре, памяти и диске.</p>
  <h3 id="epz2">Проверка процессора (CPU)</h3>
  <p id="fCMC">Процессор — один из важнейших компонентов сервера. Узнать его параметры можно следующими командами:</p>
  <p id="NAdW"><strong>Общая информация о процессоре</strong></p>
  <pre id="rCxe">lscpu</pre>
  <p id="wWM9">​Вывод покажет модель, частоту, количество ядер и архитектуру процессора.</p>
  <p id="YbX1"><strong>Просмотр загрузки процессора в реальном времени</strong></p>
  <pre id="bxUI">top ​</pre>
  <p id="IlaI">Нажмите q, чтобы выйти из режима. </p>
  <p id="BeHC"><strong>Упрощенный вывод текущей загрузки процессора</strong></p>
  <pre id="OOvs">mpstat </pre>
  <p id="ZUmC">​Если команда не найдена, то сначала выполните установку</p>
  <pre id="bQCL" data-lang="python">sudo apt install sysstat</pre>
  <h3 id="VtIq"></h3>
  <h3 id="u2uq">Проверка оперативной памяти (RAM)</h3>
  <p id="7kry">Чтобы проверить объем и использование оперативной памяти:</p>
  <p id="9iUN"><strong>Общий объем памяти и использование</strong></p>
  <pre id="0rWu">free -h</pre>
  <p id="YjYY">Флаг -h выводит данные в удобном для чтения формате (MB/GB).</p>
  <p id="UL8Z"><strong>Более детальная информация о памяти</strong></p>
  <pre id="6gnP">cat /proc/meminfo</pre>
  <p id="1pXQ">Эта команда покажет детализированные данные, включая доступную и свободную память.</p>
  <p id="2C1L"><strong>Мониторинг памяти в реальном времени</strong></p>
  <pre id="14qj">top</pre>
  <p id="Xczg">В правом верхнем углу вы увидите строки, связанные с использованием RAM и Swap.</p>
  <p id="wgtE"></p>
  <h3 id="18N9">Проверка дискового пространства</h3>
  <p id="6VFX">Место на диске часто становится проблемой, поэтому важно знать, сколько его доступно.</p>
  <p id="QMYZ"><strong>Общий объем и доступное место на дисках</strong> </p>
  <pre id="dwxC">df -h  </pre>
  <p id="sFQn">Команда покажет, сколько места занято и сколько свободно на каждом разделе.</p>
  <p id="4ZIb"><strong>Размер конкретной папки</strong> </p>
  <pre id="n2qR">du -sh /path/to/folder  </pre>
  <p id="vCV0">Замените <code>/path/to/folder</code> на путь к интересующей вас директории.</p>
  <p id="J7J2"><strong>Поиск самых больших файлов и папок</strong> </p>
  <pre id="QIiC">du -ah / | sort -rh | head -n 10  </pre>
  <p id="kjRE">Команда покажет 10 самых тяжелых файлов и папок на сервере.</p>
  <p id="rMQk"></p>
  <h3 id="Oq8h">Проверка общей загрузки системы</h3>
  <p id="hoBw">Для общей оценки состояния сервера можно использовать следующую команду:</p>
  <p id="qFal"><strong>Узнать текущую загрузку процессора, памяти и диска</strong>: это улучшенная версия <code>top</code>, которая предоставляет более удобный интерфейс. Для установки выполните </p>
  <pre id="ct7C">sudo apt install htop </pre>
  <p id="CHC0">Команда для запуска утилиты </p>
  <pre id="XZse">htop </pre>
  <h3 id="wxv7">Частые ошибки и как их избежать</h3>
  <p id="VDnn"><strong>Команда не найдена</strong>: убедитесь, что у вас установлены необходимые утилиты. Например, для <code>htop</code> и <code>mpstat</code> нужно выполнить установку через пакетный менеджер.</p>
  <pre id="I7dI">sudo apt install &lt;название_утилиты&gt; </pre>
  <p id="9QGa"><strong>Недостаточно прав</strong>: если команда требует доступа к системным файлам, добавьте <code>sudo</code> перед ней.</p>
  <p id="GmXK"><strong>Проблемы с чтением вывода</strong>: Используйте флаг <code>h</code> (human-readable), где это возможно, чтобы вывод был удобнее.</p>
  <p id="40SK"></p>
  <h3 id="Xrl4">Заключение</h3>
  <p id="SDWG">Проверка параметров сервера — важный навык, который помогает быстро диагностировать проблемы и следить за состоянием системы. Используя команды, описанные в этой статье, вы сможете узнать все необходимое о своем сервере: процессор, оперативную память и место на диске.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@vlad_i_mir/V_I_p1r3Y6a</guid><link>https://teletype.in/@vlad_i_mir/V_I_p1r3Y6a?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir</link><comments>https://teletype.in/@vlad_i_mir/V_I_p1r3Y6a?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir#comments</comments><dc:creator>vlad_i_mir</dc:creator><title>Работа со screen</title><pubDate>Fri, 07 Mar 2025 14:48:05 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/85/b9/85b9f2f7-237c-4967-8ba2-5579b180c7da.png"></media:content><category>Основы</category><description><![CDATA[<img src="https://img4.teletype.in/files/3f/9f/3f9f8ebe-b1d6-477c-84ac-53fbb8cb0a07.png"></img>Работа терминала устроена таким образом, что при его закрытии также остановят свою работу процессы, которые не запущены в фоне. Если провести аналогию с Windows, то это, то же самое что запустить, например, установку Google Chrome, но во время инсталляции закрыть установочную программу. В случае с Windows мы просто сворачиваем окно такой программы, чтобы оно нам не мешало. Что же касается серверов с Linux, то в терминале мы всё выполняем с помощью команд и нет возможности свернуть окна по причине их отсутствия.]]></description><content:encoded><![CDATA[
  <h3 id="pyNn">Введение</h3>
  <p id="w5VW">Работа терминала устроена таким образом, что при его закрытии также остановят свою работу процессы, которые не запущены в фоне. Если провести аналогию с Windows, то это, то же самое что запустить, например, установку Google Chrome, но во время инсталляции закрыть установочную программу. В случае с Windows мы просто сворачиваем окно такой программы, чтобы оно нам не мешало. Что же касается серверов с Linux, то в терминале мы всё выполняем с помощью команд и нет возможности свернуть окна по причине их отсутствия.</p>
  <p id="KfbY">Чтобы на сервере запустить программу в фоне и оставить её там работать, используют разные подходы. Например, можно создать сервисный файл и запустить его, а потом просто при помощи специальных команд проверять логи. А можно воспользоваться сторонними программами, которые создают сессии и оставляют их работать в фоновом режиме. Наиболее распространенные решения — это Tmux и Screen, в этой статье познакомимся со вторым.</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="S8wS"><strong>Screen</strong> — это утилита для управления сессиями терминала, позволяющая запускать процессы в фоне и восстанавливать сессии после отключения.</p>
  </section>
  <p id="91ij"></p>
  <h3 id="iwWf">Установка и полезные команды</h3>
  <p id="FvIb">На сервер c Ubuntu утилита Screen устанавливается буквально двумя командами</p>
  <pre id="bNWW">sudo apt update
sudo apt install screen</pre>
  <p id="1qhP">Для создания сессии воспользуйтесь командой ниже, где имя_сессии — это желаемое имя для сессии, которую вы хотите создать (используйте только цифры и латинские буквы). После использования этой команды вы автоматически попадаете в сессию, то есть это как новое “окно” внутри терминала, но интерфейс не поменяетсяBashCopy</p>
  <pre id="9Tlq">screen -S имя_сессии</pre>
  <p id="NIs4">Внутри сессии вы можете выполнять команды и запускать всё то, что и в основном “окне” командной строки.</p>
  <ul id="2qgW">
    <li id="tFz1">Для выхода из сессии можно использовать комбинацию клавиш <code>Ctrl+A, затем D</code>, в некоторых пользователей на этом этапе возникают проблемы — они не могут выйти из сессии или вовсе случайно закрывают её. Но есть альтернатива, из сессии можно выйти при помощи команды ниже. Но если в сессии запущена нода и идут логи, то такой командой выйти не получиться и всё же придется воспользоваться <code>Ctrl+A, затем D</code>,</li>
  </ul>
  <pre id="0DLP">screen -d</pre>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="YutP">Ctrl+A, затем D = screen -d, но это скорее вопрос привычки, чем необходимости. Выходить из сессии при помощи комбинации намного быстрее, но для новичков выход при помощи команды будет более надежным вариантом.</p>
  </section>
  <p id="P7mZ">Если вам нужно повторно зайти в сессию после выхода, то используйте команду ниже, где имя_сессии — это имя сессии, которую вы создавали ранее</p>
  <pre id="sgIi">screen -r имя_сессии</pre>
  <p id="99ME">Частая ошибка новичков — это создание множества сессий с одинаковыми названиями по причине невнимательности. Дело в том, что новички часто путают команды создания сессии (флаг -S) и открытия уже существующей сессии (флаг -r). Проблема в том, что Screen разрешает создавать много сессий с одинаковыми названиями, так как он всё равно присваивает цифровой идентификатор (ID) перед буквенным именем, пример на скриншоте ниже</p>
  <figure id="fOE0" class="m_column">
    <img src="https://img4.teletype.in/files/3f/9f/3f9f8ebe-b1d6-477c-84ac-53fbb8cb0a07.png" width="778" />
  </figure>
  <p id="Shnb">Чтобы увидеть список уже запущенных сессий, воспользуйтесь командой ниже</p>
  <pre id="SaAJ">screen -ls</pre>
  <p id="X8Te">Понятно, что такое количество сессий с одинаковыми названиями нам не нужны, для удаления сессий используют следующую команду, где имя_сессии — это имя сессии, которую вы хотите удалить</p>
  <pre id="9rBx">screen -S имя_сессии -X quit</pre>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="qjL9">Если в списке сессия с уникальным именем, то можно просто написать, например, <code>screen -S forto -X quit</code>, но если есть хотя бы два одинаковых имени, то придется указывать ID — <code>screen -S 3290953.forto -X quit</code> или <code>screen -S 3290953 -X quit</code></p>
  </section>
  <p id="cOlb">Но командная строка тем и хороша, что практически всё можно автоматизировать. Если воспользоваться командой ниже, то она удалит все сессии с одинаковыми именами, где имя_сессии — это имя, присвоенное для многих сессий, которые вы хотите удалить</p>
  <pre id="FuWI">screen -ls | grep &quot;имя_сессии&quot; | awk &#x27;{print $1}&#x27; | xargs -I {} screen -S {} -X quit</pre>
  <p id="uyNX">Для понимания работы команды:</p>
  <ol id="tk8O">
    <li id="h6lD"><strong><code>screen -ls</code></strong>: выводит список всех сессий.</li>
    <li id="3Ncw"><strong><code>grep &quot;forto&quot;</code></strong>: фильтрует список, оставляя только сессии с названием &quot;<code>имя_сессии</code>&quot;.</li>
    <li id="XshY"><strong><code>awk &#x27;{print $1}&#x27;</code></strong>: извлекает идентификаторы (ID) этих сессий.</li>
    <li id="QD9H"><strong><code>xargs -I {} screen -S {} -X quit</code></strong>: передает каждый ID в команду <code>screen -S &lt;ID&gt; -X quit</code>, которая завершает соответствующую сессию.</li>
  </ol>
  <p id="ngmO"></p>
  <h3 id="Uq0l">Шпаргалка</h3>
  <p id="CNB6">Все команды для управления Screen довольно простые и их легко запомнить уже после нескольких раз использования, но на всякий случай вот шпаргалка:</p>
  <figure id="8yKY" class="m_column">
    <img src="https://img3.teletype.in/files/2e/79/2e79f64a-956c-493c-826c-06199a1667ab.png" width="701" />
  </figure>
  <h3 id="qRBy">Заключение</h3>
  <p id="xsoG">Более подходящий вариант для работы с нодами через командную строку — это их запуск через сервисный файл, но не всегда проекты предоставляют такую возможность. На самом деле Screen — это неплохая альтернатива, но всё-таки рекомендуем проверять работу запущенных сессий (минимум один раз в 1-2 дня), так как через сбой на сервере они могут закрыться, а Screen не умеет самостоятельно повторно их открывать.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@vlad_i_mir/YTNhRdKYoJ4</guid><link>https://teletype.in/@vlad_i_mir/YTNhRdKYoJ4?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir</link><comments>https://teletype.in/@vlad_i_mir/YTNhRdKYoJ4?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir#comments</comments><dc:creator>vlad_i_mir</dc:creator><title>Как установить Mobaxterm</title><pubDate>Fri, 07 Mar 2025 14:41:32 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/42/1e/421e5814-ded3-4f96-a66d-6a341c6bc49b.png"></media:content><category>Основы</category><description><![CDATA[<img src="https://img2.teletype.in/files/11/bd/11bd04fa-997d-42ae-b4d1-9e70ccebe68b.png"></img>MobaXterm — это универсальный инструмент для удаленного администрирования и работы с серверами. Он сочетает в себе множество функций, таких как SSH, SFTP, VNC, RDP и даже встроенный терминал, что делает его идеальным для управления серверами и выполнения задач с удаленным доступом. Ещё один плюс — это наличие удобного проводника, через которые можно легко скачать з сервера файлы на ваш компьютер или наоборот загрузить с компьютера на сервер.]]></description><content:encoded><![CDATA[
  <hr />
  <h2 id="6fn1">Ведение</h2>
  <p id="cbGL">MobaXterm — это универсальный инструмент для удаленного администрирования и работы с серверами. Он сочетает в себе множество функций, таких как SSH, SFTP, VNC, RDP и даже встроенный терминал, что делает его идеальным для управления серверами и выполнения задач с удаленным доступом. Ещё один плюс — это наличие удобного проводника, через которые можно легко скачать з сервера файлы на ваш компьютер или наоборот загрузить с компьютера на сервер.</p>
  <hr />
  <h2 id="HpqL">Установка Mobaxterm</h2>
  <ul id="HROa">
    <li id="6Jw2">Переходим по этой <a href="https://mobaxterm.mobatek.net/download.html" target="_blank">ссылке</a> и нажимаем на кнопку загрузки бесплатной версии (в этой версии можно создать 12 сессий, но для новичка этого вполне достаточно)</li>
  </ul>
  <figure id="7YWl" class="m_column">
    <img src="https://img2.teletype.in/files/11/bd/11bd04fa-997d-42ae-b4d1-9e70ccebe68b.png" width="1833" />
  </figure>
  <ul id="4bqp">
    <li id="kILP">Выбираем версию с инсталлятором и скачиваем</li>
  </ul>
  <figure id="HLWC" class="m_column">
    <img src="https://img1.teletype.in/files/47/5c/475c0f22-3c39-4a63-87a7-b77fb8c8d63d.png" width="1822" />
  </figure>
  <ul id="01B8">
    <li id="ax7Z">Открываем скачанный архив и устанавливаем как обычную программу</li>
  </ul>
  <figure id="Dy9j" class="m_column">
    <img src="https://img2.teletype.in/files/5f/71/5f7195bd-6f4a-4ccd-a534-546b8f5422d4.png" width="612" />
  </figure>
  <ul id="NKYq">
    <li id="DK77">После установки открываем программу и видим такой интерфейс, я выбираю темную тему — так намного удобней долго работать с командной строкой.</li>
  </ul>
  <figure id="mw5d" class="m_column">
    <img src="https://img3.teletype.in/files/ab/68/ab6851f0-384e-4487-994e-f49509e8c9a3.png" width="1918" />
  </figure>
  <hr />
  <h2 id="OVsD">Создание сессии и подключение к ней</h2>
  <ul id="e6LG">
    <li id="IF07">В левой колонке нажимаете правой кнопкой мышь и выбираете пункт создания сессии</li>
  </ul>
  <figure id="1iBN" class="m_column">
    <img src="https://img1.teletype.in/files/49/9d/499d7ba8-03a4-4d1b-91b5-8e01fdd96a21.png" width="1917" />
  </figure>
  <ul id="Dvnf">
    <li id="Zam8">Появится окно, в котором нужно выбрать тип подключения, выбираем SSH</li>
  </ul>
  <figure id="fHYs" class="m_column">
    <img src="https://img1.teletype.in/files/88/0a/880a1ce7-011c-48f2-91d4-dd8353869ae5.png" width="1918" />
  </figure>
  <ul id="q2k4">
    <li id="kO3k">В это поле вписываем IP нашего сервера и нажимаем кнопку “OK”</li>
  </ul>
  <figure id="6nru" class="m_column">
    <img src="https://img4.teletype.in/files/b1/48/b1482c00-5d11-4ed4-b22a-008321c3af51.png" width="1915" />
  </figure>
  <ul id="bqkU">
    <li id="Xgo3">Нажимаем два раза на сессию и справа откроется окно, как в браузере</li>
  </ul>
  <figure id="28jZ" class="m_column">
    <img src="https://img4.teletype.in/files/77/3f/773f785f-0cf6-4a23-96dd-a88bd2b6370d.png" width="1913" />
  </figure>
  <ul id="EmMz">
    <li id="mxsx">Вводим логин и пароль, чтобы зайти на сервер. Иногда после того, как вставили пароль, на сервер заходит автоматически, а иногда нужно ещё нажать Enter</li>
  </ul>
  <figure id="BIiU" class="m_column">
    <img src="https://img1.teletype.in/files/8a/65/8a65a778-bb11-461f-9060-98cc1e9bb181.png" width="1918" />
  </figure>
  <ul id="ivj9">
    <li id="traN">Справа откроется сам терминал, куда необходимо вводить все команды, а слева проводник с папками и файлами. Например, выбираем файл, нажимаем на синюю стрелочку вниз, выбираем папку и скачиваем файл себе на компьютер. Если хотим загрузить файл на сервер, то нажимаем на зеленую стрелочку вверх и выбираем файл для загрузки</li>
  </ul>
  <figure id="PaGH" class="m_column">
    <img src="https://img3.teletype.in/files/6c/5a/6c5a23ef-bf08-42a9-aa3b-26c383be67dc.png" width="1918" />
  </figure>
  <ul id="K0zn">
    <li id="taCp">Для закрытия сессии нужно написать команду <code>exit</code> или воспользоваться комбинацией клавиш Ctrl+D</li>
  </ul>
  <figure id="y5h2" class="m_column">
    <img src="https://img1.teletype.in/files/05/f5/05f50d05-3701-4576-b6e5-75f8426ea363.png" width="906" />
  </figure>
  <hr />
  <h2 id="oF4V">Заключение</h2>
  <p id="pIIJ">MobaXterm — мощный и удобный инструмент, который значительно упрощает управление серверами и работу с удаленными системами. С его помощью даже новичок сможет легко настроить подключение, управлять файлами и выполнять задачи в командной строке.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@vlad_i_mir/eEjx-JBUk15</guid><link>https://teletype.in/@vlad_i_mir/eEjx-JBUk15?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir</link><comments>https://teletype.in/@vlad_i_mir/eEjx-JBUk15?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir#comments</comments><dc:creator>vlad_i_mir</dc:creator><title>Пошаговая инструкция: Создание Telegram-бота с функцией &quot;Обучение&quot;</title><pubDate>Thu, 06 Mar 2025 12:07:53 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/fc/63/fc6321ee-741b-4528-a15b-ccef6b235740.png"></media:content><description><![CDATA[<img src="https://img4.teletype.in/files/73/51/73513313-2597-4dd9-9a0e-4b8aab51ae81.jpeg"></img>Представь, что мы собираем ящик с инструментами для нашего бота.]]></description><content:encoded><![CDATA[
  <figure id="TBvg" class="m_column">
    <img src="https://img2.teletype.in/files/51/44/5144af79-6bf4-46d5-985a-98d532845676.jpeg" />
  </figure>
  <h3 id="fKuI">Что нам понадобится</h3>
  <ul id="FXbM">
    <li id="ZqLb">Компьютер или сервер (например, домашний компьютер или облачный сервер, если у тебя есть).</li>
    <li id="KXAk">Интернет.</li>
    <li id="MkKi">Чуть-чуть терпения и желание повеселиться с ботом!</li>
  </ul>
  <hr />
  <h3 id="mH1i">Шаг 1: Подготовка — Устанавливаем нужные штуки</h3>
  <p id="cQAu">Представь, что мы собираем ящик с инструментами для нашего бота.</p>
  <p id="pcg3"><strong>Убедись, что у тебя есть Python</strong>:</p>
  <ol id="j8oq">
    <ul id="vjvd">
      <li id="eWpN">Открой терминал (на Windows это &quot;Командная строка&quot; или PowerShell, на Linux/Mac — просто &quot;Терминал&quot;).</li>
      <li id="53S0">Напиши: </li>
    </ul>
  </ol>
  <pre id="BWaD">python3 --version</pre>
  <ol id="HTcu">
    <ul id="7TVb">
      <li id="M5uo">Если видишь что-то вроде Python 3.9.2, всё круто! Если нет, попроси взрослого помочь установить Python с сайта python.org.</li>
    </ul>
  </ol>
  <p id="KzfY"><strong>Установи &quot;инструменты&quot; для бота</strong>:</p>
  <ol id="6gc7">
    <ul id="EOpg">
      <li id="ZTWN">В том же терминале пиши по очереди:</li>
    </ul>
  </ol>
  <pre id="xuYE">pip3 install python-telegram-bot 
pip3 install openai
pip3 install python-dotenv</pre>
  <ol id="ZIls">
    <ul id="LXBy">
      <li id="EKQU">Это как скачать приложения для бота: одно для Telegram, другое для умных ответов (GPT), третье для хранения секретов.</li>
    </ul>
  </ol>
  <p id="Q5eS"><strong>Установи &quot;экран&quot; (screen), чтобы бот не выключался</strong>:</p>
  <ol id="8fZf">
    <ul id="XUhI">
      <li id="3NgY">Если ты на Linux (например, сервер), пиши:</li>
    </ul>
  </ol>
  <pre id="25K3">sudo apt install screen</pre>
  <ol id="2rGo">
    <ul id="pjb7">
      <li id="zIQY">Если что-то не получается, попроси взрослого помочь. На Windows это не нужно, если ты запускаешь дома.</li>
    </ul>
  </ol>
  <hr />
  <h3 id="cAIe">Шаг 2: Создаём бота и собираем секреты</h3>
  <p id="CKXB">Теперь мы сделаем бота и дадим ему &quot;ключи&quot; для работы.</p>
  <p id="ne6w"><strong>Создай бота в Telegram</strong>:</p>
  <ol id="sS0r">
    <ul id="aXNT">
      <li id="Bg18">Открой Telegram на телефоне или компьютере.</li>
      <li id="rdm0">Найди @BotFather (это такой &quot;папа всех ботов&quot;).</li>
      <li id="o3BQ">Напиши ему<strong> /start</strong>, потом <strong>/newbot.</strong></li>
      <li id="hD8x">Дай боту имя (например, &quot;УмныйВоваБот&quot;) и ник (например, @VovaSmartBot).</li>
      <li id="X0wS">Он даст тебе код, типа<strong> 771456457973:AAGwsD0GetKrPtn-OuMyoV_uBMR45645diS7U</strong>. Запиши его!</li>
    </ul>
  </ol>
  <p id="kOY3"><strong>Получи ключ для GPT</strong>:</p>
  <ol id="pyyJ">
    <ul id="Zddp">
      <li id="1GXj">Попроси взрослого зарегистрироваться на <a href="https://platform.openai.com" target="_blank">platform.openai.com</a>.</li>
      <li id="fpGw">Там в разделе &quot;API Keys&quot; нажми &quot;Create new secret key&quot;.</li>
      <li id="HKeQ">Скопируй ключ, он выглядит как <strong>sk-proj-qBB9UQNZBXudTpDJff9aJoZecGrXTeCtgV3K2TzZ6YT4m-Tfhg4M5wozR5vWtCwDfghxE-v3j-boKhghKOymT3Blbорлрололр7jn2XJQBrJzuTWauMIZNjLYfghY2hDeDZ9kWowgf9kSriAj11фывф-Gp0U95FBLvEыквg4SyfgP0qvCK0A.</strong></li>
    </ul>
  </ol>
  <p id="tLcb"><strong>Создай секретный файл .env</strong>:</p>
  <ol id="DnBI">
    <ul id="yaf4">
      <li id="fIJ0">В терминале создай папку для бота: </li>
    </ul>
  </ol>
  <pre id="f1oJ">mkdir my_cool_bot cd my_cool_bot
apt install nano</pre>
  <ol id="5qw9">
    <ul id="F5Ob">
      <li id="vMFy">Открой текстовый редактор: </li>
    </ul>
  </ol>
  <pre id="HXDt">nano .env</pre>
  <ol id="t7pA">
    <ul id="HcrS">
      <li id="pHyN">Вставь свои ключи:</li>
    </ul>
  </ol>
  <pre id="S50l">TELEGRAM_TOKEN=твой_код_от_BotFather 
OPENAI_API_KEY=твой_код_от_OpenAI</pre>
  <ol id="KbZ1">
    <ul id="ZKkx">
      <li id="MFSY">Сохрани: нажми <strong>Ctrl+O</strong>, потом <strong>Enter</strong>, и выйди с <strong>Ctrl+X.</strong></li>
    </ul>
  </ol>
  <hr />
  <h3 id="o8Cy">Шаг 3: Пишем код для бота</h3>
  <p id="BPtS">Теперь дадим боту мозги! Мы заменим кнопку и добавим обучение.</p>
  <ol id="FYMC">
    <li id="XdKA"><strong>Создай файл bot.py</strong>:</li>
    <ul id="J3CG">
      <li id="zPWz">В той же папке (<strong>my_cool_bot</strong>) пиши: </li>
    </ul>
  </ol>
  <pre id="FGUj">nano bot.py</pre>
  <ol id="qX51">
    <ul id="lYC7">
      <li id="EIVW">Вставь этот код:</li>
    </ul>
  </ol>
  <pre id="FNSl" data-lang="python">import os
import json
from dotenv import load_dotenv
from telegram import Update, ReplyKeyboardMarkup
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
from openai import OpenAI

# Загружаем секретные ключи
load_dotenv()
TELEGRAM_TOKEN = os.getenv(&quot;TELEGRAM_TOKEN&quot;)
OPENAI_API_KEY = os.getenv(&quot;OPENAI_API_KEY&quot;)

# Подключаемся к GPT
client = OpenAI(api_key=OPENAI_API_KEY)

# Хранилища для данных
user_prompts = {}
user_history = {}
user_training_data = {}

# Загружаем данные обучения из файла, если он есть
def load_training_data():
    global user_training_data
    try:
        with open(&quot;training_data.json&quot;, &quot;r&quot;) as f:
            user_training_data = json.load(f)
    except FileNotFoundError:
        user_training_data = {}

# Сохраняем данные обучения в файл
def save_training_data():
    with open(&quot;training_data.json&quot;, &quot;w&quot;) as f:
        json.dump(user_training_data, f)

# Загружаем данные при старте
load_training_data()

# Меню с кнопками
main_menu = ReplyKeyboardMarkup([
    [&quot;История&quot;, &quot;Промт для бота&quot;],
    [&quot;Темы Постов&quot;, &quot;Обучение&quot;]
], resize_keyboard=True)

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    print(f&quot;Кто-то сказал /start! ID: {update.message.from_user.id}&quot;)
    await update.message.reply_text(
        &quot;Привет! Я твой умный бот. Выбери что-нибудь в меню или просто поболтай со мной!&quot;,
        reply_markup=main_menu
    )

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.message.from_user.id
    text = update.message.text
    print(f&quot;Сообщение от {user_id}: {text}&quot;)

    if text == &quot;История&quot;:
        history = user_history.get(user_id, &quot;История пуста.&quot;)
        await update.message.reply_text(history)
    
    elif text == &quot;Промт для бота&quot;:
        await update.message.reply_text(&quot;Напиши, кем я должен быть (например, &#x27;Ты - повар&#x27; или &#x27;Ты - учитель&#x27;).&quot;)
    
    elif text == &quot;Темы Постов&quot;:
        prompt = user_prompts.get(user_id, &quot;Ты - универсальный помощник.&quot;)
        post_ideas = get_post_ideas_from_gpt(prompt)
        if &quot;Ошибка&quot; not in post_ideas:
            ideas = post_ideas.split(&quot;\n\n&quot;)
            for idea in ideas:
                if idea.strip():
                    await update.message.reply_text(idea.strip())
        else:
            await update.message.reply_text(post_ideas)
    
    elif text == &quot;Обучение&quot;:
        await update.message.reply_text(&quot;Пришли мне ссылку, текст или что-то интересное, чтобы я научился!&quot;)
    
    else:
        # После &quot;Промт для бота&quot;
        if &quot;Промт для бота&quot; in context.user_data.get(&quot;last_command&quot;, &quot;&quot;):
            user_prompts[user_id] = text
            await update.message.reply_text(&quot;Круто, я теперь это умею!&quot;)
        
        # После &quot;Обучение&quot;
        elif &quot;Обучение&quot; in context.user_data.get(&quot;last_command&quot;, &quot;&quot;):
            if user_id not in user_training_data:
                user_training_data[user_id] = []
            user_training_data[user_id].append(text)
            save_training_data()  # Сохраняем в файл
            summary = process_training_data(text)
            await update.message.reply_text(f&quot;{summary}\nБлагодаря тебе я теперь это знаю, Вове привет!&quot;)
        
        # Просто болтаем
        else:
            prompt = user_prompts.get(user_id, &quot;Ты - универсальный помощник.&quot;)
            response = get_chat_response(prompt, text)
            await update.message.reply_text(response)
        
        # Записываем в историю
        if user_id not in user_history:
            user_history[user_id] = &quot;&quot;
        user_history[user_id] += f&quot;Ты сказал: {text}\n&quot;

    context.user_data[&quot;last_command&quot;] = text

def get_post_ideas_from_gpt(prompt):
    try:
        print(f&quot;Спрашиваю GPT про посты с промтом: {prompt}&quot;)
        response = client.chat.completions.create(
            model=&quot;gpt-4o&quot;,
            messages=[
                {&quot;role&quot;: &quot;system&quot;, &quot;content&quot;: f&quot;{prompt} Дай 5 идей для постов на март 2025. Раздели их пустой строкой.&quot;},
                {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: &quot;Дай мне идеи!&quot;}
            ],
            max_tokens=500
        )
        return response.choices[0].message.content
    except Exception as e:
        return f&quot;Упс, ошибка с GPT: {str(e)}&quot;

def get_chat_response(prompt, user_input):
    try:
        print(f&quot;Болтаю с GPT: {user_input}&quot;)
        response = client.chat.completions.create(
            model=&quot;gpt-4o&quot;,
            messages=[
                {&quot;role&quot;: &quot;system&quot;, &quot;content&quot;: prompt},
                {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: user_input}
            ],
            max_tokens=500
        )
        return response.choices[0].message.content
    except Exception as e:
        return f&quot;Ой, ошибка с GPT: {str(e)}&quot;

def process_training_data(data):
    try:
        print(f&quot;Учусь на этом: {data}&quot;)
        response = client.chat.completions.create(
            model=&quot;gpt-4o&quot;,
            messages=[
                {&quot;role&quot;: &quot;system&quot;, &quot;content&quot;: &quot;Ты - ученик. Дай очень краткий обзор того, что понял из текста или ссылки.&quot;},
                {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: f&quot;Что это: {data}&quot;}
            ],
            max_tokens=50
        )
        return response.choices[0].message.content
    except Exception as e:
        return f&quot;Не понял, что это: {str(e)}&quot;

def main():
    application = Application.builder().token(TELEGRAM_TOKEN).build()
    application.add_handler(CommandHandler(&quot;start&quot;, start))
    application.add_handler(MessageHandler(filters.TEXT &amp; ~filters.COMMAND, handle_message))
    print(&quot;Я готов работать!&quot;)
    application.run_polling()

if __name__ == &quot;__main__&quot;:
    main()</pre>
  <ol id="YOw9">
    <li id="frpW"><strong>Сохрани файл</strong>:</li>
    <ul id="RjVn">
      <li id="6qrT">Нажми <strong>Ctrl+O</strong>, потом <strong>Enter</strong>, и выйди с <strong>Ctrl+X.</strong></li>
    </ul>
  </ol>
  <hr />
  <h3 id="AFwx">Шаг 4: Запускаем бота, чтобы он не выключался</h3>
  <p id="zhHj">Теперь сделаем так, чтобы бот работал, даже если ты закроешь терминал.</p>
  <p id="SSgv"><strong>Открой &quot;экран&quot;</strong>:</p>
  <ol id="J9Sd">
    <ul id="L1y6">
      <li id="aA88">В той же папке (my_cool_bot) пиши:</li>
    </ul>
  </ol>
  <pre id="JqHm">screen</pre>
  <ol id="vnqK">
    <ul id="YEcz">
      <li id="N85e">Ты увидишь новый экран (может быть сообщение — нажми Enter).</li>
    </ul>
  </ol>
  <p id="zhN9"><strong>Запусти бота</strong>:</p>
  <ol id="gilZ">
    <ul id="aedd">
      <li id="qvtW">Пиши: </li>
    </ul>
  </ol>
  <pre id="LpY0">python3 bot.py</pre>
  <ol id="CAok">
    <ul id="kJMd">
      <li id="IQWz">Если всё ок, увидишь <strong>Я готов работать!.</strong></li>
    </ul>
  </ol>
  <p id="tTVp"><strong>Спрячь экран</strong>:</p>
  <ol id="WQr9">
    <ul id="gOaA">
      <li id="2Wnk">Нажми <strong>Ctrl+A,</strong> потом <strong>D</strong>.</li>
      <li id="hJEn">Ты вернёшься назад, а бот будет работать!</li>
    </ul>
  </ol>
  <p id="IB1D"><strong>Проверь, что он жив</strong>:</p>
  <ol id="B0kw">
    <ul id="DtgA">
      <li id="PFft">Пиши: </li>
    </ul>
  </ol>
  <pre id="mFSc">screen -ls</pre>
  <ol id="2eiG">
    <ul id="MOQq">
      <li id="ydqp">Увидишь что-то вроде <strong>12345.pts-0 (Detached)</strong> — это значит, бот живёт.</li>
    </ul>
  </ol>
  <hr />
  <h3 id="7M7F">Шаг 5: Проверяем, как всё работает</h3>
  <p id="w87B">Теперь давай поиграем с ботом!</p>
  <p id="Atb7"><strong>Открой Telegram</strong>:</p>
  <ol id="ixoJ">
    <ul id="sn6M">
      <li id="cSLP">Найди своего бота по его нику (например, @VovaSmartBot).</li>
      <li id="Jarz">Напиши <strong>/start.</strong></li>
      <li id="T6Tn">Увидишь меню с кнопками: &quot;История&quot;, &quot;Промт для бота&quot;, &quot;Темы Постов&quot;, &quot;Обучение&quot;.</li>
    </ul>
  </ol>
  <p id="5L4F"><strong>Проверь &quot;Обучение&quot;</strong>:</p>
  <ol id="tUIq">
    <ul id="o0KM">
      <li id="JhUk">Нажми <strong>&quot;Обучение&quot;</strong>.</li>
      <li id="NfCJ">Напиши что-нибудь, например:</li>
      <ul id="b7Ai">
        <li id="F9Kp"><strong>https://ru.wikipedia.org/wiki/Кот</strong></li>
        <li id="gnNQ">Или: <strong>Кот — это пушистое животное, которое мурлыкает.</strong></li>
      </ul>
      <li id="S6US">Бот ответит что-то вроде: </li>
    </ul>
  </ol>
  <blockquote id="mUcQ"><code>Коты — пушистые и мурлыкают. </code></blockquote>
  <blockquote id="1IT6"><code>Благодаря тебе я теперь это знаю, Вове привет!</code></blockquote>
  <p id="dvQ4"><strong>Проверь другие кнопки</strong>:</p>
  <ol id="PJjs">
    <ul id="lpzb">
      <li id="DfOA">&quot;<strong>История</strong>&quot;: Покажет, что ты писал.</li>
      <li id="PNV9">&quot;<strong>Промт для бота&quot;</strong>: Напиши &quot;Ты - кот&quot;, и бот станет говорить как кот.</li>
      <li id="1klB">&quot;<strong>Темы Постов</strong>&quot;: Даст 5 идей для постов, каждая в отдельном сообщении.</li>
    </ul>
  </ol>
  <p id="qfTK"><strong>Поболтай с ботом</strong>:</p>
  <ol id="wj3Q">
    <ul id="qfCL">
      <li id="AKRY">Напиши &quot;Привет, как дела?&quot; — он ответит как помощник (или кот, если ты сменил промт).</li>
    </ul>
  </ol>
  <hr />
  <h3 id="Q3dh">Шаг 6: Что делать, если что-то сломалось</h3>
  <ul id="edJW">
    <li id="Gbdz"><strong>Бот не отвечает</strong>:</li>
    <ul id="3eUm">
      <li id="wkVf">Вернись в экран: </li>
    </ul>
  </ul>
  <pre id="UFS6">screen -r</pre>
  <ul id="gI7F">
    <ul id="0lfX">
      <li id="rzyb">Посмотри, что он пишет. Если ошибка про <strong>TELEGRAM_TOKEN</strong> или <strong>OPENAI_API_KEY,</strong> проверь <strong>.env.</strong></li>
    </ul>
    <li id="ObC2"><strong>Не запускается</strong>:</li>
    <ul id="acwH">
      <li id="NUf8">Убедись, что ты в папке <strong>my_cool_bot</strong>: </li>
    </ul>
  </ul>
  <pre id="RhDH">cd my_cool_bot 
ls</pre>
  <ul id="NUbV">
    <ul id="iAAD">
      <li id="QvoX">Должны быть<strong> bot.py</strong> и .<strong>env</strong>.</li>
    </ul>
  </ul>
  <hr />
  <h3 id="UO4T">Круто, ты сделал бота!</h3>
  <p id="PGFi">Теперь он умеет учиться, хранит данные в файле <strong>training_data.json</strong> (в той же папке), и будет жить в <strong>screen</strong>, пока сервер включён. Если хочешь остановить бота, зайди в <strong>screen </strong>(<strong>screen -r</strong>), нажми <strong>Ctrl+C</strong>, и выйди с <strong>exit.</strong></p>
  <p id="5KrI">Напиши, если что-то непонятно или не работает — я помогу! 😊</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@vlad_i_mir/w5DCInDtyPV</guid><link>https://teletype.in/@vlad_i_mir/w5DCInDtyPV?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir</link><comments>https://teletype.in/@vlad_i_mir/w5DCInDtyPV?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir#comments</comments><dc:creator>vlad_i_mir</dc:creator><title>Как установить ноду Dria Compute Node (пошаговая инструкция)</title><pubDate>Tue, 04 Mar 2025 23:19:38 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/76/79/7679c4ad-7bf8-42d9-b2c4-8fd6563e9973.png"></media:content><category>Основы</category><description><![CDATA[<img src="https://img3.teletype.in/files/26/c1/26c1b9ca-6d3e-45e5-8044-f948df6ba5a6.jpeg"></img>Ты хочешь установить ноду Dria, чтобы подключиться к децентрализованной сети и запускать AI-агентов. Вот шаг за шагом, как это сделать:]]></description><content:encoded><![CDATA[
  <figure id="K5fF" class="m_column">
    <img src="https://img3.teletype.in/files/26/c1/26c1b9ca-6d3e-45e5-8044-f948df6ba5a6.jpeg" width="1120" />
  </figure>
  <p id="hc1s">Ты хочешь установить ноду Dria, чтобы подключиться к децентрализованной сети и запускать AI-агентов. Вот шаг за шагом, как это сделать:</p>
  <p id="2Tx7"></p>
  <h2 id="UOOR">Шаг 1: Установи нужные программы</h2>
  <p id="1Xtx"><strong>Открой терминал</strong> (это приложение, где можно вводить команды).</p>
  <p id="Plfk"><strong>Установим curl</strong>: Это программа, которая поможет загрузить нужные файлы. Введи команду:</p>
  <pre id="Reig" data-lang="bash">sudo apt update &amp;&amp; sudo apt install curl -y </pre>
  <p id="0GI4"><strong>Установи unzip</strong> (если его нет):</p>
  <pre id="rJNi" data-lang="bash">sudo apt-get install unzip </pre>
  <p id="c9vn"></p>
  <h2 id="wTi1">Шаг 2: Скачай и установи Dria Compute Launcher</h2>
  <p id="cuJ9"><strong>Загрузи Dria Compute Launcher</strong>:</p>
  <p id="d7EF">Введи команду в терминале</p>
  <pre id="lltl" data-lang="bash">curl -fsSL https://dria.co/launcher | bash </pre>
  <p id="9BTp">Это скачает и установит специальный файл для запуска ноды Dria.</p>
  <p id="UQBw"><strong>Перезапусти терминал</strong>:</p>
  <p id="stOE">Закрой терминал и открой его снова, чтобы все изменения вступили в силу.</p>
  <hr />
  <h2 id="nAX9">Шаг 3: Установка Ollama </h2>
  <p id="tDwy"><strong>Скачай и установи Ollama</strong>:Введи команду:</p>
  <pre id="DDtf" data-lang="bash">curl -fsSL https://ollama.com/install.sh | sh </pre>
  <p id="jboS"><strong>Проверь, что Ollama установлен</strong>:</p>
  <p id="vaB8">Введи:</p>
  <pre id="kNv2" data-lang="bash">ollama --version </pre>
  <p id="GYff">Если все правильно, он покажет версию программы.</p>
  <p id="2kFi"></p>
  <h2 id="Bm33">Шаг 3: Настрой и запусти ноду Dria </h2>
  <p id="AUx7"><strong>Список команд</strong>: в терминале введи:</p>
  <pre id="mEqi">dkn-compute-launcher help </pre>
  <p id="NtK3">Это покажет список команд, которые можно использовать. Если ты видишь этот список, значит установка прошла успешно!</p>
  <ol id="Rzib">
    <li id="E8y9"><strong>settings</strong> — Изменение настроек узла: модели, API-ключи, сетевые параметры.</li>
    <li id="Tdbi"><strong>setup</strong> — Создание файла окружения (.env) с нуля (перезапишет существующие значения).</li>
    <li id="hwiR"><strong>start</strong> — Запуск последнего вычислительного узла.</li>
    <li id="cuBr"><strong>referrals</strong> — Генерация или ввод реферального кода.</li>
    <li id="3rKe"><strong>points</strong> — Показать ваши очки $DRIA.</li>
    <li id="25ak"><strong>uninstall</strong> — Удаление лаунчера и его файлов.</li>
    <li id="Eudn"><strong>info</strong> — Информация о текущем окружении.</li>
    <li id="39rZ"><strong>update</strong> — Ручное обновление узла и лаунчера.</li>
    <li id="9RBa"><strong>specific</strong> — Запуск определенной версии узла.</li>
    <li id="7rWx"><strong>env-editor</strong> — Открытие текстового редактора для файла окружения (для продвинутых пользователей).</li>
    <li id="U01z"><strong>help</strong> — Вывод справки (этого сообщения или помощи по подкомандам).</li>
  </ol>
  <p id="Gg2f"><strong>опции </strong></p>
  <ol id="Qwhu">
    <li id="LQYs"><strong>-e, --env &lt;ENV&gt;</strong> — Указание пути к файлу .env (по умолчанию: /root/.dria/dkn-compute-launcher/.env).</li>
    <li id="gyOm"><strong>-p, --profile &lt;PROFILE&gt;</strong> — Название профиля для файла окружения.</li>
    <li id="vsS6"><strong>-h, --help</strong> — Вывод справки.</li>
    <li id="Sc3t"><strong>-V, --version</strong> — Вывод версии программы.</li>
  </ol>
  <p id="SXpr"></p>
  <p id="ZEqK"><strong>Изменение настроек узла: модели, API-ключи, сетевые параметры.</strong></p>
  <pre id="a4nG" data-lang="bash">dkn-compute-launcher settings</pre>
  <p id="Hdpz">Это покажет настройки</p>
  <p id="mXbN"><strong>Запуск ноды</strong>: </p>
  <p id="J97m"><code>dkn-compute-launcher start </code></p>
  <p id="Ollu">Это запустит твою ноду и подключит её к сети Dria.</p>
  <p id="GkDd"><strong>Проверь статус</strong>:</p>
  <p id="Jjd1">Чтобы проверить, работает ли нода, введи команду:</p>
  <pre id="1qZF" data-lang="bash">dkn-compute-launcher status </pre>
  <p id="tnmT">Если все нормально, терминал покажет, что нода активна. Чтобы нода работала даже после закрытия терминала, используй команду <code>screen</code> для запуска её в фоновом режиме. Поэтому останавливаем работу узла <strong>Ctrl + С </strong>и затем запускаем его в <code>screen</code></p>
  <p id="ELiT">Пример:</p>
  <pre id="3q0U" data-lang="bash">screen -S dria-node dkn-compute-launcher start </pre>
  <p id="TXjC">Чтобы выйти из <code>screen</code>, нажми <strong>Ctrl + A</strong>, потом <strong>D</strong>.</p>
  <ul id="UNjP">
    <li id="yOGB">Чтобы вернуться в <code>screen</code>, введи:</li>
  </ul>
  <pre id="F1NT" data-lang="bash">screen -r dria-node </pre>
  <p id="q6X3">или просмотреть запущенные скрины </p>
  <pre id="EU5N" data-lang="bash">screen -ls</pre>
  <p id="TnZ7">Еще не маловажный инструмент эта работа с профилем</p>
  <pre id="MULt" data-lang="bash">screen -S dria-node36 dkn-compute-launcher --profile 36 start </pre>
  <pre id="Z7RA" data-lang="bash">dkn-compute-launcher --profile 11 settings</pre>
  <p id="i4QV"></p>
  <p id="9ozt"><strong>Для запуска 40 сессий, изменяя номера с 1 до 40, с интервалом в 15 секунд:</strong></p>
  <pre id="jt09" data-lang="bash">for i in $(seq 1 40); do screen -S dria-node$i dkn-compute-launcher --profile $i start; sleep 15; done</pre>
  <p id="xeGD">Вот та же команда, но для запуска 40 сессий, изменяя номера с 1 до 40, с интервалом в 15 секунд:</p>
  <hr />
  <p id="NGsy">Bash</p>
  <pre id="vAFL">for i in $(seq 1 40); do screen -S dria-node$i dkn-compute-launcher --profile $i start; sleep 15; done
</pre>
  <hr />
  <p id="eBUI">Пояснение команды</p>
  <ul id="48us">
    <li id="esEE"><code>for i in $(seq 1 40); do ... done</code>: Этот цикл будет проходить по числам от <strong>1 до 40</strong>. На каждой итерации текущее число присваивается переменной <code>i</code>.</li>
    <li id="gLhH"><code>screen -S dria-node$i dkn-compute-launcher --profile $i start</code>: Это ваша команда для запуска процесса. <code>$i</code> автоматически заменится на текущее число из цикла. Таким образом, в каждой новой сессии <code>screen</code> будет уникальное имя (например, <code>dria-node1</code>, <code>dria-node2</code> и так далее до <code>dria-node40</code>) и соответствующий номер профиля.</li>
    <li id="0sQf"><code>sleep 15</code>: После запуска каждой <code>screen</code>-сессии скрипт будет ждать <strong>15 секунд</strong>, прежде чем перейти к следующей итерации. Это обеспечит необходимый интервал между запусками.</li>
  </ul>
  <p id="k2RH">Эта команда запустит 40 отдельных <code>screen</code>-сессий, каждая из которых будет иметь свой уникальный идентификатор и профиль, с паузой в 15 секунд между запусками.</p>
  <p id="wx7h"></p>
  <p id="Z6xn"></p>
  <h2 id="fwGb">Шаг 4: Исправляем ошибки если они есть </h2>
  <h4 id="hHJM">1. Проверяем фаервол на сервере</h4>
  <p id="6l0k">Твой порт 4001 открыт внутри сервера, но провайдером может блокировать его снаружи через свой фаервол. </p>
  <p id="3AdL">Давай убедимся, что он разрешён,введи:</p>
  <pre id="W4CQ" data-lang="bash">sudo ufw status</pre>
  <p id="z3CW">Ты должен увидеть </p>
  <blockquote id="oX8P"><strong>4001 ALLOW Anywhere. </strong></blockquote>
  <p id="WkU9">Если 4001 нет в списке, добавь его: </p>
  <pre id="sb7J" data-lang="bash">sudo ufw allow 4001 sudo ufw status </pre>
  <h4 id="APhB">2. Обновляем узел</h4>
  <p id="Er3v">Давай обновимся.</p>
  <p id="QVf7">Останови узел, нажми Ctrl+C, чтобы выключить.</p>
  <pre id="xrrk" data-lang="bash">dkn-compute-launcher update </pre>
  <p id="NpoH">Это скачает новую версию. Затем снова запустите узел </p>
  <h4 id="qcEB">3. Добавляем bootstrap nodes</h4>
  <p id="2ejU">В .env у тебя DKN_BOOTSTRAP_NODES= пустое. Это как адресная книга — без неё узел не знает, к кому подключаться. Добавим стандартные узлы Dria.</p>
  <ul id="p92j">
    <li id="B3YE">Открой файл .env: </li>
  </ul>
  <pre id="3HkG">nano /root/.dria/dkn-compute-launcher/.env</pre>
  <ul id="ouQx">
    <li id="3kpI">Найди строку DKN_BOOTSTRAP_NODES= и замени её на: </li>
  </ul>
  <pre id="Fw90">DKN_BOOTSTRAP_NODES=/ip4/52.8.51.142/tcp/4001/p2p/16Uiu2HAm9d3sMhNa3N1tN9v9kKANvJABu5gRYH7K6f5UUcUKzuwT,/ip4/52.9.132.242/tcp/4001/p2p/16Uiu2HAmFidHMYbMJG9tS4tHQeXuK3DA5kBAnVcF4hdhsG6jTdqa</pre>
  <p id="BOD2"> Это официальные узлы Dria из документации на GitHub.</p>
  <ul id="MH4l">
    <li id="OQQ4">Сохрани файл: нажми <strong>Ctrl+O</strong>, <strong>Enter</strong>, потом выйди с <strong>Ctrl+X</strong>.</li>
  </ul>
  <h4 id="nyk6">4. Запускаем узел заново</h4>
  <ul id="CJF2">
    <li id="zew6">Запусти: </li>
  </ul>
  <pre id="UPVZ" data-lang="bash">screen -S dria-node dkn-compute-launcher start </pre>
  <p id="LC3i">Нажми Ctrl+A, D, чтобы выйти из screen.</p>
  <ul id="HlJ4">
    <li id="jnC4">Подожди 1-2 минуты, зайди обратно: </li>
  </ul>
  <pre id="FaHW" data-lang="bash">screen -r dria-node</pre>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@vlad_i_mir/CzRkuvFeU_S</guid><link>https://teletype.in/@vlad_i_mir/CzRkuvFeU_S?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir</link><comments>https://teletype.in/@vlad_i_mir/CzRkuvFeU_S?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=vlad_i_mir#comments</comments><dc:creator>vlad_i_mir</dc:creator><title>Telegram-бота с нуля </title><pubDate>Mon, 03 Mar 2025 22:38:52 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/c9/ed/c9ed42bd-faa0-4c9d-9cd6-3b846774ae51.png"></media:content><description><![CDATA[<img src="https://img3.teletype.in/files/2d/d6/2dd65dbb-2167-446b-a922-792558a5a2fd.jpeg"></img>Название: Telegram-бот, созданный для помощи пользователям в регистрации команд на турниры. Бот взаимодействует с пользователями через диалог, собирая данные о команде (дисциплина, название команды, ФИО капитана, контактный номер, дата рождения, город, организация, информация о дополнительных игроках и комментарий), и записывает их в Google Sheets. Бот также поддерживает беседу на тему спорта, используя OpenAI API (gpt-4o) для генерации ответов. Промт для беседы загружается из Google Sheets.]]></description><content:encoded><![CDATA[
  <h2 id="m3sm">1. Описание бота</h2>
  <p id="ok1G"><strong>Название</strong>: PhygitalSportBot<br /> <strong>Описание</strong>:<br /> PhygitalSportBot — это Telegram-бот, созданный для помощи пользователям в регистрации команд на турниры по фиджитал-спорту. Бот взаимодействует с пользователями через диалог, собирая данные о команде (дисциплина, название команды, ФИО капитана, контактный номер, дата рождения, город, организация, информация о дополнительных игроках и комментарий), и записывает их в Google Sheets. Бот также поддерживает беседу на тему фиджитал-спорта, используя OpenAI API (<code><strong>gpt-4o</strong></code>) для генерации ответов. Промт для беседы загружается из Google Sheets.</p>
  <h2 id="XX5R">2. Описание функционала</h2>
  <ul id="MiBM">
    <li id="EsFV"><strong>Приветствие</strong>: Бот начинает диалог с приветственного сообщения и предлагает зарегистрировать команду.</li>
    <li id="9j1D"><strong>Регистрация команды</strong>:</li>
    <ul id="CfNQ">
      <li id="rRSD">Запрашивает название дисциплины (например, Фиджитал-Футбол) и подтверждает выбор.</li>
      <li id="erK5">Запрашивает название команды и подтверждает.</li>
      <li id="Quoq">Запрашивает ФИО капитана, контактный номер, дату рождения, город, организацию — с подтверждением на каждом шаге.</li>
      <li id="7skN">Запрашивает информацию о дополнительных игроках (опционально).</li>
      <li id="sdK3">Запрашивает комментарий (опционально).</li>
      <li id="XRVs">Записывает данные в Google Sheets.</li>
    </ul>
    <li id="1GQs"><strong>Беседа</strong>: Если пользователь не хочет регистрироваться, бот продолжает беседу на тему фиджитал-спорта, используя OpenAI API (<strong>gpt-4o</strong>) и промт из Google Sheets.</li>
    <li id="7B12"><strong>Проверка статуса</strong>: Команда <strong>/status &lt;название_команды&gt;</strong> позволяет проверить, зарегистрирована ли команда.</li>
    <li id="vnUb"><strong>Отмена</strong>: Команда <strong>/cancel </strong>позволяет отменить регистрацию и вернуться к беседе.</li>
  </ul>
  <p id="xLwY"></p>
  <h2 id="0Tzt">3. Требования к серверу</h2>
  <ul id="UkAR">
    <li id="c73f"><strong>Операционная система</strong>: Ubuntu 20.04 или выше (рекомендуется Ubuntu 22.04).</li>
    <li id="Js9i"><strong>Процессор</strong>: Минимум 1 ядро.</li>
    <li id="Jj0W"><strong>Оперативная память</strong>: Минимум 2 ГБ (рекомендуется 4 ГБ).</li>
    <li id="R4FQ"><strong>Дисковое пространство</strong>: Минимум 10 ГБ (для установки зависимостей и хранения логов).</li>
    <li id="zJFa"><strong>Интернет</strong>: Доступ к интернету с возможностью подключения к api.telegram.org и api.openai.com.</li>
    <li id="JCZS"><strong>Порты</strong>: Открытые исходящие порты 80 и 443 для HTTP/HTTPS-запросов.</li>
    <li id="bgum"><strong>Локация сервера</strong>: Сервер должен находиться в стране, поддерживаемой OpenAI (например, Германия, США). Если сервер в неподдерживаемой стране (например, Россия), потребуется VPN.</li>
  </ul>
  <p id="mHXx"></p>
  <h2 id="TGyC">4. Подготовка сервера</h2>
  <h4 id="RLye">4.1. Обновление системы</h4>
  <p id="RhSu">Обновите систему, чтобы установить последние пакеты и исправления безопасности.</p>
  <pre id="zIg3" data-lang="python">apt update &amp;&amp; apt upgrade -y</pre>
  <ul id="UAyd">
    <li id="dc1K"><strong>apt update</strong> — обновляет список доступных пакетов.</li>
    <li id="6m4T"><strong>apt upgrade -y</strong> — обновляет установленные пакеты, <strong>-y </strong>автоматически подтверждает действия.</li>
  </ul>
  <h4 id="A20W">4.2. Установка необходимых пакетов</h4>
  <p id="K42f">Установите базовые утилиты, Python и зависимости:</p>
  <pre id="qe9l" data-lang="python">apt install python3 python3-pip python3-venv nano curl git -y</pre>
  <ul id="v2tA">
    <li id="iIO2"><strong>python3</strong> — интерпретатор Python.</li>
    <li id="QXpK"><strong>python3-pip</strong> — менеджер пакетов для Python.</li>
    <li id="9ATR"><strong>python3-venv</strong> — для создания виртуального окружения.</li>
    <li id="zKJ6"><strong>nano</strong> — текстовый редактор для редактирования файлов.</li>
    <li id="cIm7"><strong>curl </strong>— для проверки подключения к API.</li>
    <li id="3rmT"><strong>git</strong> — для работы с репозиториями (опционально).</li>
    <li id="9lfM"><strong>-y</strong> — автоматически подтверждает установку.</li>
  </ul>
  <h4 id="hjEF">4.3. Создание рабочей директории</h4>
  <p id="lUmL">Создайте директорию для бота:</p>
  <pre id="0LpA" data-lang="python">mkdir /root/bot_env 
cd /root/bot_env</pre>
  <ul id="i5iL">
    <li id="kS9A"><strong>mkdir /root/bot_env</strong> — создаёт директорию /root/bot_env.</li>
    <li id="usqM"><strong>cd /root/bot_env</strong> — переходит в созданную директорию.</li>
  </ul>
  <h4 id="Ofed">4.4. Создание и активация виртуального окружения</h4>
  <p id="GzFJ">Создайте виртуальное окружение, чтобы изолировать зависимости бота:</p>
  <pre id="PM6c" data-lang="python">python3 -m venv /root/bot_env/venv 
source /root/bot_env/venv/bin/activate</pre>
  <ul id="Y1ND">
    <li id="sve9"><strong>python3 -m venv /root/bot_env/venv</strong> — создаёт виртуальное окружение в директории /root/bot_env/venv.</li>
    <li id="7j1E"><strong>source /root/bot_env/venv/bin/activate </strong>— активирует виртуальное окружение (вы увидите (venv) в начале строки терминала).</li>
  </ul>
  <h4 id="ELou">4.5. Установка Python-библиотек</h4>
  <p id="MxU7">Установите все необходимые библиотеки для бота:</p>
  <pre id="tM8g" data-lang="python">pip install telegram python-telegram-bot openai gspread oauth2client tenacity</pre>
  <ul id="Crbb">
    <li id="xnGr"><strong>telegram и python-telegram-bot</strong> — для работы с Telegram API.</li>
    <li id="wUyA"><strong>openai</strong> — для работы с OpenAI API (<strong>gpt-4o</strong>).</li>
    <li id="3dRC"><strong>gspread</strong> — для работы с Google Sheets.</li>
    <li id="XBek"><strong>oauth2client</strong> — для аутентификации в Google Sheets API.</li>
    <li id="gV7j"><strong>tenacity</strong> — для повторных попыток при записи в Google Sheets.</li>
  </ul>
  <p id="A1dD">Пример вывода установки:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="1sXI"><strong><code>Successfully installed telegram-0.0.1 python-telegram-bot-21.11.1 openai-1.65.2 <br />gspread-6.2.0 oauth2client-4.1.3 tenacity-9.0.0</code></strong></p>
  </section>
  <h3 id="UMqj"></h3>
  <h2 id="PlKX">5. Подготовка API-ключей и доступов</h2>
  <h4 id="omrS">5.1. Получение API-ключа OpenAI</h4>
  <ol id="m71e">
    <li id="wpzi"><strong>Создайте учётную запись OpenAI</strong>:</li>
    <ul id="fHEt">
      <li id="rpa8">Перейдите на <strong>https://platform.openai.com/.</strong></li>
      <li id="iQqo">Зарегистрируйтесь или войдите в существующую учётную запись.</li>
    </ul>
    <li id="OlCL"><strong>Получите API-ключ</strong>:</li>
    <ul id="P7K6">
      <li id="AKpm">Перейдите в раздел <a href="https://platform.openai.com/account/api-keys" target="_blank">API Keys</a>.</li>
      <li id="AcTr">Нажмите &quot;Create new secret key&quot;, дайте ключу имя (например, <strong>PhygitalBotKey</strong>).</li>
      <li id="IdtF">Скопируйте ключ (например, <strong>sk-abc123...</strong>). Сохраните его в безопасное место.</li>
    </ul>
    <li id="hdkp"><strong>Добавьте API-ключ в переменную окружения</strong>: </li>
  </ol>
  <p id="uk4z">На сервере добавьте ключ в <strong>/etc/environment</strong> для глобального доступа:</p>
  <pre id="RkWX" data-lang="python">nano /etc/environment</pre>
  <p id="qaGT">Добавьте строку:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="2ksV"><code>OPENAI_API_KEY=&quot;sk-abc123...&quot;</code> </p>
  </section>
  <p id="KJQW">Замените <strong>sk-abc123...</strong> на ваш API-ключ.<br /> Сохраните файл (<strong>Ctrl + O, Enter, Ctrl + X</strong>) и примените изменения:<br /></p>
  <pre id="jWs1" data-lang="python">source /etc/environment</pre>
  <p id="HyXc"> Проверьте, что ключ доступен:</p>
  <pre id="145t" data-lang="python">echo $OPENAI_API_KEY </pre>
  <p id="JlL4">Вывод должен быть вашим ключом: sk-abc123....</p>
  <h4 id="bnBB">5.2. Получение токена Telegram</h4>
  <ol id="HhSv">
    <li id="OM8u"><strong>Создайте бота в Telegram</strong>:</li>
    <ul id="jC7f">
      <li id="XtdM">Откройте Telegram и найдите @BotFather.</li>
      <li id="pgu9">Отправьте <strong>/start.</strong></li>
      <li id="n0La">Отправьте <strong>/newbot.</strong></li>
      <li id="oWjE">Следуйте инструкциям: задайте имя бота (например, <strong>PhygitalSportBot</strong>) и username (например, <strong>@PhygitalSportBot</strong>).</li>
      <li id="LlrE">После создания бота вы получите токен, например: <strong>7717227973:AAGwsD0GetKrPtn-OuMyoV_uBMRIZXdiS7U.</strong></li>
      <li id="ASoA">Скопируйте токен и сохраните его в безопасное место.</li>
    </ul>
  </ol>
  <h4 id="bvUw">5.3. Настройка доступа к Google Sheets</h4>
  <ol id="C98w">
    <li id="erEO"><strong>Создайте файл <em>credentials.json</em></strong><em><u>:</u></em></li>
    <ul id="my9X">
      <li id="WchR">Перейдите в Google Cloud Console: <strong>https://console.cloud.google.com.</strong></li>
      <li id="LjRd">Создайте новый проект (например, <strong>PhygitalBot</strong>).</li>
      <li id="zbhd">Включите API:</li>
      <ul id="TzzS">
        <li id="dBkt">В разделе &quot;APIs &amp; Services&quot; → &quot;Library&quot; найдите и включите <strong>Google Sheets API</strong> и <strong>Google Drive API</strong>.</li>
      </ul>
      <li id="8nip">Создайте Service Account:</li>
      <ul id="XPdV">
        <li id="7XYe">Перейдите в &quot;IAM &amp; Admin&quot; → &quot;Service Accounts&quot;.</li>
        <li id="fyID">Нажмите &quot;Create Service Account&quot;.</li>
        <li id="KKMc">Укажите имя (например, <strong>phygital-bot-service-account</strong>), нажмите &quot;Create and Continue&quot;, пропустите шаг с ролями, нажмите &quot;Done&quot;.</li>
      </ul>
      <li id="mW4g">Создайте ключ:</li>
      <ul id="Zb4d">
        <li id="gBr2">В списке Service Accounts выберите созданный аккаунт, перейдите на вкладку &quot;Keys&quot;.</li>
        <li id="4nS1">Нажмите &quot;Add Key&quot; → &quot;Create New Key&quot;, выберите &quot;JSON&quot;, нажмите &quot;Create&quot;.</li>
        <li id="iZXd">Файл <strong>phygital-bot-XXXXX-XXXXXXXXXXXX.json</strong> скачается на ваш компьютер.</li>
      </ul>
    </ul>
    <li id="Ew3A"><strong>Перенесите credentials.json на сервер</strong>: Создайте директорию для файла:<br /> </li>
  </ol>
  <pre id="Tbkl" data-lang="python">mkdir -p /root/bot_env/credentials</pre>
  <p id="Yqe8"> Скопируйте файл на сервер:<br /></p>
  <pre id="ISzk" data-lang="python">scp /path/to/phygital-bot-XXXXX-XXXXXXXXXXXX.json root@your-server-ip:/root/bot_env/credentials/credentials.json </pre>
  <p id="FPSN">Замените<strong> /path/to/phygital-bot-XXXXX-XXXXXXXXXXXX.json</strong> на путь к файлу на вашем компьютере и <strong>your-server-ip</strong> на IP-адрес сервера.<br /></p>
  <p id="TSCB">Проверьте, что файл на месте:</p>
  <pre id="l20F" data-lang="python">ls -l /root/bot_env/credentials/credentials.json</pre>
  <p id="nfJc"></p>
  <ol id="W2bS">
    <li id="Bsx6"><strong>Дайте доступ к Google Sheet</strong>:</li>
    <ul id="oSFD">
      <li id="pxDt">Откройте Google Sheet: <strong>https://docs.google.com/spreadsheets/d/1whGZ1RefscCSiVNnVUGaXWiISnXa59EhXqxwmTXG3Vo/edit.</strong></li>
      <li id="BbJG">Нажмите &quot;Share&quot; и добавьте <strong>client_email</strong> из <strong>credentials.json</strong> (например, <strong>phygital-bot-service-account@your-project-id.iam.gserviceaccount.com</strong>) с правами &quot;Editor&quot;.</li>
    </ul>
  </ol>
  <p id="ywvI"></p>
  <h2 id="kKFF">6. Пошаговая инструкция установки</h2>
  <h4 id="c1X0">6.1. Создание файла bot.py</h4>
  <p id="yRKJ">Создайте файл bot.py:</p>
  <pre id="IIE2" data-lang="python">nano /root/bot_env/bot.py</pre>
  <p id="zxcO">Вставьте следующий код:</p>
  <pre id="n0t1" data-lang="python">import telegram
from telegram import Update, ReplyKeyboardMarkup, ReplyKeyboardRemove
from telegram.ext import Application, CommandHandler, MessageHandler, ContextTypes, ConversationHandler
from telegram.ext import filters
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import logging
from openai import AsyncOpenAI
from datetime import datetime
import re
from tenacity import retry, stop_after_attempt, wait_fixed
import os

# Настройка логирования
logging.basicConfig(filename=&#x27;/root/bot_env/bot.log&#x27;, level=logging.INFO, 
                    format=&#x27;%(asctime)s - %(levelname)s - %(message)s&#x27;)

# Токен бота
TOKEN = &#x27;7717227973:AAGwsD0GetKrPtn-OuMyoV_uBMRIZXdiS7U&#x27;  # Замените на ваш токен Telegram

# API-ключ OpenAI из переменной окружения
OPENAI_API_KEY = os.getenv(&#x27;OPENAI_API_KEY&#x27;)

# Инициализация асинхронного клиента OpenAI
client = AsyncOpenAI(api_key=OPENAI_API_KEY)

# Настройка Google Sheets
scope = [&#x27;https://spreadsheets.google.com/feeds&#x27;, &#x27;https://www.googleapis.com/auth/drive&#x27;]
creds = ServiceAccountCredentials.from_json_keyfile_name(&#x27;/root/bot_env/credentials/credentials.json&#x27;, scope)
client_gspread = gspread.authorize(creds)
sheet = client_gspread.open_by_key(&#x27;1whGZ1RefscCSiVNnVUGaXWiISnXa59EhXqxwmTXG3Vo&#x27;)
prompt_sheet = sheet.worksheet(&#x27;promt&#x27;)
registration_sheet = sheet.worksheet(&#x27;registration&#x27;)

# Кэшируем данные из Google Sheets при запуске
PROMPT_CONTEXT = &quot;\n&quot;.join(prompt_sheet.col_values(1)[1:]) if len(prompt_sheet.col_values(1)) &gt; 1 else &quot;Нет данных для контекста&quot;
logging.info(f&quot;Loaded PROMPT_CONTEXT: {PROMPT_CONTEXT}&quot;)
EXISTING_TEAMS = set(registration_sheet.col_values(3)[1:])  # Кэшируем названия команд

# Кэш для ответов ChatGPT
CHATGPT_RESPONSE_CACHE = {}

# Асинхронная функция для запросов к ChatGPT
async def get_chatgpt_response(prompt):
    # Проверяем, есть ли ответ в кэше
    if prompt in CHATGPT_RESPONSE_CACHE:
        return CHATGPT_RESPONSE_CACHE[prompt]

    try:
        response = await client.chat.completions.create(
            model=&quot;gpt-4o&quot;,
            messages=[
                {&quot;role&quot;: &quot;system&quot;, &quot;content&quot;: &quot;Ты виртуальный помощник по фиджитал-спорту. Будь дружелюбным и энергичным!&quot;},
                {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: prompt}
            ],
            temperature=0.7,
            max_tokens=500
        )
        answer = response.choices[0].message.content.strip()
        # Сохраняем в кэш
        CHATGPT_RESPONSE_CACHE[prompt] = answer
        return answer
    except Exception as e:
        logging.error(f&quot;Ошибка при запросе к ChatGPT: {str(e)}&quot;)
        return &quot;Извините, произошла ошибка при получении ответа от ИИ.&quot;

# Состояния для ConversationHandler
CHAT, DISCIPLINE, DISCIPLINE_CONFIRM, TEAM_NAME, TEAM_NAME_CONFIRM, FULL_NAME, FULL_NAME_CONFIRM, PHONE, PHONE_CONFIRM, BIRTH_DATE, BIRTH_DATE_CONFIRM, CITY, CITY_CONFIRM, ORGANIZATION, ORGANIZATION_CONFIRM, ADD_PLAYER, COMMENT = range(17)

# Обработчик текстовых сообщений (без команды /talk)
async def handle_text(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; None:
    user_message = update.message.text.strip().lower()
    if not user_message:
        await update.message.reply_text(&quot;Пожалуйста, напиши свой вопрос или сообщение.&quot;)
        return

    # Если пользователь в состоянии CHAT, продолжаем беседу
    if context.user_data.get(&#x27;state&#x27;) == &#x27;CHAT&#x27;:
        prompt = f&quot;Опираясь на следующий контекст:\n{PROMPT_CONTEXT}\nПродолжи беседу на тему фиджитал-спорта. Пользователь написал: {user_message}&quot;
        response = await get_chatgpt_response(prompt)
        await update.message.reply_text(response)
        return

    # Проверяем, не хочет ли пользователь зарегистрироваться
    if &quot;регистр&quot; in user_message or &quot;записаться&quot; in user_message:
        context.user_data[&#x27;state&#x27;] = &#x27;REGISTRATION&#x27;
        await update.message.reply_text(
            &quot;Отлично! Давай зарегистрируем твою команду. Сначала укажи название дисциплины (например, Фиджитал-Футбол).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return DISCIPLINE

    # Обрабатываем обычные сообщения через ChatGPT
    prompt = f&quot;Опираясь на следующий контекст:\n{PROMPT_CONTEXT}\nОтветь на вопрос: {user_message}&quot;
    response = await get_chatgpt_response(prompt)
    await update.message.reply_text(response)

# Команда /start для начала диалога
async def start_registration(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    logging.info(&quot;Received /start command&quot;)
    context.user_data.clear()  # Очищаем старые данные
    context.user_data[&#x27;state&#x27;] = &#x27;CHAT&#x27;  # Устанавливаем состояние CHAT
    context.user_data[&#x27;registration&#x27;] = {}
    context.user_data[&#x27;players&#x27;] = []  # Список для хранения игроков

    # Приветствие (без обращения к ChatGPT для скорости)
    await update.message.reply_text(&quot;Привет! Я твой помощник по фиджитал-спорту! 🏅 Фиджитал-спорт — это крутое сочетание физической активности и цифровых технологий. &quot;
                                    &quot;Давай поговорим об этом! Знаешь, какие дисциплины есть в фиджитал-спорте? Например, фиджитал-футбол или фиджитал-гонки!&quot;)

    # Предложение регистрации
    reply_keyboard = [[&#x27;да&#x27;, &#x27;нет&#x27;]]
    await update.message.reply_text(
        &quot;Кстати, хочешь зарегистрировать свою команду на турнир? (да/нет)&quot;,
        reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
    )
    return CHAT

# Обработчик состояния CHAT
async def chat_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    user_message = update.message.text.strip().lower()
    logging.info(f&quot;Received message in CHAT state: {user_message}&quot;)

    if user_message in [&#x27;да&#x27;, &#x27;yes&#x27;, &#x27;y&#x27;]:
        logging.info(&quot;User agreed to registration, moving to DISCIPLINE state&quot;)
        context.user_data[&#x27;state&#x27;] = &#x27;REGISTRATION&#x27;
        await update.message.reply_text(
            &quot;Отлично! Давай зарегистрируем твою команду. Сначала укажи название дисциплины (например, Фиджитал-Футбол).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return DISCIPLINE
    elif user_message in [&#x27;нет&#x27;, &#x27;no&#x27;, &#x27;n&#x27;]:
        await update.message.reply_text(
            &quot;Хорошо, давай продолжим говорить о фиджитал-спорте! Что ты думаешь о сочетании физической активности и цифровых технологий?&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        context.user_data[&#x27;state&#x27;] = &#x27;CHAT&#x27;
        return CHAT
    else:
        # Продолжаем беседу
        prompt = f&quot;Опираясь на следующий контекст:\n{PROMPT_CONTEXT}\nПродолжи беседу на тему фиджитал-спорта. Пользователь написал: {user_message}&quot;
        response = await get_chatgpt_response(prompt)
        await update.message.reply_text(response)

        # Повторно предлагаем регистрацию
        reply_keyboard = [[&#x27;да&#x27;, &#x27;нет&#x27;]]
        await update.message.reply_text(
            &quot;Кстати, хочешь зарегистрировать свою команду? (да/нет)&quot;,
            reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
        )
        return CHAT

# Обработчик названия дисциплины
async def discipline(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    discipline = update.message.text.strip().capitalize()
    logging.info(f&quot;Received discipline: {discipline}&quot;)
    context.user_data[&#x27;registration&#x27;][&#x27;discipline&#x27;] = discipline
    reply_keyboard = [[&#x27;да&#x27;, &#x27;нет&#x27;]]
    await update.message.reply_text(
        f&quot;Дисциплина: {discipline}. Всё верно?&quot;,
        reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
    )
    return DISCIPLINE_CONFIRM

async def discipline_confirm(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    response = update.message.text.strip().lower()
    logging.info(f&quot;Received response in DISCIPLINE_CONFIRM state: {response}&quot;)
    if response == &#x27;да&#x27;:
        await update.message.reply_text(
            &quot;Отлично! Теперь укажи название команды (например, Молния).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return TEAM_NAME
    elif response == &#x27;нет&#x27;:
        await update.message.reply_text(
            &quot;Давай исправим. Укажи название дисциплины (например, Фиджитал-Футбол).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return DISCIPLINE
    else:
        await update.message.reply_text(&quot;Пожалуйста, выбери &#x27;да&#x27; или &#x27;нет&#x27;.&quot;)
        return DISCIPLINE_CONFIRM

# Обработчик названия команды
async def team_name(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    team_name = update.message.text.strip().capitalize()
    logging.info(f&quot;Received team name: {team_name}&quot;)
    context.user_data[&#x27;registration&#x27;][&#x27;team_name&#x27;] = team_name
    reply_keyboard = [[&#x27;да&#x27;, &#x27;нет&#x27;]]
    await update.message.reply_text(
        f&quot;Команда: {team_name}. Всё верно?&quot;,
        reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
    )
    return TEAM_NAME_CONFIRM

async def team_name_confirm(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    response = update.message.text.strip().lower()
    logging.info(f&quot;Received response in TEAM_NAME_CONFIRM state: {response}&quot;)
    if response == &#x27;да&#x27;:
        await update.message.reply_text(
            &quot;Супер! Теперь укажи ФИО капитана (например, Иванов Иван Иванович).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return FULL_NAME
    elif response == &#x27;нет&#x27;:
        await update.message.reply_text(
            &quot;Давай исправим. Укажи название команды (например, Молния).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return TEAM_NAME
    else:
        await update.message.reply_text(&quot;Пожалуйста, выбери &#x27;да&#x27; или &#x27;нет&#x27;.&quot;)
        return TEAM_NAME_CONFIRM

# Обработчик ФИО
async def full_name(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    full_name = update.message.text.strip()
    name_parts = full_name.split()
    logging.info(f&quot;Received full name: {full_name}&quot;)
    if len(name_parts) != 3:
        await update.message.reply_text(&quot;Пожалуйста, укажи полное ФИО (Имя Фамилия Отчество, например, Иванов Иван Иванович).&quot;)
        return FULL_NAME
    formatted_name = &quot; &quot;.join(part.capitalize() for part in name_parts)
    context.user_data[&#x27;registration&#x27;][&#x27;full_name&#x27;] = formatted_name
    reply_keyboard = [[&#x27;да&#x27;, &#x27;нет&#x27;]]
    await update.message.reply_text(
        f&quot;ФИО капитана: {formatted_name}. Всё верно?&quot;,
        reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
    )
    return FULL_NAME_CONFIRM

async def full_name_confirm(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    response = update.message.text.strip().lower()
    logging.info(f&quot;Received response in FULL_NAME_CONFIRM state: {response}&quot;)
    if response == &#x27;да&#x27;:
        await update.message.reply_text(
            &quot;Отлично! Теперь укажи контактный телефон (например, 5555555). Формат будет преобразован в 555-55-55.&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return PHONE
    elif response == &#x27;нет&#x27;:
        await update.message.reply_text(
            &quot;Давай исправим. Укажи ФИО заново (например, Иванов Иван Иванович).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return FULL_NAME
    else:
        await update.message.reply_text(&quot;Пожалуйста, выбери &#x27;да&#x27; или &#x27;нет&#x27;.&quot;)
        return FULL_NAME_CONFIRM

# Обработчик телефона
async def phone(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    phone = update.message.text.strip()
    phone = re.sub(r&#x27;\D&#x27;, &#x27;&#x27;, phone)
    logging.info(f&quot;Received phone: {phone}&quot;)
    if len(phone) != 7:
        await update.message.reply_text(&quot;Пожалуйста, укажи 7 цифр для номера телефона (например, 5555555). Формат будет преобразован в 555-55-55.&quot;)
        return PHONE
    formatted_phone = f&quot;{phone[:3]}-{phone[3:5]}-{phone[5:7]}&quot;
    context.user_data[&#x27;registration&#x27;][&#x27;phone&#x27;] = formatted_phone
    reply_keyboard = [[&#x27;да&#x27;, &#x27;нет&#x27;]]
    await update.message.reply_text(
        f&quot;Телефон: {formatted_phone}. Всё верно?&quot;,
        reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
    )
    return PHONE_CONFIRM

async def phone_confirm(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    response = update.message.text.strip().lower()
    logging.info(f&quot;Received response in PHONE_CONFIRM state: {response}&quot;)
    if response == &#x27;да&#x27;:
        await update.message.reply_text(
            &quot;Спасибо! Теперь укажи дату рождения капитана (в формате дд.мм.гг, например, 01.01.00). &quot;
            &quot;Можно также вводить в формате дд,мм,гг (например, 01,01,00) или ддммгггг (например, 01012000).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return BIRTH_DATE
    elif response == &#x27;нет&#x27;:
        await update.message.reply_text(
            &quot;Давай исправим. Укажи контактный телефон заново (например, 5555555).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return PHONE
    else:
        await update.message.reply_text(&quot;Пожалуйста, выбери &#x27;да&#x27; или &#x27;нет&#x27;.&quot;)
        return PHONE_CONFIRM

# Обработчик даты рождения
async def birth_date(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    birth_date = update.message.text.strip()
    logging.info(f&quot;Received birth date: {birth_date}&quot;)
    if re.match(r&#x27;^\d{2},\d{2},\d{2}$&#x27;, birth_date):
        birth_date = birth_date.replace(&#x27;,&#x27;, &#x27;.&#x27;)
    elif re.match(r&#x27;^\d{8}$&#x27;, birth_date):
        birth_date = f&quot;{birth_date[:2]}.{birth_date[2:4]}.{birth_date[4:6]}&quot;
    elif not re.match(r&#x27;^\d{2}\.\d{2}\.\d{2}$&#x27;, birth_date):
        await update.message.reply_text(&quot;Пожалуйста, укажи дату рождения в формате дд.мм.гг (например, 01.01.00). &quot;
                                        &quot;Можно также вводить в формате дд,мм,гг (например, 01,01,00) или ддммгггг (например, 01012000).&quot;)
        return BIRTH_DATE

    try:
        birth_date_obj = datetime.strptime(birth_date, &#x27;%d.%m.%y&#x27;)
        today = datetime.now()
        age = today.year - birth_date_obj.year - ((today.month, today.day) &lt; (birth_date_obj.month, birth_date_obj.day))
        context.user_data[&#x27;registration&#x27;][&#x27;birth_date&#x27;] = birth_date
        context.user_data[&#x27;registration&#x27;][&#x27;age&#x27;] = age
        reply_keyboard = [[&#x27;да&#x27;, &#x27;нет&#x27;]]
        await update.message.reply_text(
            f&quot;Дата рождения: {birth_date}, возраст: {age} лет. Всё верно?&quot;,
            reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
        )
    except ValueError:
        await update.message.reply_text(&quot;Неверный формат даты. Укажи дату в формате дд.мм.гг (например, 01.01.00).&quot;)
        return BIRTH_DATE
    return BIRTH_DATE_CONFIRM

async def birth_date_confirm(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    response = update.message.text.strip().lower()
    logging.info(f&quot;Received response in BIRTH_DATE_CONFIRM state: {response}&quot;)
    if response == &#x27;да&#x27;:
        await update.message.reply_text(
            &quot;Спасибо! Теперь укажи город проживания (например, Москва).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return CITY
    elif response == &#x27;нет&#x27;:
        await update.message.reply_text(
            &quot;Давай исправим. Укажи дату рождения заново (в формате дд.мм.гг, например, 01.01.00).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return BIRTH_DATE
    else:
        await update.message.reply_text(&quot;Пожалуйста, выбери &#x27;да&#x27; или &#x27;нет&#x27;.&quot;)
        return BIRTH_DATE_CONFIRM

# Обработчик города
async def city(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    city = update.message.text.strip().capitalize()
    logging.info(f&quot;Received city: {city}&quot;)
    context.user_data[&#x27;registration&#x27;][&#x27;city&#x27;] = city
    reply_keyboard = [[&#x27;да&#x27;, &#x27;нет&#x27;]]
    await update.message.reply_text(
        f&quot;Город: {city}. Всё верно?&quot;,
        reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
    )
    return CITY_CONFIRM

async def city_confirm(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    response = update.message.text.strip().lower()
    logging.info(f&quot;Received response in CITY_CONFIRM state: {response}&quot;)
    if response == &#x27;да&#x27;:
        await update.message.reply_text(
            &quot;Укажи организацию (цех) или учебное заведение, которое вы представляете (например, Цех №5 или МГУ).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return ORGANIZATION
    elif response == &#x27;нет&#x27;:
        await update.message.reply_text(
            &quot;Давай исправим. Укажи город проживания заново (например, Москва).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return CITY
    else:
        await update.message.reply_text(&quot;Пожалуйста, выбери &#x27;да&#x27; или &#x27;нет&#x27;.&quot;)
        return CITY_CONFIRM

# Обработчик организации
async def organization(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    organization = update.message.text.strip()
    logging.info(f&quot;Received organization: {organization}&quot;)
    context.user_data[&#x27;registration&#x27;][&#x27;organization&#x27;] = organization
    reply_keyboard = [[&#x27;да&#x27;, &#x27;нет&#x27;]]
    await update.message.reply_text(
        f&quot;Организация: {organization}. Всё верно?&quot;,
        reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
    )
    return ORGANIZATION_CONFIRM

async def organization_confirm(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    response = update.message.text.strip().lower()
    logging.info(f&quot;Received response in ORGANIZATION_CONFIRM state: {response}&quot;)
    if response == &#x27;да&#x27;:
        await update.message.reply_text(
            &quot;Хочешь добавить других игроков в команду? (да/нет)&quot;,
            reply_markup=ReplyKeyboardMarkup([[&#x27;да&#x27;, &#x27;нет&#x27;]], one_time_keyboard=True)
        )
        return ADD_PLAYER
    elif response == &#x27;нет&#x27;:
        await update.message.reply_text(
            &quot;Давай исправим. Укажи организацию заново (например, Цех №5 или МГУ).&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return ORGANIZATION
    else:
        await update.message.reply_text(&quot;Пожалуйста, выбери &#x27;да&#x27; или &#x27;нет&#x27;.&quot;)
        return ORGANIZATION_CONFIRM

# Обработчик добавления игроков
async def add_player(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    response = update.message.text.strip().lower()
    logging.info(f&quot;Received response in ADD_PLAYER state: {response}&quot;)
    if response == &#x27;да&#x27;:
        await update.message.reply_text(&quot;Укажи ФИО и дату рождения игрока (например, Петров Петр Петрович 02.02.02).&quot;)
        return ADD_PLAYER
    elif response == &#x27;нет&#x27;:
        players = context.user_data.get(&#x27;players&#x27;, [])
        await update.message.reply_text(
            &quot;Хочешь добавить комментарий? (Если нет, напиши &#x27;нет&#x27;). Максимальная длина — 500 символов.&quot;,
            reply_markup=ReplyKeyboardRemove()
        )
        return COMMENT
    else:
        player_data = update.message.text.strip()
        context.user_data[&#x27;players&#x27;].append(player_data)
        reply_keyboard = [[&#x27;да&#x27;, &#x27;нет&#x27;]]
        await update.message.reply_text(
            f&quot;Игрок добавлен: {player_data}. Хочешь добавить ещё одного игрока?&quot;,
            reply_markup=ReplyKeyboardMarkup(reply_keyboard, one_time_keyboard=True)
        )
        return ADD_PLAYER

# Обработчик комментария
async def comment(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    comment = update.message.text.strip()
    logging.info(f&quot;Received comment: {comment}&quot;)
    if comment.lower() == &#x27;нет&#x27;:
        comment = &#x27;&#x27;
    elif len(comment) &gt; 500:
        await update.message.reply_text(&quot;Комментарий слишком длинный! Пожалуйста, укороти его до 500 символов.&quot;)
        return COMMENT
    context.user_data[&#x27;registration&#x27;][&#x27;comment&#x27;] = comment

    # Проверка на дублирование команды (используем кэш)
    team_name = context.user_data[&#x27;registration&#x27;][&#x27;team_name&#x27;]
    if team_name in EXISTING_TEAMS:
        await update.message.reply_text(f&quot;Команда &#x27;{team_name}&#x27; уже зарегистрирована! Если это другая команда, укажи другое название. Напиши новое название команды.&quot;)
        return TEAM_NAME

    # Собираем данные для записи
    registration_data = context.user_data[&#x27;registration&#x27;]
    players = context.user_data.get(&#x27;players&#x27;, [])
    date_registered = datetime.now().strftime(&quot;%H:%M %d.%m.%y&quot;)
    row = [
        date_registered,
        registration_data[&#x27;discipline&#x27;],
        registration_data[&#x27;team_name&#x27;],
        registration_data[&#x27;full_name&#x27;],
        registration_data[&#x27;phone&#x27;],
        f&quot;{registration_data[&#x27;birth_date&#x27;]} ({registration_data[&#x27;age&#x27;]})&quot;,
        registration_data[&#x27;city&#x27;],
        registration_data[&#x27;organization&#x27;],
        f&quot;{comment}; Игроки: {&#x27;; &#x27;.join(players) if players else &#x27;&#x27;}&quot;  # Добавляем игроков в комментарий
    ]

    # Записываем данные в Google Sheets с повторными попытками
    @retry(stop=stop_after_attempt(3), wait=wait_fixed(2))
    def append_to_sheet(row):
        registration_sheet.append_row(row)

    try:
        append_to_sheet(row)
        EXISTING_TEAMS.add(team_name)  # Обновляем кэш
        await update.message.reply_text(&quot;Регистрация завершена! 🎉 Данные вашей команды записаны. Что ещё могу сделать для тебя? &quot;
                                        &quot;Давай продолжим говорить о фиджитал-спорте! Как думаешь, какая дисциплина самая интересная?&quot;)
        context.user_data[&#x27;state&#x27;] = &#x27;CHAT&#x27;  # Переходим в режим беседы
        return CHAT
    except Exception as e:
        logging.error(f&quot;Ошибка при записи в Google Sheets: {str(e)}&quot;)
        await update.message.reply_text(&quot;Произошла ошибка при записи данных. Пожалуйста, попробуй снова позже.&quot;)
        return ConversationHandler.END

# Обработчик отмены
async def cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; int:
    await update.message.reply_text(&quot;Регистрация отменена. Давай продолжим говорить о фиджитал-спорте! &quot;
                                    &quot;Какие у тебя планы на предстоящий турнир?&quot;)
    context.user_data[&#x27;state&#x27;] = &#x27;CHAT&#x27;
    return CHAT

# Команда /status для проверки статуса регистрации
async def status(update: Update, context: ContextTypes.DEFAULT_TYPE) -&gt; None:
    if not context.args:
        await update.message.reply_text(&quot;Пожалуйста, укажи название команды после команды /status, например: /status Молния&quot;)
        return

    team_name = &quot; &quot;.join(context.args).capitalize()
    try:
        all_rows = registration_sheet.get_all_values()
        found = False
        for row in all_rows[1:]:  # Пропускаем заголовок
            if row[2] == team_name:  # Колонка 3 - название команды
                await update.message.reply_text(
                    f&quot;Команда &#x27;{team_name}&#x27; зарегистрирована!\n&quot;
                    f&quot;Дисциплина: {row[1]}\n&quot;
                    f&quot;Капитан: {row[3]}\n&quot;
                    f&quot;Телефон: {row[4]}\n&quot;
                    f&quot;Дата рождения: {row[5]}\n&quot;
                    f&quot;Город: {row[6]}\n&quot;
                    f&quot;Организация: {row[7]}\n&quot;
                    f&quot;Комментарий: {row[8]}&quot;
                )
                found = True
                break
        if not found:
            await update.message.reply_text(f&quot;Команда &#x27;{team_name}&#x27; не найдена. Зарегистрируй её с помощью /start!&quot;)
    except Exception as e:
        logging.error(f&quot;Ошибка при проверке статуса: {str(e)}&quot;)
        await update.message.reply_text(&quot;Произошла ошибка при проверке статуса. Попробуй снова позже.&quot;)

# Основная функция для запуска бота
def main() -&gt; None:
    logging.info(&quot;Starting bot...&quot;)
    application = Application.builder().token(TOKEN).build()

    # Добавляем ConversationHandler для регистрации
    conv_handler = ConversationHandler(
        entry_points=[CommandHandler(&#x27;start&#x27;, start_registration)],
        states={
            CHAT: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, chat_handler)],
            DISCIPLINE: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, discipline)],
            DISCIPLINE_CONFIRM: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, discipline_confirm)],
            TEAM_NAME: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, team_name)],
            TEAM_NAME_CONFIRM: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, team_name_confirm&#x27;)],
            FULL_NAME: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, full_name)],
            FULL_NAME_CONFIRM: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, full_name_confirm)],
            PHONE: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, phone)],
            PHONE_CONFIRM: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, phone_confirm)],
            BIRTH_DATE: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, birth_date)],
            BIRTH_DATE_CONFIRM: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, birth_date_confirm)],
            CITY: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, city)],
            CITY_CONFIRM: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, city_confirm)],
            ORGANIZATION: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, organization)],
            ORGANIZATION_CONFIRM: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, organization_confirm)],
            ADD_PLAYER: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, add_player)],
            COMMENT: [MessageHandler(filters.TEXT &amp; ~filters.COMMAND, comment)],
        },
        fallbacks=[CommandHandler(&#x27;cancel&#x27;, cancel)]
    )

    application.add_handler(conv_handler)
    application.add_handler(CommandHandler(&#x27;status&#x27;, status))
    application.add_handler(MessageHandler(filters.TEXT &amp; ~filters.COMMAND, handle_text))
    application.run_polling()

if __name__ == &#x27;__main__&#x27;:
    main()</pre>
  <p id="zpnt">Сохраните файл (<strong>Ctrl + O, Enter, Ctrl + X</strong>).</p>
  <p id="DyzQ"></p>
  <h4 id="281p">6.2. Настройка автозапуска</h4>
  <p id="ea7N">Чтобы бот запускался автоматически после перезагрузки сервера:</p>
  <pre id="sLA4" data-lang="python">crontab -e</pre>
  <p id="ERub">Выберите редактор (например, <strong>1</strong> для <strong>nano</strong>), затем добавьте:</p>
  <pre id="Dzzy" data-lang="python">@reboot /bin/bash -c &quot;source /root/bot_env/venv/bin/activate &amp;&amp; nohup /root/bot_env/venv/bin/python3 /root/bot_env/bot.py &amp;&quot;</pre>
  <p id="iuzc">Сохраните (<strong>Ctrl + O, Enter, Ctrl + X</strong>).</p>
  <p id="OnjX"></p>
  <h2 id="hR6m">7. Процедуры запуска бота</h2>
  <h4 id="Rylo">7.1. Первый запуск</h4>
  <p id="lfd3">Запустите бота вручную для проверки:</p>
  <pre id="3BM2" data-lang="python">source /root/bot_env/venv/bin/activate 
cd /root/bot_env 
nohup /root/bot_env/venv/bin/python3 bot.py &amp;</pre>
  <ul id="r91j">
    <li id="Zn8L"><strong>source /root/bot_env/venv/bin/activate</strong> — активирует виртуальное окружение.</li>
    <li id="6X66"><strong>cd /root/bot_env</strong> — переходит в директорию бота.</li>
    <li id="yHxs"><strong>nohup /root/bot_env/venv/bin/python3 bot.py &amp;</strong> — запускает бота в фоновом режиме, игнорируя закрытие терминала.</li>
  </ul>
  <p id="FLw5"></p>
  <h4 id="zPAC">7.2. Проверка логов</h4>
  <pre id="YQ5A" data-lang="python">tail -f /root/bot_env/bot.log</pre>
  <p id="oS6G">Ожидаемый вывод:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="uK0k"><code>2025-03-03 20:00:00,123 - INFO - Starting bot... 2025-03-03 20:00:00,456 - INFO - HTTP Request: POST https://api.telegram.org/bot7717227973:AAGwsD0GetKrPtn-OuMyoV_uBMRIZXdiS7U/getUpdates &quot;HTTP/1.1 200 OK&quot;</code></p>
  </section>
  <h4 id="t3nq"></h4>
  <h3 id="uABY">7.3. Проверка процесса</h3>
  <pre id="YaOz" data-lang="python">ps aux | grep python</pre>
  <p id="g3im">Ожидаемый вывод:</p>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="3vVO"><code>root 12345 0.1 0.2 123456 7890 ? S 20:00 0:01 /root/bot_env/venv/bin/python3 bot.py</code></p>
  </section>
  <h2 id="Fecp"></h2>
  <h2 id="K1Jk">8. Процедуры внесения изменений в промт в Google Sheets</h2>
  <h4 id="4NGU">8.1. Изменение промта</h4>
  <ol id="sWQI">
    <li id="RSIn">Откройте Google Sheet: <strong>https://docs.google.com/spreadsheets/d/1whGZ1RefscCSiVNnVUGaXWiISnXa59EhXqxwmTXG3Vo/edit.</strong></li>
    <li id="hHkH">Перейдите на лист promt.</li>
    <li id="gdN5">Измените текст в первом столбце (A) — это промт, который бот использует для беседы.</li>
    <li id="F57s">Сохраните изменения (Google Sheets делает это автоматически).</li>
  </ol>
  <h4 id="7Jhg">8.2. Полный рестарт бота</h4>
  <p id="M0UN">Бот загружает промт при запуске, поэтому нужно перезапустить его:</p>
  <p id="jK8H"><strong>Остановите текущий процесс</strong>:</p>
  <pre id="ofSm" data-lang="python">ps aux | grep python 
kill -9 &lt;PID&gt;</pre>
  <p id="s06A"><strong>Запустите бота заново</strong>:</p>
  <pre id="8M7Z" data-lang="python">source /root/bot_env/venv/bin/activate 
cd /root/bot_env 
nohup /root/bot_env/venv/bin/python3 bot.py &amp;</pre>
  <h4 id="UZ3c">8.3. Полный повторный запуск сервера</h4>
  <p id="nfD0">Если вы хотите перезапустить сервер:</p>
  <p id="0g2V"><strong>Остановите бота</strong>:</p>
  <pre id="0g2V" data-lang="python">ps aux | grep python kill -9 &lt;PID&gt;</pre>
  <p id="voua"><strong>Перезагрузите сервер</strong>:</p>
  <pre id="voua" data-lang="python">reboot</pre>
  <p id="Wz8S"><strong>Проверьте, что бот запустился</strong>: После перезагрузки подключитесь к серверу и проверьте:</p>
  <pre id="Wz8S" data-lang="python">ps aux | grep python tail -f /root/bot_env/bot.log</pre>
  <p id="Wz8S"> Бот должен автоматически запуститься благодаря crontab.</p>
  <p id="fUZZ"></p>
  <h2 id="zyNl">9. Полезные команды для тестирования и пояснения результатов</h2>
  <h4 id="qGxQ">9.1. Проверка процесса</h4>
  <pre id="918V" data-lang="python">ps aux | grep python</pre>
  <ul id="cYGw">
    <li id="J961"><strong>Ожидаемый результат</strong>: Вы должны увидеть процесс <strong>bot.py</strong>, например:</li>
  </ul>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="3s53"><code>root 12345 0.1 0.2 123456 7890 ? S 20:00 0:01 /root/bot_env/venv/bin/python3 bot.py</code></p>
  </section>
  <ul id="vjdJ">
    <li id="pmQQ"><strong>Пояснение</strong>: Если процесс есть, бот запущен. Если нет, проверьте логи.</li>
  </ul>
  <h4 id="EliR">9.2. Проверка логов</h4>
  <pre id="6krZ">tail -f /root/bot_env/bot.log</pre>
  <ul id="FHFZ">
    <li id="4lzu"><strong>Ожидаемый результат</strong>:</li>
  </ul>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="zclE"><code>2025-03-03 20:00:00,123 - INFO - Starting bot... 2025-03-03 20:00:00,456 - INFO - HTTP Request: POST https://api.telegram.org/... &quot;HTTP/1.1 200 OK&quot;</code></p>
  </section>
  <p id="6Cdx"><strong>Пояснение</strong>: Логи показывают, что бот запустился и успешно подключается к Telegram API. Если есть ошибки (например, 401 Unauthorized), проверьте токен Telegram.</p>
  <h4 id="citH">9.3. Проверка подключения</h4>
  <pre id="k2cu">curl https://api.telegram.org curl https://api.openai.com</pre>
  <ul id="Ralo">
    <li id="VzDq"><strong>Ожидаемый результат</strong>: Оба запроса должны вернуть HTTP-ответ (например, 200 OK или HTML-код).</li>
    <li id="Ifcf"><strong>Пояснение</strong>: Если запросы не проходят, проверьте фаервол или интернет-соединение.</li>
  </ul>
  <h4 id="wFx5">9.4. Тестирование бота в Telegram</h4>
  <ul id="9WFf">
    <li id="HsWT"><strong>Отправьте /start</strong>:</li>
  </ul>
  <ol id="K0wh">
    <ul id="33XH">
      <li id="4Jfd"><strong>Ожидаемый результат</strong>:</li>
    </ul>
  </ol>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="YsAu"><code>Привет! Я твой помощник по фиджитал-спорту! 🏅 Фиджитал-спорт — это крутое сочетание физической активности и цифровых технологий. Давай поговорим об этом! Знаешь, какие дисциплины есть в фиджитал-спорте? Например, фиджитал-футбол или фиджитал-гонки! Кстати, хочешь зарегистрировать свою команду на турнир? (да/нет)</code></p>
  </section>
  <p id="xRhY"></p>
  <p id="ZDIx"><strong>Пояснение</strong>: Бот успешно запустился и отправил приветственное сообщение.</p>
  <ul id="RgQW">
    <li id="qELR"><strong> Ответьте &quot;да&quot;</strong>:</li>
  </ul>
  <ol id="5btQ">
    <ul id="svoV">
      <li id="mX62"><strong>Ожидаемый результат</strong>:</li>
    </ul>
  </ol>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="fpml"><code>Отлично! Давай зарегистрируем твою команду. Сначала укажи название дисциплины (например, Фиджитал-Футбол).</code></p>
  </section>
  <p id="XOG3"><strong>Пояснение</strong>: Бот начал процесс регистрации.</p>
  <ul id="mexB">
    <li id="lykM"><strong>Пройдите регистрацию</strong>:</li>
  </ul>
  <ol id="qXzq">
    <ul id="rQ8b">
      <li id="4SqS">Введите дисциплину (например, &quot;Фиджитал-Футбол&quot;), подтвердите (&quot;да&quot;).</li>
      <li id="NdU2">Укажите название команды (например, &quot;Молния&quot;), подтвердите.</li>
      <li id="xd1y">Укажите ФИО (например, &quot;Иванов Иван Иванович&quot;), подтвердите.</li>
      <li id="7KLd">Укажите телефон (например, &quot;5555555&quot;), подтвердите.</li>
      <li id="U5w7">Укажите дату рождения (например, &quot;01.01.00&quot;), подтвердите.</li>
      <li id="Lrql">Укажите город (например, &quot;Москва&quot;), подтвердите.</li>
      <li id="wgSG">Укажите организацию (например, &quot;МГУ&quot;), подтвердите.</li>
      <li id="5GEt">Ответьте &quot;нет&quot; на вопрос о дополнительных игроках.</li>
      <li id="Ernx">Ответьте &quot;нет&quot; на вопрос о комментарии.</li>
      <li id="JwQT"><strong>Ожидаемый результат</strong>:</li>
    </ul>
  </ol>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="riTN"><code>Регистрация завершена! 🎉 Данные вашей команды записаны. Что ещё могу сделать для тебя? Давай продолжим говорить о фиджитал-спорте! Как думаешь, какая дисциплина самая интересная?</code></p>
  </section>
  <p id="bMjr"><strong>Пояснение</strong>: Бот успешно записал данные в Google Sheets.</p>
  <ul id="ML9e">
    <li id="8zhv"><strong>Проверьте статус</strong>:</li>
  </ul>
  <pre id="QuZl" data-lang="python">/status Молния</pre>
  <ol id="FMFS">
    <ul id="e2nw">
      <li id="Z2O1"><strong>Ожидаемый результат</strong>:<br /> </li>
    </ul>
  </ol>
  <section style="background-color:hsl(hsl(24,  24%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="Y9O4"><code>Команда &#x27;Молния&#x27; зарегистрирована! </code></p>
    <p id="HT6F"><code>Дисциплина: Фиджитал-Футбол </code></p>
    <p id="JAGb"><code>Капитан: Иванов Иван Иванович </code></p>
    <p id="BYCh"><code>Телефон: 555-55-55 </code></p>
    <p id="Dn5h"><code>Дата рождения: 01.01.00 (24) </code></p>
    <p id="ysNe"><code>Город: Москва </code></p>
    <p id="Vosp"><code>Организация: МГУ </code></p>
    <p id="qBaW"><code>Комментарий: Игроки:</code></p>
  </section>
  <p id="kgqO"><strong>Пояснение</strong>: Бот нашёл данные команды в Google Sheets и вывел их.</p>
  <p id="z6em"></p>
  <ul id="lnxX">
    <li id="whFV"><strong>Проверьте беседу</strong>: После регистрации спросите что-то о фиджитал-спорте, например: &quot;Какие дисциплины самые популярные?&quot;</li>
  </ul>
  <ol id="lnh8">
    <ul id="5OxJ">
      <li id="oHB0"><strong>Ожидаемый результат</strong>: Бот ответит, используя промт из Google Sheets и OpenAI API.</li>
      <li id="93ni"><strong>Пояснение</strong>: Бот успешно продолжает беседу.</li>
    </ul>
  </ol>
  <hr />
  <h3 id="TGKR">Итог</h3>
  <p id="zWvY">Инструкция включает все шаги для установки бота с нуля: от подготовки сервера до тестирования. Бот будет работать, если все API-ключи и доступы настроены корректно. Если возникнут проблемы, проверьте логи (<strong>tail -f /root/bot_env/bot.log</strong>) и убедитесь, что сервер может подключиться к Telegram и OpenAI API.</p>
  <p id="LfIm"></p>
  <p id="N3dh"><strong>Если  понравилось пишите  👨‍🚀</strong></p>

]]></content:encoded></item></channel></rss>