
Eco²
Backend · Cloud infrastructure
Wskazówki segregacji z jednego zdjęcia i rozmowy.
Wszechstronny asystent AI, który rozumie zasady segregacji odpadów w Korei.
Eco² vocabulary
- edge
- auth offload
- domain api
- task queue
- scan pipeline
- chat agent
- event bus
- cluster
- gitops
- autoscaling
- observability
- load test
- evaluation
Edge: ROUTE 53 · ALB · HTTPS 443 · internet-facing · external-dns · istio-ingressgateway · NodePort · eco2-gateway · VirtualService · x-canary · AuthorizationPolicy · ENVOY SIDECAR · kiali-serverAuth Offload: AuthorizationPolicy · action: CUSTOM · notPaths · envoyExtAuthzGrpc · failOpen: false · CheckRequest · x-user-id · BlacklistCache · BootstrapFromRedis · outbox:blacklist · blacklist.events · UsersServiceDomain API: VirtualService · x-user-id · /api/v1/scan · X-Idempotency-Key · job_id · stream_url · 202 ACCEPTED · Retry-After · ScanTask · UsersService · ImageService · ENVOY SIDECARTask Queue: outbox:blacklist · blacklist.events · RabbitmqCluster · scan.direct · reward.events · dlx · x-dead-letter-exchange · chat.process · AioPikaBroker · task_acks_late · apply_async · gevent · scan.vision · scan.rule · scan.answer · scan.reward · CELERY CHAIN · QueueLength · inspect ping · QUEUE SATURATIONScan Pipeline: ScanTask · scan.direct · reward.events · apply_async · gevent · scan.vision · scan.rule · scan.answer · scan.reward · CELERY CHAIN · RewardStep · item_class_list.yaml · situation_tags.yaml · LITE RAG · JsonRegulationRetriever · PipelineStage · waste_rag · XADD · domain: worker-ai · pipeline_duration · vision_stage_durationChat Agent: ImageService · chat.process · AioPikaBroker · create_chat_graph · route_by_intent · MULTI-INTENT FANOUT · waste_rag · recyclable_price · collection_point · image_generation · aggregator · thread_id · SyncableRedisSaver · AsyncPostgresSaver · LANGSMITH_TRACING · regenerateEvent Bus: job_id · stream_url · PipelineStage · XADD · scan:events:{shard} · XREADGROUP · XACK · XAUTOCLAIM · PendingReclaimer · STATE KV · scan:state:{job_id} · sse:events:{shard} · SSEBroadcastManager · Last-Event-ID · scan_sse_connections_active · ServiceMonitor · traceparentCluster: NodePort · kubeadm init · kubeadm join · vxlanMode · BGPConfiguration · module "vpc" · worker_ai · nodeSelector · domain: worker-ai · NoSchedule · 24-NODE CLUSTERGitOps: external-dns · x-canary · dev-root · ApplicationSet · sync-wave · selfHeal · ignoreDifferences · argocd-image-updater · update-strategy: digest · write-back-method · targetRevision · ci-services.ymlAutoscaling: ignoreDifferences · ScaledObject · QueueLength · cooldownPeriod · pollingInterval · fallback · maxReplicaCount · stabilizationWindowSeconds · HorizontalPodAutoscaler · scan_sse_connections_active · prometheus-adapterObservability: 24-NODE CLUSTER · prometheus-adapter · FLUENT BIT · Elasticsearch · Kibana · kube-prometheus-stack · AlertmanagerConfig · ServiceMonitor · JAEGER · OPENTELEMETRY · traceparent · kiali-server · LANGSMITH_TRACINGLoad Test: k6 · ramping-vus · thresholds · pipeline_duration · vision_stage_duration · poll_timeout · inspect ping · WORKER RESTART · POLLING TIMEOUT · QUEUE SATURATIONEvaluation: EvalConfig · eval_mode · eval_sample_rate · eval_cost_budget_daily_usd · EvalResult · EvalGrade · code_grader · llm_grader · CUSUM · regenerate · OpenAIBARSEvaluator
Jak 24 węzły faktycznie się łączą, przepływ po przepływie.
Samodzielnie zarządzany Kubernetes zbudowany z kubeadm. Mapa umieszcza 24 fizyczne węzły i działające na nich workloady w pięciu warstwach z README i łączy je faktycznymi połączeniami. Wybór przepływu wyróżnia tylko tę ścieżkę z ponumerowanymi krokami.
Rozpoznaje odpady na zdjęciu i wyjaśnia, jak się ich pozbyć, a w rozmowie wywołuje narzędzia do miejsc, pogody, cen surowców wtórnych i wyszukiwania w sieci oraz generuje obrazy. W tym projekcie zespołowym mój zakres zaczął się od klastra i podstaw wdrożeń, a potem objął backend domenowy, przetwarzanie asynchroniczne, agenta konwersacyjnego i weryfikację.
Od prac konkursowych po wzmacnianie backendu i utrzymania
Usługa zakończyła działanie; nagrane demo i raport techniczny pokazują ją w działaniu.
Żądanie Scan → dostarczanie na żywo
Żądanie analizy zdjęcia staje się zakolejkowaną pracą, a jego zdarzenia postępu wracają do tej samej przeglądarki.
Przeglądarkazapytanie DNS: zapytanie DNSRoute 53
Z rekordów Route 53 rozwiązywana jest tylko nazwa. Żądania nie przechodzą przez DNS.
Przeglądarkaprzepływ danych: HTTPS 443AWS ALB
TLS kończy się na ALB.
AWS ALBprzepływ danych: HTTP · NodePortIstio ingress Envoy
k8s-ingress-gatewayPrzekazywane do ingress Envoy Istio przez NodePort celu typu instancja EC2.
Istio ingress Envoy
k8s-ingress-gatewayprzepływ danych: VirtualServiceScan APIk8s-api-scanKierowane do Scan API, które kolejkuje pracę i od razu zwraca job_id; zapytanie o wynik odpowiada 202, dopóki zadanie się nie zakończy.
Scan API
k8s-api-scanprzepływ danych: Zadanie CeleryRabbitMQk8s-rabbitmqZadanie Scan trafia do RabbitMQ.
RabbitMQ
k8s-rabbitmqprzepływ danych: consumescan-workerk8s-worker-ai · k8s-worker-ai-2scan-worker (Celery · gevent) w puli AI pobiera je i wykonuje Vision → Rule → Answer → Reward. Cztery etapy to połączone w łańcuch zadania Celery, a nie węzły.
Pula AI
k8s-worker-ai · k8s-worker-ai-2przepływ danych: HTTPSLLM APIWorkery scan i chat wywołują API OpenAI i Google.
scan-worker
k8s-worker-ai · k8s-worker-ai-2przepływ danych: XADD scan:eventsStreamsk8s-redis-streamsZdarzenia postępu są zapisywane do jednego z czterech shardów Streams.
Streams
k8s-redis-streamsprzepływ danych: XREADGROUPEvent Routerk8s-event-routerEvent Router odczytuje je jako consumer group i po przetworzeniu wykonuje XACK; pending i reclaim utrzymują dostarczanie typu at-least-once.
Event Router
k8s-event-routerprzepływ danych: SETEX stateState KVk8s-redis-streamsZapisuje najnowszy stan i znacznik duplikatu do State KV na tym samym węźle Redis.
Event Router
k8s-event-routerprzepływ danych: PUBLISHPub/Subk8s-redis-pubsubDostarczane w czasie rzeczywistym na kanale zadania w shardowanym Pub/Sub.
Pub/Sub
k8s-redis-pubsubprzepływ danych: SUBSCRIBESSE Gatewayk8s-sse-gatewaySSE Gateway subskrybuje przez jeden współdzielony listener na proces i rozsyła do każdej podłączonej przeglądarki.
SSE Gateway
k8s-sse-gatewayprzepływ danych: Strumień SSEPrzeglądarkaPołączenie otwarte tą samą ścieżką przez ALB i ingress. Dostarczanie typu at-least-once; duplikaty są obsługiwane idempotentnie.
State KV
k8s-redis-streamsprzepływ danych: Przywracanie po ponownym połączeniuSSE Gatewayk8s-sse-gatewayPo ponownym połączeniu z Last-Event-ID State KV i zachowane Streams uzupełniają pominięte zdarzenia.
Chat · tokeny i zapis
Tokeny Chat idą tą samą ścieżką zdarzeń co Scan; checkpointy i wiadomości zapisują dwa różne workloady.
Przeglądarkaprzepływ danych: HTTPS 443AWS ALB
TLS kończy się na ALB.
AWS ALBprzepływ danych: HTTP · NodePortIstio ingress Envoy
k8s-ingress-gatewayPrzekazywane do ingress Envoy Istio przez NodePort celu typu instancja EC2.
Istio ingress Envoy
k8s-ingress-gatewayprzepływ danych: VirtualServiceChat APIk8s-api-chatKierowane do Chat API.
Chat API
k8s-api-chatprzepływ danych: Zadanie TaskiqRabbitMQk8s-rabbitmqZadanie Chat trafia do RabbitMQ.
RabbitMQ
k8s-rabbitmqprzepływ danych: consumechat-workerk8s-worker-ai · k8s-worker-ai-2chat-worker (Taskiq · asyncio) klasyfikuje intencję za pomocą LangGraph, a następnie w razie potrzeby uruchamia vision, wybrane narzędzia, aggregator i w razie potrzeby podsumowanie, po czym odpowiada. Każde żądanie wykonuje tylko potrzebne mu gałęzie.
Pula AI
k8s-worker-ai · k8s-worker-ai-2przepływ danych: HTTPSLLM APIWorkery scan i chat wywołują API OpenAI i Google.
chat-worker
k8s-worker-ai · k8s-worker-ai-2przepływ danych: XADD chat:eventsStreamsk8s-redis-streamsTokeny i zdarzenia etapów są zapisywane do czterech shardów Streams; dalej ścieżka dostarczania jest taka sama jak w Scan.
Streams
k8s-redis-streamsprzepływ danych: XREADGROUPEvent Routerk8s-event-routerEvent Router odczytuje je jako consumer group i po przetworzeniu wykonuje XACK; pending i reclaim utrzymują dostarczanie typu at-least-once.
Event Router
k8s-event-routerprzepływ danych: PUBLISHPub/Subk8s-redis-pubsubDostarczane w czasie rzeczywistym na kanale zadania w shardowanym Pub/Sub.
Pub/Sub
k8s-redis-pubsubprzepływ danych: SUBSCRIBESSE Gatewayk8s-sse-gatewaySSE Gateway subskrybuje przez jeden współdzielony listener na proces i rozsyła do każdej podłączonej przeglądarki.
SSE Gateway
k8s-sse-gatewayprzepływ danych: Strumień SSEPrzeglądarkaPołączenie otwarte tą samą ścieżką przez ALB i ingress. Dostarczanie typu at-least-once; duplikaty są obsługiwane idempotentnie.
chat-worker
k8s-worker-ai · k8s-worker-ai-2przepływ danych: checkpointCachek8s-redis-cacheCheckpoint LangGraph jest przechowywany w Redis Cache.
Cache
k8s-redis-cacheprzepływ danych: odczyt checkpointucheckpoint-syncerk8s-worker-ai · k8s-worker-ai-2checkpoint-syncer odczytuje checkpoint z Redis.
checkpoint-syncer
k8s-worker-ai · k8s-worker-ai-2przepływ danych: synchronizacja do PostgreSQLPostgreSQLk8s-postgresqlAsyncPostgresSaver zapisuje go asynchronicznie w PostgreSQL.
Streams
k8s-redis-streamsprzepływ danych: chat-persistence grouppersistence consumerk8s-api-chatPersistence consumer na węźle Chat odczytuje zdarzenia done jako consumer group.
persistence consumer
k8s-api-chatprzepływ danych: zapis wiadomościPostgreSQLk8s-postgresqlWiadomości Chat są zapisywane w PostgreSQL. To inny workload niż checkpoint-syncer.
Wejście · uwierzytelnianie
Synchroniczna ścieżka od wejścia do klastra do domenowego API. Tylko ścieżki chronione polityką najpierw sprawdzają uwierzytelnienie; ruch podów między węzłami odbywa się przez Calico VXLAN.
Przeglądarkazapytanie DNS: zapytanie DNSRoute 53
Z rekordów Route 53 rozwiązywana jest tylko nazwa. Żądania nie przechodzą przez DNS.
Przeglądarkaprzepływ danych: HTTPS 443AWS ALB
TLS kończy się na ALB.
AWS ALBprzepływ danych: HTTP · NodePortIstio ingress Envoy
k8s-ingress-gatewayPrzekazywane do ingress Envoy Istio przez NodePort celu typu instancja EC2.
Istio ingress Envoy
k8s-ingress-gatewayprzepływ danych: ext-authz · gRPC 50051ext-authzk8s-api-authTylko ścieżki objęte polityką CUSTOM najpierw pytają Go ext-authz (limit czasu 2 s, failOpen false). Ścieżki takie jak logowanie, health i docs są wyłączone.
ext-authz
k8s-api-authprzepływ danych: sprawdzenie blacklistyblacklistk8s-redis-authToken jest sprawdzany w blackliście Redis.
Istio ingress Envoy
k8s-ingress-gatewayprzepływ danych: VirtualServiceChat APIk8s-api-chatKierowane do Chat API.
Chat API
k8s-api-chatprzepływ danych: gRPCimages APIk8s-api-imageSynchroniczne wywołanie chat → images wymienione w README.
auth API
k8s-api-authprzepływ danych: gRPCusers APIk8s-api-usersSynchroniczne wywołanie auth → users wymienione w README.
Pula storage · zapisy asynchroniczne
Blacklistę uwierzytelniania i własność postaci zapisują workery puli storage, które pobierają pracę z RabbitMQ.
blacklist
k8s-redis-authprzepływ danych: outbox:blacklistauth-relayk8s-worker-storage · k8s-worker-storage-2auth-relay (auth-Bus z README) odczytuje outbox Redis.
auth-relay
k8s-worker-storage · k8s-worker-storage-2przepływ danych: blacklist.eventsRabbitMQk8s-rabbitmqPublikuje ponownie do RabbitMQ, z ponowieniami i DLQ.
RabbitMQ
k8s-rabbitmqprzepływ danych: blacklist.eventsauth-workerk8s-worker-storage · k8s-worker-storage-2auth-worker odbiera zdarzenia blacklisty.
auth-worker
k8s-worker-storage · k8s-worker-storage-2przepływ danych: zapis blacklistyblacklistk8s-redis-authSą zapisywane w blackliście Redis.
RabbitMQ
k8s-rabbitmqprzepływ danych: Celery batchusers-workerk8s-worker-storage · k8s-worker-storage-2users-worker odbiera pracę dotyczącą własności postaci w partiach.
users-worker
k8s-worker-storage · k8s-worker-storage-2przepływ danych: UPSERTPostgreSQLk8s-postgresqlJest ona stosowana w PostgreSQL.
Konfiguracja · skalowanie · obserwacja
Platform Layer nie jest etapem, przez który przechodzą żądania; wdraża, konfiguruje, skaluje i obserwuje pozostałe warstwy. Węzły to instancje EC2 utworzone przez Terraform, z kubeadm i Calico zainstalowanymi przez Ansible; CI tylko waliduje Terraform i nigdy nie stosuje go automatycznie.
GitHub Actions · Docker Hubkonfiguracja · skalowanie: obraz · rewizja manifestuArgo CD image updater
k8s-masterArgo CD uzgadnia konfigurację klastra przez App-of-Apps i Sync Waves. Potwierdzono tylko umieszczenie image updatera w control-plane.
ALB Controller · ExternalDNS
k8s-masterkonfiguracja · skalowanie: Ingress → ALB · rekordy DNSZarządzane przez AWSALB Controller i ExternalDNS konfigurują zasoby po stronie AWS. To nie jest ścieżka, którą idą żądania.
Istiod
k8s-masterkonfiguracja · skalowanie: konfiguracja xDSIstio ingress Envoyk8s-ingress-gatewayIstiod przekazuje przez xDS konfigurację Gateway, VirtualService i EnvoyFilter do ingress Envoy i do sidecara Envoy każdego API.
KEDA
k8s-monitoringkonfiguracja · skalowanie: liczba podówPula AIk8s-worker-ai · k8s-worker-ai-2KEDA dostosowuje liczbę podów workerów. Liczba węzłów się nie zmienia.
KEDA
k8s-monitoringkonfiguracja · skalowanie: liczba podówpula storagek8s-worker-storage · k8s-worker-storage-2Pody workerów puli storage są skalowane w ten sam sposób.
Fluent Bitobserwowalność: logiElasticsearch
k8s-loggingFluent Bit to DaemonSet na każdym węźle, wysyłający logi do Elasticsearch.
Pula AI
k8s-worker-ai · k8s-worker-ai-2obserwowalność: śledzenie przebiegów LLMLangSmithŚlady wywołań LLM trafiają do LangSmith, zewnętrznej usługi SaaS.
Każde połączenie z tą samą wagą. Wybór przepływu wyróżnia tylko jego ścieżkę z ponumerowanymi krokami.
- Linia ciągła · kierunek przepływu żądań, pracy, zdarzeń i zapisów
- Kropkowana · zapytanie DNS; żądania przez nie nie przechodzą
- Linia przerywana · konfiguracja lub skalowanie; nie ścieżka danych
- Długa kreska z kropką · logi i śledzenie przebiegów
- Gruba czarna linia · wybrany przepływ; liczby podają kolejność
- Ramka · fizyczny węzeł, nazwa hosta w nagłówku
- Wewnętrzny element · workload działający na tym węźle
- Przerywana obwódka · dwuwęzłowa pula planowania
- Przerywana ramka · poza klastrem, nie liczona jako węzeł
- Pomarańczowy obrys · miejsce, w którym decyduje model
- Control plane1 węzeł
- Domain API8 węzłów
- Pula AI2 węzły
- pula storage2 węzły
- Data5 węzłów
- Platform6 węzłów
Pięć warstw z README (pasy) i grupy fizyczne (odcień nagłówka każdego węzła) grupują te same 24 węzły inaczej. State KV dzieli węzeł ze Streams i nie jest liczony osobno; Route 53, ALB i usługi spoza klastra nie są węzłami. Pula to zakres planowania, a nie twierdzenie, że każdy pod działa na obu węzłach.
24węzły
24 = 1 control plane + 8 API + 4 worker + 5 data + 6 platform
1Control plane
role: control-planekube-apiserver · scheduler · controller-manager · etcd oraz kontrolery platformy.
- k8s-master
8Domain API
domain: <usługa>Jeden węzeł na domenę. Wywołania wewnętrzne używają gRPC.
- k8s-api-auth
- k8s-api-users
- k8s-api-scan
- k8s-api-character
- k8s-api-location
- k8s-api-image
- k8s-api-chat
- k8s-api-info
4Execution worker
Dwie pule planowania po dwa węzły. KEDA zmienia liczbę podów; liczba węzłów pozostaje taka sama.
pula storage
domain: worker-storage- k8s-worker-storage
- k8s-worker-storage-2
Pula AI
domain: worker-ai- k8s-worker-ai
- k8s-worker-ai-2
5Data
Redis jest podzielony według przeznaczenia na cztery węzły. Magazyn PostgreSQL to EBS CSI · gp3.
- k8s-postgresql
- k8s-redis-auth
- k8s-redis-streams
- k8s-redis-cache
- k8s-redis-pubsub
6Platform
Komunikaty, obserwowalność, ingress i dostarczanie w czasie rzeczywistym mają każdy własny węzeł.
- k8s-rabbitmq
- k8s-monitoring
- k8s-logging
- k8s-ingress-gateway
- k8s-sse-gateway
- k8s-event-router
- Każdy węzeł
- Fluent Bit · DaemonSet
- Calico
Skonfigurowane modele · według dostawcy
Usługa została wyłączona, więc są to modele skonfigurowane w repozytorium, a nie dziś dostępne opcje. Każda rola jest wymieniona osobno; to nie jest lista zweryfikowanych przebiegów.
OpenAI
Domyślny dostawca Chat
Chat
openai/gpt-5.2domyślny
Domyślnym modelem jest gpt-5.2; model wskazany w żądaniu ma pierwszeństwo.
Scan
gpt-5.2domyślnygpt-5.2-progpt-5.1gpt-5gpt-5-progpt-5-mini
Modele spoza mapowania 13 modeli są odrzucane.
Mapowanie obrazów
gpt-image-1.5
Oddzielny od gpt-5.2, modelu orkiestracji Responses. Generowanie obrazów jest domyślnie wyłączone.
Ewaluacja
gpt-4o-minidomyślny
Oceniający LLM do ewaluacji rozmów, oddzielny od modelu Chat.
Google
Gdy Chat wybiera Google
Chat
google/gemini-3-pro-previewgoogle/gemini-3-flash-preview
Przy wybranym Google domyślny jest gemini-3-flash-preview.
Scan
gemini-3-pro-previewgemini-3-flash-previewgemini-2.5-progemini-2.5-flashgemini-2.5-flash-litegemini-2.0-flashgemini-2.0-flash-lite
Mapowanie obrazów
gemini-3-pro-image-preview
Źródłobackend main d8840c7Publiczny commit September 29, 2026 · sprawdzono October 8, 2026