Archive
1290 posts · Page 88 of 108. ← Blog
Most software processes data at rest: you store it, then query it. Stream processing flips that — it computes on data in motion, as each event arrives, continuously and forever. This shift from "store then process" to "process as it flows" underpins fraud detection, real-time analytics, monitoring, and the event-driven systems that react to the world as it happens. This series builds stream processing from first principles, starting with why computing on data in motion is a fundamentally different model.
Most software processes data at rest; stream processing computes on data in motion, as each event arrives, continuously and forever. Batch vs stream, why unboundedness makes streaming hard, and when latency justifies its complexity over simpler batch.
The instinct, once single agents work, is to build teams of them — a researcher agent, a writer agent, a critic agent, all collaborating like a little organization. It's an appealing vision, and sometimes exactly right. But multi-agent systems are also where a lot of complexity and cost hides, and the honest guidance is more restrained than the hype: use multiple agents when the problem genuinely calls for it, and prefer a single well-designed agent when it doesn't. Understanding the multi-agent patterns — and their real tradeoffs — is what lets you make that call well.
The instinct, once single agents work, is to build teams of them — a researcher, a writer, a critic, collaborating like an organization. Sometimes that's right. But multi-agent systems are also where a lot of complexity and cost hides, and the honest guidance is restrained: use multiple agents when the problem genuinely calls for it, and prefer a single well-designed agent when it doesn't.
Teach an agent a capability from a folder of files — a SKILL.md manifest, resources, and scripts — loaded on demand via progressive disclosure.
Teach an agent from a SKILL.md manifest, resources, and scripts on disk: fsskills scans the tree and a skills ContextProvider exposes load, read, and run tools.
The reference architecture distinguishes request-based and message-driven agent communication. For in-process orchestration, the workflow IS the broker — and A2A is just the wire format.
The first output is rarely the best output — a truth as old as writing, and one that applies to agents too. An agent that acts once and moves on repeats its mistakes; an agent that looks back at what it did, judges whether it worked, and tries again can dramatically improve. Reflection — the agent evaluating and correcting its own work — is what turns a one-shot attempt into an iterative process that gets better, and it's one of the most powerful patterns for making agents reliable on hard tasks.
The first output is rarely the best output. An agent that acts once and moves on repeats its mistakes; an agent that looks back at what it did, judges whether it worked, and tries again can dramatically improve. Reflection turns a one-shot attempt into an iterative process that gets better.
The provider is the swappable back end: the same Joker agent, one-shot and streaming, now through the OpenAI API.
The same Joker agent, one-shot and streaming, through openaiprovider: openai.NewClient reads OPENAI_API_KEY and the model name lives in AgentConfig, not a Foundry deployment.
AgentSession is short-term memory. MemoryContextProvider + MemoryFileStore is long-term memory. Mem0 is long-term memory for serious workloads. The boundary that matters and how to implement each.
An LLM is, fundamentally, stateless — it remembers nothing between calls except what you put in its context window. For an agent that takes many steps or works across many sessions, that's a serious problem: without memory, every step starts from scratch, and nothing is ever learned. Memory is how agents overcome statelessness — holding the context of the current task, and carrying knowledge across tasks and time. Understanding the kinds of agent memory, and their limits, is essential to building agents that can handle real, extended work.
An LLM is fundamentally stateless — it remembers nothing between calls except what you put in its context. For an agent that takes many steps or works across sessions, that's a serious problem. Memory is how agents overcome statelessness — holding the current task's context, and carrying knowledge across tasks and time.
A provider whose "credential" is a local process, gated by a human-in-the-loop permission handler for every action the model wants to take.
A provider whose credential is a local copilot CLI process, with an OnPermissionRequest handler that approves or rejects each shell action the model wants to run.
The Microsoft Agent Framework deliberately does not ship an agent registry. Here is why that is the right call, and what to build as a project-local convention when you need one.
Ask an agent to "research this market and write a report" and it faces the same problem a person would: the task is too big to do in one leap. The answer, for agents as for people, is to break it down — decompose the goal into steps, and work through them. Planning is how agents handle complexity that the basic reason-act loop alone would fumble, and the patterns for doing it — from planning upfront to decomposing on the fly — are among the most important in agent design.
Ask an agent to 'research this market and write a report' and it faces the same problem a person would: the task is too big to do in one leap. The answer, for agents as for people, is to break it down. Planning is how agents handle complexity that the basic reason-act loop alone would fumble.
How swapping in the Gemini provider changes the constructor and credential — and nothing else about your agent.
The Joker agent, unchanged, now backed by Google Gemini: geminiprovider.NewAgent takes a genai.Client and an API key instead of an Azure token credential.