Галоўная / Артыкулы / Практычныя прытамулкі: як я ператворыў сваю галерею фота на автонамнага агента ІІ

Практычныя прытамулкі: як я ператворыў сваю галерею фота на автонамнага агента ІІ

Практычныя прытамулкі: як я ператворыў сваю галерею фота на автонамнага агента ІІ: контракты, перакрыццяі та слоты для коду для команд, якія викорыстоўваюць гэты патэрн.

7088 слоў

У гэтым карыце парадоксальнае шлях ад сыр'ёў да рабочай системы для: «Як я ператворыў сваю галерею фота на автонамнага агента AI — Повная інструкцыя». Акцэнт ставіцца на практычныя крокі, чысткія перакананні та код, які можна проста дадаць у репазітарый без неабяснення меты. У стадзіі агульнага відгледу неабходна прадзефінаваць вхідныя даны, адпаведальную особу за крок та критэрыя завершэння пры перамены коду. Аперацыйныя працавнікі должны магчымае перадзеўсці крок з вядомага пункта контролю, не намагаючыся з'ясавіць схованы стан. Валідзіце маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выйшоў, прычына нехацкага рэзультата должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцужок задач.

Введэнне

Калі працюеце над стадзіяй «Введэнне», спачатку запісайце контракт: неабяжлівыя даннэ, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список пераконтроўкаў дапамагае заліцвачыць змяны ў кодзе пазнейша. Спрыймайце гэтую стадзію як контракт межа даннемі і перакананымі выходамі. Дайце назву рэзультатам, задацьце критэрыя успеху і не падтрымайце тых, хто выкананяе задачу часткова без паведамлення. Зробіце пераконтроўку пасля дорогіх крокаў. Програма не должна зноў выкарыстоўваць той самы вызов LLM, калі аператар прабуе зноў выканаць пазнейшы элемент.

Чаму традыцыйны пошук фота не працюе

Калі працюеце над стадзіяй «Чаму традыцыйны пошук фота», спачатку запісайце умовы: неабяжлівыя данні, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список контроля дапамагае заліцварваць можлівыя змены ў кодзе.

Запісвайце час выканання і кост токенаў або запытаў разам з функцыйнальнымі рэзултатамі. Відразы костаў з самага пачатку запобегае неспакойным рахункам, калі праця пераходзіць з дэмавай версіі ў спяльныя среды.

Зробіце контрольную пазнаку пасля дорогіх крокаў. Програма не должна зноў нарачыць косты за той самы вызов LLM, калі аператар прабуе зноў выконаць пазнейшы элемент.

Падход з альбамамі не працуе ў рэальных умовах

Калі працуеце над стадзіяй «The album approach collapses», спачатку запісайце контракт: неабяжлівыя даны, сигнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список пераконвае ў тым, што пазнейшыя змены коду будуць чыстымі. Зберагаеце настройкі за межамі коду прыемлі. Файлы сераўнавання, храненні секрэтных данных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаюць адбавіць аудыт без неабяжлівага чытання всей структуры. Ставяйце контрольныя пункты пасля дорогіх крокаў. Система вярнення праблемы не должна занова ставіць плату за той самы вызыв LLM, калі аператар перапрыяўляе роботу да наступнага элемента. Калі працуеце над стадзіяй «The album approach collapses», спачатку запісайце контракт: неабяжлівыя даны, сигнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список пераконвае ў тым, што пазнейшыя змены коду будуць чыстымі. Валіце маленькія, тэставаныя елементы працы над вялікімі скрыптамі. Калі якісь крок не выйшаў, прычына нявыпання должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаную схему працы.

Пошук за ключовымі словамі дапамага толькі часткова

Пошук за ключовымі словамі ў стадии розробкі працюе найэфективней, калі яго розглядаць як меркаваны параметр. Запісайте адна ідеальная версія, адзін прыклад неудачы і прыметкі па поверненню да попярэдней версіі, перш чым расширваць масштабы роботы. Разглядайце гэтае стадію як кантракт межа вхіднымі даннымі та перакананымі выходнымі рэзультатамі. Дайце назвы всім элементам, задаць критэрыя успеху та не падзеўляйцеся частым, непূরным викананнем задач. Зберагаюце стан графа ў простаму та типаванаму формате. Вкладышы-блокі маскуюць інфармацыю пра тое, який вузел запісаў канкрэтны поле, і спакойваюць працу пасля перерываў.

Пошук у галерэі хмары: добра, але за певную цену

Пошук у галерэі Cloud gallery працюе наяўнейша, калі яго спрыяваць як мерыемую паверхню. Запісаце адна «золатая» транскрыпцыя, адин прыклад неудачы і прыметку па вярнэнню да пачатковага стану пры расшырэнні масштаба. Запісвайце часы выканання і кост токена або запиту праза функцыональныя рэзультаты. Відразлівасць коста з самага пачатку запобегае неспакоўным рахункам, калі процес пераходзіць з дэмовай среды ў спяльнаваныя сераўеры. Храніце стан графа як плоскі і з адначытаемымі даннымі. Вярнутыя блокі маскуюць інфармацыю пра тое, який вузел запісаў канкрэтны поле, і спакшваюць продажчыку роботу пасля перарываў.

Асалодны прыем: абсэнцыя сэмантычнага разумеўння

Настоямы розныя стадзіі працуюць наўжоўды лепш, калі іх спрыяваць як меркаваную паверхню. Зберагуце адны ідеальны прыклад роботы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Хавайце настройкі за межамі коду прыемлівання. Файлы сераўнавальных сэрваў, хранілішча секретных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куда аператары можуць адбавляць контроль без неабяжнага чытання всіх дадзеных. Хавайце стан графа простым і з адзінаковым типам дадзеных. Вярсткаваныя блокі дадзеных маскуюць інфармацыю пра тое, канкрэтны вузол запісаў канкрэтнае поле, і спакшваюць возобнавленне роботы пасля перарываў. Настоямы розныя стадзіі працуюць наўжоўды лепш, калі іх спрыяваць як меркаваную паверхню. Зберагуце адны ідеальны прыклад роботы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшаў, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцоўкі задач.

Канцэпцыя: Семантычны пошук, адказна паспяшна

Для стадіі Semantic Search у проекте The Concept неабяжна ўзначыць вхідныя даны, адпаведальнага за этап і крэтыры завершэння пры змяне коду. Аперацыйныя працавнікі должны магчымае запускаць этап з вядомай точкі контролю, не падозрываючы прыхованы стан. Спрыяйце цій стадіі як даговору межаў вхідных даных і перакананых выходных рэзультатаў. Даць назвы артыфактам, узначыць крэтыры успеху і адмовіцца ад тыхнага частковага завершэння без паведамлення. Заставіць людзкую апраўду для тых крокаў, якія выкарыстоўваюць грошы або зміняюць даны для працы. Компіляцыйныя налашчэння не ўзначаюць павнае выпаненне бізнес-задач.

Якую ролю выпалоўвае мова?

Для этапа «Звядзе язык выходзіць?» неабяжна пазначыць вхідныя даны, адпаведальнага за шаг і крэтарыя выходу пры перадзеі коду. Аператары должны магчымаць перзапуск шагу з вядомай точкі контролю, не прабуючы спадарваць схованы стан. Запісвайце час выконання і кост токенаў або запытаў разам з функцыйнальнымі рэзултатамі. Відразы костаў з самага пачатку запобегае неспакойным рахункам, калі процес пераходзіць з дэмавайнага режыма ў спакульнае сераўера. Заставіце людзкую апрацоўку для тых крокаў, якія выкарыстоўваюць грошы або зменяюць даны ў працэсе. Компіляцыйныя налаштаванні не ўзроўнаўцяюцься з пачатковай готовасцю системы для роботы.

Выбір правильных інструментаў (і чаму на гэта патрэбна была калькі зусенняў)

У стадії Выбор правильных інструментаў неабходна з’явіць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння пры перадзеіснаванні коду. Аператары должны магчымаць перзапуск кроку з вядомай точкі контролю, не спрабоўваючы здогадвацца пра схованы стан. Конфігурацыю трэба знаходзіць паза кодам прыкладнення. Файлы сераўіса, хранальнікі секрэтных данных і флагі функцый належаць у аднам месца, якое аператары можаць пераглядаць, не чытаяўшы весь ланцуг задач. Аутентыфікацыя павінна выканацца на воратах, а пераправенне прав нальгавання — у роўні дадзэйнаў. Сам токен-носіцель не є межай адпаведальнасці. У стадії Выбор правильных інструментаў неабходна з’явіць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння пры перадзеіснаванні коду. Аператары должны магчымаць перзапуск кроку з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Валіць кращэ маленькія, тэставаныя елементы за велікія скрыпты. Калі крок не выйшаў, прычына нехаспекі павінна вказываць на адну адпаведальнасць, а не на заплутаны ланцуг задач.

CLIP ViT-B/32 через FastEmbed — глыбы системы

Калі працуеце з CLIP ViT-B 32 через певны этап, спачатку запісайце умовы: неабяжлівыя вхідныя даны, сигнал успеху і тое, што выходзіць у разы ў частковай невялікай памяці. Такі список дапамагае залічыць пазнейшыя змены ў кодзе. Спрыймайце гэты этап як угоду між вхіднымі данымі і перакананымі выходамі. Дайце назву рэзультатам, задаць тэсты на успех і не падпішывайцеся на тыхое часткова завершэння. Замерьце рівень запам’ятовування на фіксаванай сэтцы запитаў прычым регулюванні прапазісаў. Частыя змены прапазісаў рэдка калі вялікі эфект на слабую систему пошуку.

from fastembed import ImageEmbeddingModel, TextEmbeddingModel

# Loaded once, reused forever
image_model = ImageEmbeddingModel.from_pretrained("Qdrant/clip-ViT-B-32-vision")
text_model = TextEmbeddingModel.from_pretrained("Qdrant/clip-ViT-B-32-text")
# After embedding:
image_vector = embed_image("sunset_photo.jpg") # shape: (512,)
query_vector = embed_text("beautiful sunset") # shape: (512,)
# Cosine similarity — just a dot product on normalised vectors
similarity = np.dot(image_vector, query_vector)
# If image is a sunset → similarity ≈ 0.85 (strong match)
# If image is food → similarity ≈ 0.15 (weak match)

Qdrant Edge — памяць

Калі працуеце з рэжымам мемарыяў Qdrant Edge, спачатку запісайце умовы викорыстання: неабходныя данні, сігнал пра успех і тое, што выходзіць на частыя неудачы. Такі список дапамагае заліцварваць можлівыя змены ў кодзе. Запісваюце час выконання і кост токенаў або запытаў разам з функцыйнальнымі рэзултатамі. Відразы костаў з самага пачатку запобегае неспакойным рахункам, калі праця пераходзіць з дэмаверсіі ў спакульнаныя сераўсы. Стварайце контрольныя пункты пасля дорогіх крокаў. Функцыя адновлення не должна зноў нараховваць косты той самай вызову LLM, калі аператар прабуюць зноў выконаць пазнейшы вузел.

from qdrant_edge import(
    Distance,
    EdgeConfig,
    EdgeShard,
    EdgeVectorParams,
)
config = EdgeConfig(
            vectors={
                VECTOR_NAME: EdgeVectorParams(
                    size=EMBED_DIM,
                    distance=Distance.Cosine
                )
            }
        )
        _shard = EdgeShard.create(path=str(SHARD_DIR), config=config)

Аднаўленне всього разам

Калі працуеце на стадыі «Аб’еднанне всього», спачатку запісайце контракт: неабяжлівыя даны, сигнал успеху і тое, што выканаецца у разе частковага нявыполнення. Такі список пераканальвае ў тым, каб пазнейшыя змены коду былі чыстымі. Зберагаеце настройкі паза кодам прыемлі. Файлы сераўіса, храненні секрэтных данных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаюць адбавіць аудыт без неабяжлівага чытання всей структуры. Ставяйце контрольныя пункты пасля дорогіх крокаў. Функцыя вярнення до роботы не должна занова ставіць плату за той самы вызыв LLM, калі аператар перапрыяўляе роботу да наступнага элемента. Калі працуеце на стадыі «Аб’еднанне всього», спачатку запісайце контракт: неабяжлівыя даны, сигнал успеху і тое, што выканаецца у разе частковага нявыполнення. Такі список пераканальвае ў тым, каб пазнейшыя змены коду былі чыстымі. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выканаецца, прычына нявыполнення должна вказываць на адну адпаведальнасць, а не на заплутаную лінію обробкі.

OpenClaw — галавны мозг

Этап «OpenClaw – мозг» працюе найкраща, калі яго расследжваць як вимерную паверхню. Запісаўце адна «золатая» транскрыпцыя, адзін прыклад неудачы і запіс пра вярненне да пачатковага стану перш чым расширваць масштабы. Расследжвайце этап як кантракт межа вхіднымі даннымі і перакананымі выходнымі рэзультатамі. Даўце назвы артыфактам, задаце критэрыя успеху і адмовіцеся ад мовчанкавага частковага завершэння. Храніце стан графа ў простам і типаваным формате. Вкладзеныя блокі маскуюць, який вузел запісаў кожны поле, і спакоююць продажчыку пасля перарываў.

Настройка сяродавысці

Этап стварэння сяродавішча працуе наўжоўды лепш, калі яго спрыятаць як вимерную плошчу. Запісаўце адна «золатая» транскрыпцыю, адзін прыклад неудачы і прыметку па адвярненню змян перад расшырэнням масштаба. Запісвайце часы выканання і кост токена або запиту па боку ад функцыональных рэзультатаў. Візуабельнасць костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмаверсіі ў спяльныя сяродавішчы. Храніце стан графа як плоскі і з адзінаковым типам дадзеных. Вкладаныя блобы маскуюць, який вузол запісаў кожны поле, і спакшваюць продажчык працы пасля перарываў.

Шаг 1: Клонавайце репозітарый і створыце вяртуальнае сяродавішча

Этап 1: Клонаванне стэджа працуе наякраўсі, калі яго спрыягаць як мерымая паверхню. Зберагуце адна ідеальная транскрыпцыя, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перад расшырэнням масштаба. Зберагуйце настройкі пазырочна ад коду прыемліка. Файлы сераўнавання сяродовысці, хранілішча секрэтных дадзеных і флагі функций павінны знаходзіцца ў адном месцы, куда аператары можуць аудытаваць іх без неабяжнага чытання всіх дадзеных. Зберагуйце стан графа ў простам і типаваным формате. Вярнутыя блокі маскуюць інфармацыю пра тое, який вузел запісаў які поле, і спакоююць продаж чытання пасля перерываў. Этап 1: Клонаванне стэджа працуе наякраўсі, калі яго спрыягаць як мерымую паверхню. Зберагуце адна ідеальная транскрыпцыя, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перад расшырэнням масштаба. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісьць крока не выходзіць, прычына неудачы павінна вказываць на адную адпаведальнасць, а не на заплутаны ланцоўкі задач.

# Clone the repo
git clone https://github.com/vatsala-singh/AI-Powered-Photo-Search-and-Tagging-Agent.git
cd AI-Powered-Photo-Search-and-Tagging-Agent

# Create and activate virtual environment
python -m venv .venv
source .venv/bin/activate        # Mac/Linux
# .venv\Scripts\activate         # Windows

Этап 2: Установка залежнасцяў

Для другога крока, практыкуя інсталляцыю, неабходна ўстановка стадіі, а таксама ваказваўце вхідных дадзенняў, адпаведальнага за крок і крэтарыяў завершэння працы перад зменым коду. Аперацыйныя працавнікі павінны магчымае перапрацаваць крок пачаткуючы з вядомага контрольнага пункту, не прымусваныя здогадвацца пра схованы стан. Спрыяйце гэтай стадіі як даговору межа вхіднымі дадзеннямі і перакананымі выходнымі рэзультатамі. Даўце назвы артыфактам, ваказваўце крэтарыяў успеху і адмовіцеся ад беззвучнага частковага завершэння. Забезпечыце людскія апраўданні для тых крокаў, якія выкарыстоўваюць грошы або зміняюць даны праўай працы. Працэс складання коду не є роўнозначным пачатковай цэласнасці бізнес-процэсу.

pip install -r requirements.txt

Крок 3: З’ясаваць структуру проекту

Для трэцьяго крока «Розумеўце стадію» неабходна пазначыць вхідныя даны, адпаведальнага за крок і критэрыя завершэння пры зміне коду. Аператары должны магчыма ўвайсці крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Запісвайце час выконання і кост токенаў або запытаў па боку функцыйнаых рэзультатаў. Візуабельнасць костаў з самага пачатку запобегае неспакойным рахункам, калі процес пераходзіць з дэмавайнтару ў спяльныя сераўры. Заставіце людзкую апрацоўку для тых крокаў, якія выкарыстоўваюць грошы або зміняюць даны ў працэсе. Працэс складання коду не ўзроўнаважваецца з повнасцю бізнес-процэсаў.

AI-Powered-Photo-Search-and-Tagging-Agent/
│
├── main.py                  # FastAPI app + OpenClaw agent entry point
├── config.py                # All configurable parameters in one place
├── requirements.txt
│
├── pipeline/
│   ├── embedder.py          # CLIP embedding logic (image + text)
│   └── indexer.py           # Batch photo processing and indexing
│
├── store/
│   └── qdrant_client.py     # Qdrant Edge setup and collection management
│
├── tools/
│   ├── search.py            # Semantic search tool
│   ├── tag.py               # Zero-shot auto-tagging tool
│   ├── duplicates.py        # Near-duplicate detection tool
│   └── albums.py            # Smart album grouping tool
│
├── test/
│   ├── embedder_test.py
│   ├── indexer_test.py
│   ├── search_test.py
│   └── qdrant_edge_client_test.py
│
└── qdrant-edge-data/        # Auto-created at runtime
    ├── storage/             # Qdrant's internal shard data
    ├── models/              # Cached CLIP model weights
    └── photos/              # Collection data

Крок 4: Адзін раз пагляньце на config.py

У стадії «Пагляд на крок 4» неабяжна прадзеўніць вхідныя даны, адпаведальную особу за крок і крэтыяры завершэння пры зміне коду. Аперацыйныя працавнікі павінны магчымае перзапускаць крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Конфігурацыю трэба залічваць праза код аплікацыі. Файлы сераўіса, хранільнікі секрэтных дадзеных і флагі функцый павінны знаходзіцца ў адном месцы, якое працавнікі можуць пераглядаць, не чытаючы весь ланцуг задач. Прызначайце людскія апраўды для рэлей, якія витрачаюць грошы або зменяюць даны у працоўнай сітцы. Падключэння праз час компілявання не ўзначае повнасці бізнес-процэсу. У стадії «Пагляд на крок 4» неабяжна прадзеўніць вхідныя даны, адпаведальную особу за крок і крэтыяры завершэння пры зміне коду. Аперацыйныя працавнікі павінны магчымае перзапускаць крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Валічыце маленькія, тэставальныя елементы пра велікія скрыпты. Калі крок не выйшоў, прычына нехарактэрыстыкі павінна вказываць на адную адпаведальнасць, а не на заплутаны ланцуг задач.

# config.py

CLIP_IMAGE_MODEL = "Qdrant/clip-ViT-B-32-vision"
CLIP_TEXT_MODEL  = "Qdrant/clip-ViT-B-32-text"
EMBEDDING_DIM    = 512          # CLIP ViT-B/32 output dimension

COLLECTION_NAME  = "photos"
QDRANT_PATH      = "./qdrant-edge-data"

BATCH_SIZE             = 32     # Images per indexing batch
TOP_K                  = 10     # Default search results returned
TAG_THRESHOLD          = 0.20   # Min similarity score for a tag to apply
DUPLICATE_THRESHOLD    = 0.97   # Min similarity to flag as duplicate

Шаг 5: Запуск сервера

Калі вы працуеце над шагам 5 «Запуск», спачатку запісайце умовы кантракту: неабяжлівыя данні, сигнал успеху і тое, што выходзіць у разе частковага невыпання. Такі список контролю дапамагае заліцвачыць змяны ў кодзе. Спрэчвайце гэты этап як кантракт межа даннімі і перакананымі выходамі. Дайце назвы элементам, задаць правіла пераканання успеху і не падзеўляйцеся частковым завершэнням без паведамлення. Зробіце контрольную точку пасля дорогіх крокаў. Програма для продакцыі не должна занова ставіць плату за той самы вызов LLM, калі аператар праказвае пазнейшы вузел.

uvicorn main:app --reload --port 8000

Шаг 6: Пераканацца ў налашоўкі

Калі вы працуеце над этапам 6 «Парацэнка», спачатку запісайце умовы контракту: неабяжлівыя даны, сигнал успеху і тое, што выходзіць у разе частковага невыпання. Такі список контроля дапамагае заліцвачыць змяны коду пасля таго.

# Quick sanity check - should return {"status": "ok"}
curl http://localhost:8000/health
curl http://localhost:8000/api/status

Стварэнне каналу імбеддынга зображэнняў

Калі працуеце над стадзіяй «Стварэнне імедж-ембеддынга», спачатку запісайце умовы вярбунка: неабяжлівыя данні, сігнал успеху і тое, што выходзіць пад частковыя аберанціі. Такі список дапамагае залічваць пазнейшыя змены ў кодзе чыста.

Інструмент для стварэння імедж-ембеддынга

Этап уявлення працюе належначы, калі яго розглядаць як вимерную паверхню. Зафіксавце адна ідеальная версія, адзин случай неудачы і прыметкі па поверненню да пачатковага стану пры расшырэнні масштаба. Разглядзайце этап як кантракт межа вхіднымі даннымі і перакананымі выходнымі рэзультатамі. Даўце назвы артыфактам, задаце критэрыя успеху і адмовіцеся ад тыхоўага частковага завершэння. Раздзеліце політыку часткавага абрабатвання дадзеных ад політыкі ўтрымання іх. Змена адной з яных не павінна вымагаць перапісвання другой, калі зменяюцца паказнікі якосці.

# pipeline/embedder.py

from fastembed import ImageEmbeddingModel, TextEmbeddingModel
from PIL import Image
import numpy as np
from config import CLIP_IMAGE_MODEL, CLIP_TEXT_MODEL

# Load once, reuse for the lifetime of the process
# Models are large (~150MB each) — we never want to reload them per request
_image_model = ImageEmbeddingModel.from_pretrained(CLIP_IMAGE_MODEL)
_text_model  = TextEmbeddingModel.from_pretrained(CLIP_TEXT_MODEL)

def embed_image(image_path: str) -> np.ndarray:
    """Convert an image file to a 512-d CLIP embedding."""
    image = Image.open(image_path).convert("RGB")
    embeddings = list(_image_model.embed([image]))
    return np.array(embeddings[0])   # shape: (512,)

def embed_text(query: str) -> np.ndarray:
    """Convert a text string to a 512-d CLIP embedding."""
    embeddings = list(_text_model.embed([query]))
    return np.array(embeddings[0])   # shape: (512,)

Індексавальнік

Этап індексавання працюе наяўнасты лепш, калі яго розглядаць як вимерную паверхню. Запісаце адна ідеальная транскрыпцыя, адзін прыклад неудачы і прыметку па абратанні стану раней, чым расширваце дыячную сферу. Запісвайце часы выканання і косты токеноў або запытаў разам з функцыйнаімі рэзультатамі. Візуабельнасць костаў з самага пачатку запобегае неспакойным рахункам, калі процес пераходзіць з дэмовай среды ў спяльнаныя сераўы. Храніце стан графа ў простам і типаваным формате. Вкладзеныя блокі маскуюць інфармацыю пра тое, який вузел запісаў канкрэтны поле, і спакшваюць продажчыку роботу пасля перарываў.

# pipeline/indexer.py

import os
import uuid
from pathlib import Path
from datetime import datetime
from PIL import Image

from pipeline.embedder import embed_image
from store.qdrant_client import get_shard
from tools.tag import generate_tags
from config import BATCH_SIZE

SUPPORTED_FORMATS = {".jpg", ".jpeg", ".png", ".webp", ".bmp", ".tiff"}

def index_folder(folder_path: str) -> dict:
    """
    Recursively index all images in a folder into Qdrant Edge.
    Returns a summary: total found, indexed, skipped.
    """
    folder   = Path(folder_path)
    shard    = get_shard()

    image_paths = [
        p for p in folder.rglob("*")
        if p.suffix.lower() in SUPPORTED_FORMATS
    ]

    total    = len(image_paths)
    indexed  = 0
    skipped  = 0
    batch    = []

    for i, path in enumerate(image_paths):
        try:
            vector   = embed_image(str(path))
            tags     = generate_tags(str(path))
            img      = Image.open(path)

            point = {
                "id":      str(uuid.uuid4()),
                "vector":  vector.tolist(),
                "payload": {
                    "filename":  path.name,
                    "filepath":  str(path.absolute()),
                    "tags":      tags,
                    "timestamp": int(path.stat().st_mtime),
                    "width":     img.width,
                    "height":    img.height,
                }
            }
            batch.append(point)
            indexed += 1

        except Exception as e:
            print(f"Skipping {path.name}: {e}")
            skipped += 1

        # Flush every BATCH_SIZE images
        if len(batch) >= BATCH_SIZE:
            shard.upsert(points=batch)
            batch = []
            print(f"  Progress: {i+1}/{total} images indexed...")

    # Flush remaining
    if batch:
        shard.upsert(points=batch)

    return {"total": total, "indexed": indexed, "skipped": skipped}

Індексаванне аўтарысаў у Qdrant Edge

Этап індексавання зображэнняў у Qdrant працуе наякша, калі яго розглядаюць як мерыябельную паверхню. Зафіксуйце адны ідеальны прыклад, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Зберагаюце настройкі пазначэнныя ад коду прыемлі. Файлы сераўнавання, храненні секрэтных данных і флагі функций павінны знаходзіцца ў адном месцы, куда аператары можуць аудытаваць іх без неабяжнага чытання всіх дадзеных. Зберагаюце стан графа ў простам і типаваным формате. Вкладныя блокі маскуюць інфармацыю пра тое, який вузел запісаў які поле, і спакоююць продовжэнне роботы пасля перерываў. Этап індексавання зображэнняў у Qdrant працуе наякша, калі яго розглядаюць як мерыябельную паверхню. Зафіксуйце адны ідеальны прыклад, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Вядзеце прывялівае, тэставаныя елементы ў працу пад час роботы з велікімі скрыптамі. Калі якась зэнта не выйшла, прычына неудачы павінна вказываць на адную адпаведальнасць, а не на заплутаны ланцоўкі задач.

Як тут працуе Qdrant Edge

Для этапа «Як працюе Qdrant Edge» неабяжна прадзефінавацыя вхідных дадзеных, адпраўніка крока і крэтарыяў завершэння перад зменым коду. Аперацыяныя працавнікі павінны магчымае перапрацаваць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Спрыяйце гэтаму этапу як кантракту межа вхіднымі дадзенымі і паверанымі выходнымі. Даўце назвы артыфактам, прадзефінавацыя перакананняў у успеху і адмовіцеся ад беззвучнага частковага завершэння. Заставьце людзкую апраўду для крокаў, якія выкарыстоўваюць грошы або зміняюць даныя у працэсе виробніцтва. Працэс складання коду не ўзроўнаважваецца з пачытальнасцю бізнес-процэсаў.

Настройка шарда

Для налагоджэння этапа шардавання неабяцкова практычна вказаць інпуты, адміністратара шагу та крэтыяры завершэння пры перадзеіснаванні коду. Аператары должны магчымаць перзапуск шагу з вядомай точкі контролю, не падозрываючы прыхованы стан. Запісваць трэба час выконання та вартасць токена або запыту разам з функцыйнальнымі рэзултатамі. Відразувыя данні пра вартасць запобегаюць неспакоўным рахункам, калі процес пераходзіць з дэмовай среды ў спакульную. Неабяцкова адзначыць людскія празгляды для тых крокав, якія витрачаюць грошы або зменяюць данні ў працэйной среде. Прыўязка на час компілявання не ўзначае повнайшага адпрацоўвання бізнес-праблем.

def get_shard() -> EdgeShard:
    """
    Return the singleton EdgeShard, creating it on first call.

    - If SHARD_DIR does not exist → create a brand-new shard.
    - If SHARD_DIR already contains data → reopen it (no config needed).

    EdgeShard runs entirely in-process. No binary, no port, no network.
    """
    global _shard
    if _shard is not None:
        return _shard

    SHARD_DIR.mkdir(parents=True, exist_ok=True)
    # Detect whether this is a fresh shard or an existing one.
    # EdgeShard.create() fails if data already exists on disk.
    shard_has_data = any(SHARD_DIR.iterdir())

    if shard_has_data:
        print(f"[qdrant_client] Reopening existing shard at '{SHARD_DIR}'")
        _shard = EdgeShard.load(path=SHARD_DIR)
    else:
        print(f"[qdrant_client] Creating new shard at '{SHARD_DIR}'")
        config = EdgeConfig(
            vectors={
                VECTOR_NAME: EdgeVectorParams(
                    size=EMBED_DIM,
                    distance=Distance.Cosine
                )
            }
        )
        _shard = EdgeShard.create(path=str(SHARD_DIR), config=config)
        print(f"[store] Shard ready — vector: '{VECTOR_NAME}', dim: {EMBED_DIM}")
    return _shard

Разлік між стварэнням та завантажэнням

Для стадіі «Стварэнне» проты «Завантажэння» неабяжна практычна апранаванне вхідных дадзеных, адміністратара шагу і крэтэрыяў завершэння пры перадзеіснаванні коду. Аператары павінны магчымаецца перазапускаць шаг з вядомай точкі контролю, не падозрываючы прыхованы стан. Конфігурацыю трэба знаходзіць за межамі коду прыемленае. Файлы сераўнавання, хранільнікі секрэтных дадзеных і флагі функцыйяў павінны быць у адном месца, якое аператары можаць пераглядаць, не чытаяўшы весь ланцуг аперацый. Неабяжна ўстановіць людскую апраўду для рэлейнаў, якія витрачаюць грошы або зменяюць данні ў працэсе. Прыемленае пад час компілявання паўзы не є адпаведнай ступенем завершанасці бізнес-процэса. Для стадіі «Стварэнне» проты «Завантажэння» неабяжна практычна апранаванне вхідных дадзеных, адміністратара шагу і крэтэрыяў завершэння пры перадзеіснаванні коду. Аператары павінны магчымаецца перазапускаць шаг з вядомай точкі контролю, не падозрываючы прыхованы стан. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптов. Калі шаг не выканаецца, прычына нехтаравання павінна вказываць на адную адпаведальнасць, а не на заплутаны ланцуг аперацый.

Шаблон сінглтон

Калі вы працуеце над этапам шаблона сінглтон, спачатку запісайце умовы викорыстоўвання: неабходныя данні, сигнал успеху і тое, што выходзіць у разе частковай нявыплненасці. Такі список дапамагае заставіць пазнейшыя змены коду быць чыстымі. Спрыятлівае ставленне да гэтага этапу як да угоды межаў вхідных дадзеных і перакананых выходных рэзультатаў. Дайце назвы элементам, задаце критэрыя успеху і не прабывайце прыймаць часткова завершаныя рэзультаты без паведамлення. Зробіце перапаконтаванне пасля дорогіх крокаў. Система вярнення не павінна зноў ставіць плату за той самы вызов LLM, калі аператар прабуе зноў выконаць пазнейшы элемент.

@app.on_event("shutdown")
def on_shutdown():
  close_shard()

Схема пэйлоаду

Калі працуеце над стадзіяй «Схема пэйлоаду», спачатку запісайце умовы кантракту: неабяжлівыя даннэ, сігнал успеху і тое, што выходзіць пад частыя неудачы. Такі список контроля дапамагае заліцвачыць змяны ў кодзе.

from dataclasses import dataclass, field
from typing import List, Optional

@dataclass
class PhotoPayload:
    filename:str
    path:str
    tags: list[str] = field(default_factory=list)
    timestamp: Optional[str] = None
    width: Optional[int] = None
    height: Optional[int] = None

    def to_dict(self) -> dict:
        return {
            "filename": self.filename,
            "path": self.path,
            "tags": self.tags,
            "timestamp": self.timestamp,
            "width": self.width,
            "height": self.height
        }

Запісваўце пункты ў шард

Калі працуеце над пунктамі напісання коду на данай стадыі, спачатку запішыце умовы кантракту: неабяжлівыя даны, сигнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список пераконтроўвае чыстасць пазнейшых змян у кодзе. Зберагаюце настройкі праза код аплікацыі. Файлы сераўіса, хранільнікі секрэтных данных і флагі функцый належаць у аднам месца, куды аператары можаць пераконтроўваць іх без неабяжлівага чытання всей структуры.

from qdrant_edge import PointStruct
from store.qdrant_client import get_shard
from schema import PhotoPayload

shard = get_shard()

payload = PhotoPayload(
    filename  = "beach_sunset.jpg",
    path      = "/Users/me/Pictures/2024/Goa/beach_sunset.jpg",
    tags      = ["sunset", "beach", "outdoor"],
    timestamp = "2024-05-01T18:42:00",
    width     = 4032,
    height    = 3024
)

point = PointStruct(
    id      = "3f7a2b1c-8e4d-4f9a-b2c1-7d8e9f0a1b2c",
    vector  = {"image": vector.tolist()},   # named vector matching VECTOR_NAME
    payload = payload.to_dict()
)

shard.upsert(points=[point])

Калі працуеце над пунктамі напісання коду на данай стадыі, спачатку запішыце умовы кантракту: неабяжлівыя даны, сигнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список пераконтроўвае чыстасць пазнейшых змян у кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшаў, прычына нявыпання должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаную структуру задач.

Аўтаматычная атрыбутацыя фота

Этап аўтаматычнай атрыбутацыі фота працюе наякша, калі яго спрыяваць як мерыемую структуру. Запісаўце адна ідеальная прыклад, адзін кейс неудачы і прыметкі па поверненню да пачатковага стану пры расшырэнні масштаба. Спрыяйце этапу як кантракту межа вхіднымі дадзеннямі і перакананымі выходнымі рэзультатамі. Даўце назвы артыфактам, задаце критэрыя успеху і не прымайце часткова завершаныя рэзультаты без паведамлення. Храніце стан графа ў простым і типаванам формате. Вярнутыя структуры дадзення маскуюць інфармацыю пра тое, який вузел запісаў кожны поле, і спакшваюць продажчэнне працы пасля перарываў.

Ідея: класыфікацыя без практычных прыкладаў

Ідея стадіі класыфікацыі без практычнага трэнінгу працюе наявнасцю, калі яе рассматрываць як вимерную паверхню. Запісайце адны ідеальны прыклад, адну справу з бягам і прыметку пра вярнэнне да пачатковага стану, перш чым расширваць масштабы. Запісвайце часы выконання і косты токэнаў або запыткаў праза функцыйнае рэзультаты. Відкрытыя данні пра косты з самага пачатку запобегаюць неспакоўным рашчыткам, калі працэс пераходзіць з дэмавай версіі ў спяльныя среды. Храніце стан графа ў простам і типаваным формате. Вярнутыя структуры маскуюць інфармацыю пра тое, який вузел запісаў канкрэтны поле, і спакшваюць продажчыку роботу пасля перарываў.

TAG_VOCABULARY = [
    "sunset", "sunrise", "beach", "ocean", "mountain", "forest", "city",
    "night", "snow", "rain", "fog", "sunny", "cloudy",
    "dog", "cat", "bird", "people", "crowd", "portrait", "selfie",
    "food", "coffee", "restaurant", "travel", "architecture",
    "car", "road", "nature", "flowers", "trees",
    "indoor", "outdoor", "party", "celebration", "sport",
    "screenshot", "document", "text", "map",
]
# tools/tag.py

from pipeline.embedder import embed_image, embed_text
from config import TAG_THRESHOLD
import numpy as np

TAG_LABELS = [...]  # full list as above

# Pre-compute label embeddings once at module load —
# no point re-embedding the same 50 words on every photo
_label_vectors = {
    label: embed_text(label)
    for label in TAG_LABELS
}

def generate_tags(image_path: str) -> list[str]:
    """
    Run zero-shot classification on an image.
    Returns a list of tags whose similarity to the image
    exceeds TAG_THRESHOLD (default: 0.20).
    """
    image_vector = embed_image(image_path)

    tags = []
    for label, label_vector in _label_vectors.items():
        similarity = np.dot(image_vector, label_vector)  # cosine sim on normalised vectors
        if similarity >= TAG_THRESHOLD:
            tags.append(label)

    return tags

Тэгі ў час адзначэння індексу проты часа запытку

Тэгі на стадыі індексавання працуюць найэфектывней, калі іх спрыяваць як меркаваную паверхню. Зберагачыце адны ідеальны прыклад роботы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перад расшырэнням масштаба. Зберагачыце настройкі пазначэнныя окола коду прыемлі. Файлы серавэра, хранільнікі секретных данных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куда аператары можуць адрабоўваць аудыт без неабходнасці чытання всей структуры. Стан графа должен быть простым і з адзінаковым типам дадзеных. Вярсткаваныя блокі дадзеных маскуюць інфармацыю пра тое, який вузел запісаў канкрэтны поле, і спакоююць продажчыку роботы пасля перарываў. Тэгі на стадыі індексавання працуюць найэфектывней, калі іх спрыяваць як меркаваную паверхню. Зберагачыце адны ідеальны прыклад роботы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перад расшырэнням масштаба. Валідзіце маленькія, тэставаныя елементы замест большых скрыптов. Калі які-небудзь крок не выйшаў, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаную лінію виконання.

def generate_tags_from_vector(img_vec: np.ndarray, threshold: float = 0.20, max_tags: int = 6) -> list[str]:
    """
    Generate tags for an image vector using zero-shot CLIP classification.
    Tags with cosine similarity above threshold are included (up to max_tags).

    This is a utility function used for generating tags during indexing
    or when you already have an image vector.
    """
    tag_vecs = _get_tag_vectors()

    scores = {
        tag: float(np.dot(img_vec, vec))   # both normalized → cosine similarity
        for tag, vec in tag_vecs.items()
    }

    tags = sorted(
        [t for t, s in scores.items() if s >= threshold],
        key=lambda t: scores[t],
        reverse=True,
    )[:max_tags]

    return tags

Іспытанне тэгоў як фільтраў

У стадії «Іспытанне тэгоў як фільтраў» неабходна пазначыць вхідныя даны, адпаведальнага за этап і крэтыры завершэння пры перадзеяванні коду. Аператары должны магчымае перазапускать этап з вядомай точкі контролю, не прабуючы спадарожваць схованы стан. Спрыяйце цій стадіі як даговору межаў вхідных і перакананых выходных даных. Даўце назвы артыфактам, пазначыце крэтыры успеху і не прымайце тыхчасова часткова завершаных задач. Заставьце людзкія падтверджэння для тых крокаў, якія выкарыстоўваюць грошы або зміняюць даны для працы. Компіляцыйны падключэння не ўзроўнаўваецца з повнай завершанасцю бізнес-процэсу.

def search_photos(query: str, top_k: int = TOP_K, tags: list[str] = None) -> list[dict]:
    #search photo library with a Natural language query
    #takes in query, no of results to be displayed, and a list of tags
    # returns list of dicts with photo metadata and relevance score
    print(f"[search] Received query='{query}' with tags={tags} and top_k={top_k}")
    shard = get_shard()
    query_vector = embed_text(query)

    # Over-fetch when tag filtering is requested to have enough candidates
    # after post-filtering by tags
    over_fetch_multiplier = 5 if tags else 1
    fetch_limit = top_k * over_fetch_multiplier

    results = shard.query(
        QueryRequest(
            query=Query.Nearest(query_vector.tolist(), using=VECTOR_NAME),
            limit=fetch_limit,
            with_vector=False,
            with_payload=True,
        )
    )
    print(f"[search] Found {len(results)} initial hits for query='{query}' with tags={tags}")

    hits = []
    untagged_hits = []  # Fallback results for images without tags

    for point in results:
        payload = point.payload or {}
        point_tags = payload.get("tags", [])

        result_dict = {
            "path": payload.get("path"),
            "filename": payload.get("filename"),
            "tags": point_tags,
            "timestamp": payload.get("timestamp"),
            "score": round(point.score, 4)
        }

        # Post-filter by tags if specified
        # (EdgeShard doesn't support complex filters, so we filter in Python
        # after over-fetching more results than needed)
        if tags:
            if point_tags and any(t in point_tags for t in tags):
                # Has tags and matches the filter
                hits.append(result_dict)
            elif not point_tags:
                # No tags yet (images not auto-tagged), save as fallback
                untagged_hits.append(result_dict)
        else:
            # No tag filter specified, include all results
            hits.append(result_dict)

        # Stop if we have enough tagged results
        if len(hits) >= top_k:
            break

    # If we don't have enough tagged results, include untagged ones that match the query
    if tags and len(hits) < top_k:
        hits.extend(untagged_hits[:top_k - len(hits)])

    return hits[:top_k]

Стварэнне агента для пошуку

Для стадіі стварэння агента пошуку неабяжна ўзначыць вхідныя даны, адпаведальнага за крок і критэрыя завершэння пры перадзеіснавленні коду. Аператары должны магчымаць перзапуск кроку з вядомай точкі контролю, не падозрываючы прыхованы стан. Запісваць час выконання і кост токена або запыту праза функцыйнальныя рэзултаты. Відразлівасць коста з самага пачатку запобегае неспакоўным рахункам, калі парадок пераходзіць з дэмаверсіі ў спяльныя среды. Заставіць людзкую апраўду для тых крокаў, якія витрачаюць грошы або зменяюць даны ў працэсе. Працэс складання коду не ўзначае повнайшага адпаведання бізнес-трэбаванням.

curl --location 'http://localhost:8000/search' \
--header 'Content-Type: application/json' \
--data '{"query": "eiffel tower from rooftop","tags":[], "top_k": 1}'
{
    "query": "eiffel tower from rooftop",
    "results": [
        {
            "path": "/Users/vatsalasingh/Documents/Datasets/tag_phot/photo-1638051017225-0d9fcca18cf4.jpg",
            "filename": "photo-1638051017225-0d9fcca18cf4.jpg",
            "tags": [
                "cloudy",
                "city",
                "rain",
                "screenshot",
                "architecture",
                "travel"
            ],
            "timestamp": "2021-12-09T17:27:56",
            "score": 0.2864
        }
    ]
}

Адпаведнае рашэнне экстремальных ситуацыяў

Ёнколі трэба граматычна распрацаваць крайнія случаі, яшчэ перад зменым коду неабходна ўзначыць вхідныя даны, адпаведальнага за крок і критэрыя завершэння. Аператары павінны магчымаць перзапуск крока з вядомай точкі контролю, не падозрываючы прыхованы стан. Канфігурацыю трэба залічыць пазначкай ад коду прыемлівання. Файлы сераўнавальнага сэрвісу, хранення секрэтных дадзенаў і флагі функцыйяў павінны знаходзіцца ў адном месцы, якое аператары можаць пераглядаць, не чытаяўшы весь ланцуг. Даецца можлівасць апраўды чалавека для тых крокаў, якія выкорыстоўваюць грошы або зміняюць даны у працэсе. Прыўязка на час компілявання не є падтверджэннем полныя адпаведнасці з бізнес-трэбованнямі. Ёнколі трэба граматычна распрацаваць крайнія случаі, яшчэ перад зменым коду неабходна ўзначыць вхідныя даны, адпаведальнага за крок і критэрыя завершэння. Аператары павінны магчымаць перзапуск крока з вядомай точкі контролю, не падозрываючы прыхованы стан. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выйшоў, прычына нехарактернага рэзультата павінна вказываць на адну конкрэтную адпаведальнасць, а не...

заплутаная сетка практык.

Організацыя всьго за дапамою OpenClaw

Калі працуеце над этапам разработкі, спачатку запісайце умовы: неабяжлівыя данні, сигнал успеху і тое, што выходзіць у разе частковага невыпання. Такі список контролю дапамагае заліцварыць пазнейшыя змены ў кодзе. Спрэцьвачайце гэты этап як угоду межаў між вхіднымі данымі та перакананымі выходамі. Дайце назвы элементам, задаце критэрыя успеху та не прабывайце прыймать часткова завершаныя рэзультаты без паведамлення. Стварайце контрольныя точкі пасля дорогіх крокаў. Програма для продакцыі не должна занова ставіць плату за той самы вызов LLM, калі аператар прабуе зноў запрацаваць з пазнейшым вузлам.

Як працюе OpenClaw

Калі працюеце над этапам «Як працюе OpenClaw», спачатку запісайце умовы викорыстоўвання: неабходныя даны, сігнал успеху і тое, што выходзіць у разе частковага невыпання. Такі список дапамагае заліцвачваць змяны ў кодзе пазнейшаю часам. Запісвайце час выконання і кост токеноў або запытаў разам з функцыйнальнымі рэзультатамі. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмаверсіі ў спяльныя сераўы. Стварайце контрольныя пункты пасля дорогіх крокаў. Функцыя вярнення не должна зноў нарахоўваць косты той самай вызову LLM, калі аператар перапрыямляе роботу да наступнага вузла.

@app.post("/chat")
def chat(req: ChatRequest):
    """
    Conversational endpoint. Accepts user message and conversation history,
    returns agent's reply after processing with tools.
    """
    # Define tool functions that the agent can call
    def search_tool(query: str, top_k: int = 10, tag_filter: list = None):
        """Search photos by natural language query"""
        return search_photos(query=query, top_k=top_k, tags=tag_filter)

    def duplicates_tool(threshold: float = 0.97):
        """Find duplicate or near-duplicate photos"""
        return find_duplicates(threshold=threshold)

    def tag_tool(image_path: str):
        """Generate and update tags for a specific photo"""
        return generate_tags_from_vector(image_path=image_path)

    # Create the agent with tools
    agent = Agent(
        tools=[search_tool, duplicates_tool, tag_tool],
        system_prompt="""
        You are a personal photo assistant. You help users search, organize,
        and understand their local photo library. You have access to tools
        for semantic search, duplicate detection, and tagging.

        When helping users:
        - Use the search tool to find photos by describing their content
        - Use duplicates tool to find and clean up duplicate shots
        - Use tag tool to inspect or update tags for specific photos

        Always be concise and helpful. When returning photo results,
        format them clearly with filenames, similarity scores, and tags.
        Use emojis sparingly but helpfully.
        """
    )

    # Run the agent conversation
    response = agent.chat(
        message=req.message,
        history=req.history
    )
    return {"response": response}

Рэальныя прабегі взаімадзеяння

Калі працуеце над стадзіяй «Рэальныя праблемы ваходжання», спачатку запісайце умовы ваходжання: неабяжлівыя даны, сігнал успеху і тое, што выходзіць пад частыя неудачы. Такі список дапамагае заліцваліваць пазнейшыя змены ў кодзе. Зберагаюце настройкі за межамі коду прыемліка. Файлы сераўіса, хранілішча секрэтных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаюць адбавіць аудыт без неабяжлівага чытання всей структуры. Ставяце контрольныя пункты пасля дорогіх крокаў. Система вярнення не должна занова ставіць плату за той самы вызов LLM, калі аператар перапрыяўляе выконанне на пазнейшы вузел. Калі працуеце над стадзіяй «Рэальныя праблемы ваходжання», спачатку запісайце умовы ваходжання: неабяжлівыя даны, сігнал успеху і тое, што выходзіць пад частыя неудачы. Такі список дапамагае заліцваліваць пазнейшыя змены ў кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выйшаў, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаную структуру працы.

Чаму важнае роўэнь агента

Этап шара агента працюе найкраща, калі яго розглядаць як вимерную паверхню. Зафіксавце адзін ідеальны прымер, адзін кейс неудачы і запіс працэўкі з вярненням да пачатковага стану пры перадзеяванні масштаба. Разглядайце гэты этап як кантракт межа вхіднымі даннымі і паверынутымі выходнымі рэзультатамі. Даўце назвы артыфактам, задаце критэрыя успеху і не падзеўляйцеся частым, непূরным выкананнем задачы. Храніце стан графа ў простам і типаваным формате. Вкладзеныя блокі маскуюць інфармацыю пра тое, який вузел запісаў канкрэтны поле, і спакшваюць продажчыку роботу пасля перарываў.

Выкананне всьго локальна — і чаму гэта важна

Процес Выканання всьго локальна і на стадыі працюе найэфектыўней, калі яго спрыяваць як мерыемую паверхню. Запісаце адна ідеальная транскрыпцыя, адзін прыклад неудачы і прыметку па адвярненню змян перш чым расширваць масштаб. Запісвайце часы выканання і косты токеноў або запытаў разам з функцыйнальнымі рэзультатамі. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі процес пераходзіць з дэмаверсіі ў спяльныя среды. Храніце стан графаў у простам і типаваным формате. Вярнутыя структуры маскуюць інфармацыю пра тое, який вузел запісаў канкрэтны поле, і спакшваюць продажчыку роботу пасля перарываў.

Нічога не выходзіць з вашага прыстрою. Канец.

The Nothing leaves your device stage працюе наякша, калі яго спрыяваць як до мерымабельнай паверхні. Зберагучы адны ідеальны прыклад роботы, адны прыклад неудачы і запіс пра вярнэнне да пачатковага стану, перш чым расширваць сферу дзеяння. Храніце настройкі параду ў коде прыемленае. Файлы серавэра, сховішчы секретных даных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаць адбавляць контроль без неабяжнага чытання всіх дадзеных. Храніце стан графа ў простам і типаваным формате. Вярнутыя структуры дадзеных маскуюць інфармацыю пра тое, який вузел запісаў канкрэтны поле, і спакоююць продовжэнне роботы пасля перерываў. The Nothing leaves your device stage працюе наякша, калі яго спрыяваць як до мерымабельнай паверхні. Зберагучы адны ідеальны прыклад роботы, адны прыклад неудачы і запіс пра вярнэнне да пачатковага стану, перш чым расширваць сферу дзеяння. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцоўкі дзеяння.

Што на самай працэ патрэбна, каб гэта запрацавало

Для этапа «Што на самай працо ўключана» неабходна пазначыць вхідныя даны, адпаведальнага за крок і критэрыя завершэння пры перадзеіснавленні коду. Аператары должны магчымаць перзапуск кроку з вядомай точкі контролю, не прабуючы спадарожваць схованы стан. Спрыяйце цэму этапу як даговору межа вхіднымі данымі і перакананымі выходнымі рэзультатамі. Даўце назвы артыфактам, пазначыце критэрыя успеху і не прымайце тыхню частковую завершанасць. Заставіце людзкія апраўленні для тых крокаў, якія выкарыстоўваюць грошы або зміняюць даны ў працэсе виробніцтва. Компіляцыйныя налашчэнні не ўзроўнаўцяюцься з пачатковай цэласнасцю бізнес-процэса.

Што далей — расшырэнне системы

Для стадіі расшырэння What s Next неабяжна прадзеўначыць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння пры змены коду. Аперацыйныя працавнікі должны магчымае перадзеўжваць крок з вядомага пункта контролю, не спрабоўваючы здагадвацца пра схованы стан. Запісвайце час выконання і кост токенаў або запытаў разам з функцыйнальнымі рэзультатамі. Відразлівая видавальнасць костаў з самага пачатку запобегае неспакойным рахункам, калі процес пераходзіць з дэмавайнага режыма ў спяльныя среды. Заставіце людзкую апраўдку на тых кроках, якія витрачаюць грошы або зменяюць даны ў працоўным режыме. Працэс складання коду не ўзроўнаважваецца з повнасцю бізнес-процэсаў.

Кластераванне эйкаў

Для стадіі кластэрування аўтаматычных фота неабходна перад змянай коду адзначыць вхідныя даны, адпаведальнага за этап і крэтыры завершэння. Аператары должны магчымае перадзванаць гэты этап з вядомага пункта контролю, не спрабоўваючы здагадвацца пра схованы стан. Конфігурацыю трэба заставіць праза код аплікацыі. Файлы сяродавішча, хранільнікі секрэтных дадзеных і флагі функций должны знаходзіцца ў аднам месцы, якое аператары можаць пераглядаць, не чытаючы весь ланцуг аператацый. Прызначаць людскія празгляды для рэшэнняў, якія выкарыстоўваюць грошы або зміняюць даны для працы. Прыўязка на час компілявання не є падтверджэннем полныя адпаведнасці да бізнес-трэбаў. Для стадіі кластэрування аўтаматычных фота неабходна перад змянай коду адзначыць вхідныя даны, адпаведальнага за этап і крэтыры завершэння. Аператары должны магчымае перадзванаць гэты этап з вядомага пункта контролю, не спрабоўваючы здагадвацца пра схованы стан. Валідзіць маленькія, тэставаныя елементы працы больш ніж велікія, складныя скрыпты. Калі этап не выконваецца, прычына нехарактэрнага роблення должна быць адзінай, а не ўскладненым ланцугам аператацый.

OCR для скріншотаў і дакументаў

Калі працюеце над OCR для скріншотаў і дакументаў, спачатку запісайце умовы контракту: неабходныя даны, сігнал успеху і тое, што вядзецься у разе частковай невыплнення. Такі список переказваў дапамагае заліцвачыць змяны ў кодзе пазней. Спрыймайце гэты этап як контракт між вхіднымі данымі і перакананымі выходнымі рэзультатамі. Дайце назвы артыфактам, задаць правіла пераканання успеху і не падтрымайце тыхія частковыя завершэння. Зробіце пераказв пасля дорогіх крокаў. Система вярнення не павінна знову ставіць плату за той самы вызов LLM, калі аператар перапрыяўляе роботу да наступнага етапу.

Індексаванне кадраў відеа

Калі працюеце над стадзіяй індэксавання кадраў відеа, спачатку запішыце умовы: неабяжныя данні, сігнал успеху і тое, што выходзіць у разе частковага нэуспеху. Такі список контролю дапамагае заліцвачыць змяны ў кодзе пазнейшаю часам. Запісвайце часы выканання і косты токеноў або запытаў разам з функцыйнальнымі рэзультатамі. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмавай версіі ў спяльныя сераўры. Зробіце контрольную пазнаку пасля дорогіх крокаў. Функцыя адновлення не должна зноў нарахоўваць косты той самай вызову LLM, калі аператар прабуюць зноў выконаць пазнейшы вузел.

Гібрыдны пошук: вектары + ключавыя словы + метаданы

Калі працуеце з этапам гэтыя фазы гібранай пошуку, спачатку запісаце кантракт: неабяжлівыя данні, сігнал успеху і тое, што выходзіць пад частыя неудачы. Такі список контроля дапамагае заліцвачыць пазнейшыя змены ў кодзе. Храніце настройкі параду ўнутры коду прыемлі. Файлы сераўіса, хранальнікі секрэтных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаць адбавіць аудыт без неабяжлівага чытання всей структуры. Стварайце контрольныя пункты пасля дорогіх крокаў. Функцыя вярнення роботы не должна занова ставіць плату за той самы вызов LLM, калі аператар перапрыяўляе роботу да наступнага элемента. Калі працуеце з этапам гэтыя фазы гібранай пошуку, спачатку запісаце кантракт: неабяжлівыя данні, сігнал успеху і тое, што выходзіць пад частыя неудачы. Такі список контроля дапамагае заліцвачыць пазнейшыя змены ў кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выйшаў, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны процес.

Адаптаванне процеса выкарыстоўвання па часе і месцазнаходзенні

Этап, які урахоўвае час і месцазнаходзення, працюе наяўнейша, калі яго спрыяваць як мерыемую структуру. Зберажыце адна ідеальная версія транскрыпцыі, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Спрыявайце этап як даговор межа вхіднымі дадзеннямі і перакананымі выходнымі рэзультатамі. Даць назвы артыфактам, задаць критэрыя успеху і не падзеўляйцеся частым, непূরным выкарыстоўваннем. Раздзеліце правілы часткавага апрантавання дадзенняў і правілы ўзяць іх з памяці. Змена адных не должна прымусваць перапісванне іншых, калі змянююцца паказнікі якосці.

Заключныя меркі

Этап «Заключныя меркіі» працюе найэфектывней, калі яго розглядаць як вимерную паверхню. Запісацеце адна «золатая» транскрыпцыя, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перад расшырэнням масштаба. Запісвайце часы выканання і кост токеноў або запытаў праза функцыйнае рэзультат. Відкрытыя данні пра косцы з’являюцца рана, таму не будзе неспакою з расчыткамі, калі праця перайдзе з дэмаверсіі ў спакульнаныя сераўысы. Храніце стан графа як плоскі і з адначынным типам дадзеных. Вярнутыя блокі маскуюць, який вузел запісаў канкрэтны поле, і спакшваюць продажчыку роботу пасля перарываў.

Справы і далейшая літэратура

Этап «Справакі і дадзеныя для падальшага чытання» працюе найэфектывней, калі яго спрыяваць як меравальную плошчу. Зберагачыце адны ідеальны прыклад роботы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць сферу дзеяння. Храніце настройкі парадульна ад коду прыемлі. Файлы сераўнавання, базы секрэтных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куда аператары можуць адбавляць контроль без неабяжнага чытання всіх дадзеных. Храніце стан графа ў простам і типаваным формате. Вярнутыя структуры дадзеных маскуюць інфармацыю пра тое, який вузел запісаў канкрэтны поле, і спакшваюць продаж чытання пасля перерываў. Этап «Справакі і дадзеныя для падальшага чытання» працюе найэфектывней, калі яго спрыяваць як меравальную плошчу. Зберагачыце адны ідеальны прыклад роботы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць сферу дзеяння. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцоўкі дзеяння.

Чэрніца аператывных дзеянняў

Этап стварэння чек-ліста для аператыўных задач работае наякша, калі яго спрыяваць як мерыемую структуру. Запісайце адну ідеальную версію працы, адзін кейс неудачы і прыметкі па вярнэнню да пачатковага стану, прычым расшырюючы сферу дзеяння.

Документавайце як шлях успеху, так і шлях вярнэння да нормальнага стану разам. Практыкі перапрыбутку, людзкія контрольныя пункты і обработка некоректных звесцей ўжо є частью продукту, а не елементамі пазнейшай доработкі.

Зберагаюце стан графа ў простам і типаваным формате. Вкладзеныя структуры маскуюць інфармацыю пра тое, який вузел запісаў кожнае поле, і спакошуюць працу пасля перарываў.

Калі бюджет дазволяе, дадзіце тэст на першыя перакананні, які працюе з критычным шляхам у системе CI за дапамою фіксатываў, а не з рэальнымі платнымі API.

Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына неудачы павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач.

Зберагаюце стан графа ў простам і типаваным формате. Вкладзеныя структуры маскуюць інфармацыю пра тое, який вузел запісаў кожнае поле, і спакошуюць працу пасля перарываў.

Перш чым запускать стак, заморозьце версіі, зафіксавце «золаты» транскрыпты для критычнага шляху і паказвце способы абяроны. У спільных средах неабходны ліміты частоты запытанняў, пераконтрольванне прав на выкарыстоўвання ресурсаў і чысткі власнік для змены секрэтных даных. Лепш выбіраць простую надзею на надзейнасць, чым хітрыя експерыментальныя дэманстрацыі.

Прыметка для b7b9768f8acd: не кладзіце ключы прадаўцаў у репазітарый, задаце максимальны тэрмін дзейнасці токена на кожную сесію і зберагачыце транскрыпты разам з фіксатрамі для ацэнкі, каб пазнейшыя замены моделяў заставаліся порównаннэй.