주제: architecture
-
파이프라인, 팬아웃, 오케스트레이터, 비평 패널: 작업 유형별로 맞는 멀티 에이전트 패턴
파이프라인은 정해진 순서의 변환 작업에 적합하고, 병렬 팬아웃은 서로 독립적인 하위 질문이나 여러 번 시도한 뒤 투표로 고르는 작업에 적합합니다. 오케스트레이터와 워커 구조는 작업을 어떻게 나눌지 실행 시점에야 알 수 있는 작업에 맞고, 비평 패널은 여러 기준으로 결과물을 검토해야 할 때 적합합니다. 각 패턴은 토큰 비용을 늘리고, 그 자체로 실패할 수 있는 조정 계층을 추가로 도입합니다.
-
기술적 의사결정을 위한 DACI와 RACI: 승인자는 한 명, 기여자는 이름으로 지정
DACI는 의사결정을 진행하는 드라이버, 결정을 내리는 단 한 명의 승인자, 발언권은 있지만 표결권은 없는 기여자, 결과를 전달받는 정보 수신자를 지정합니다. RACI는 각 작업에 실행 책임자(Responsible), 최종 책임자(Accountable), 자문 대상(Consulted), 정보 수신자(Informed) 역할을 부여합니다. 논의가 시작되기 전에 역할을 미리 문서로 정해 두면 둘 다 기술적 의사결정에 효과적입니다.
-
.NET 의존성 주입 관례: 라이프타임, 스코프, 그리고 captive dependency 함정
Microsoft.Extensions.DependencyInjection은 IServiceCollection에 transient, scoped, singleton 라이프타임으로 서비스를 등록하고, 공개 생성자를 통해 주입합니다. 문서화된 규칙은 scoped 서비스를 singleton에 주입하지 말 것, 컨테이너가 만든 것은 컨테이너가 정리하게 둘 것, 서비스 로케이터 방식의 호출을 피할 것, 그리고 스코프 검증을 켜서 captive dependency가 요청 사이에 상태를 누출시키는 대신 시작 시점에 바로 실패하게 할 것입니다.
-
Event sourcing and CQRS: what they buy and what they cost
Event sourcing stores every state change as an immutable event and derives current state by replay; CQRS separates the write model from read models. Both add auditability and flexibility at the price of complexity and eventual consistency.
-
Choosing Go or Rust for a new service: a decision procedure without benchmarks
Decide between Go and Rust for a service from documented language properties and team constraints rather than from benchmark folklore: memory management model, error and concurrency style, the shape of the workload, the libraries the service must talk to, and who will maintain it in two years.
-
Technische Schulden als bewusste Entscheidung mit Buchführung
Cunninghams Metapher: Nicht ganz richtiger Code ist ein Kredit, jede Minute Mehrarbeit daran ist der Zins. Die Metapher trägt nur, wenn die Schuld bewusst aufgenommen, notiert und regelmässig bewertet wird; als Sammelbegriff für alles Unschöne oder als Entschuldigung für Schlamperei ist sie wertlos.
-
Selecting a tool or skill with a decision model: Choice to rank, Noul to abstain
Why a Choice over candidate tools answers a relative question (which candidate fits best) while a Noul per candidate answers an absolute one (does this turn need a tool at all), and how TypeSafe's skill-suggestion cookbook combines both over a catalogue of 182 skills: one request ranks all, a second reads the top three and may reject all of them.
-
File upload service walk-through: direct-to-storage tickets, asynchronous scanning and quotas
A design walk-through for uploads that bypass the application servers: a ticket that reserves quota and returns a signed upload URL, a completion step that verifies the stored object, a scan worker that promotes or deletes it, lifecycle rules for abandoned uploads, and a status model that explains every stored object.
-
Notification service walk-through: channels, preferences, delivery attempts and retries
A design walk-through for a multi-channel notification service: an ingest API with an idempotency key, a router that expands one notification into per-channel deliveries after checking preferences, per-channel queues and retry schedules, callback handling for invalid tokens, and what to defer.
-
Storing derived data in PostgreSQL: generated columns versus materialized views
A generated column derives one value per row from that row alone, either virtual (computed on read) or stored (computed on write), and may use only immutable expressions; a materialized view stores the result of any query and is only as fresh as its last REFRESH. Use stored generated columns for per-row normalisation that should be indexed, materialized views for expensive aggregates that may lag, and a maintained summary table when neither fits.
-
Agent memory design: what to persist, what to summarise and what to forget
An agent's memory has three tiers: the context window, a task scratchpad and a durable store across sessions; decide per item which tier it belongs to, keep durable memory small and reviewable, and delete what is no longer true.
-
Server-sent events versus WebSockets
Server-sent events stream text events from server to client over plain HTTP with automatic reconnection and last-event IDs; WebSockets provide a bidirectional binary-capable channel with its own protocol. Choose SSE for one-way updates and WebSockets when the client must send frequently.
-
Abstaining as an agent: when not acting is the correct output
An agent's output space should include a deliberate 'not decided' for every automated action: what abstention is, why a classifier or agent without one converts every unclear case into a wrong action, and how to build abstention in through explicit options, floors on confidence, stakes-dependent thresholds and a route for what was abstained from.
-
When does client-side routing still pay off now that browsers offer bfcache, prerendering and cross-document view transitions?
Open question: in-page routers were adopted to avoid full page loads, at the cost of shell serving, 404 handling, scroll and focus restoration and a bundle that must arrive first; the back/forward cache, the Speculation Rules API and cross-document view transitions now address the original motivations in multi-page sites. For which sites and interaction patterns does an in-page router still measurably win?
-
At what repository size do teams need monorepo build tooling beyond plain Git?
Open question: sparse checkout, partial clone and per-directory CI filters cover the first stage of a growing single repository; at which size, team count or build time have teams found that a build graph tool with remote caching became necessary, and what did the transition cost?
-
Choosing between threads, processes and asyncio for a Python workload
Classify the hot path first: waiting on I/O suits asyncio (many connections, async libraries) or a thread pool (few blocking calls); pure-Python CPU work needs processes or a free-threaded build; native code that releases the GIL can use threads. Bound every pool, choose the process start method explicitly and write the shutdown path.
-
URL shortener walk-through: key generation, redirect status and abuse controls
A design walk-through for a URL shortener: random base62 keys with collision retry, a redirect path that touches one cache and one store, 302 rather than 301 when targets must stay revocable and countable, creation-side abuse checks, and a list of what not to build first.
-
Architecture decision records
An architecture decision record captures one significant decision with its context, the decision itself, its status and its consequences, in a short file kept with the code.
-
Caching in Anwendungen: Ablaufzeiten, Invalidierung und Schutz vor dem Ansturm
Ein Anwendungs-Cache hält abgeleitete Daten und darf jederzeit verloren gehen; korrekt bleibt er nur durch bewusste Invalidierung: Ablaufzeit je Datenklasse, Löschen statt Überschreiben beim Schreiben, Versionskennung im Schlüssel und eine Sperre gegen gleichzeitiges Nachladen heisser Schlüssel.
-
ETL versus ELT: where the transformation runs and what that changes
ETL transforms data in a separate engine before loading it into the target; ELT loads raw data first and transforms it with the target store's own processing. The choice decides where compute is paid for, what raw data lands in the warehouse, and how easily a transformation can be rerun.
기계 판독 가능: JSON