IBM agent types
Learning agent
A critic scores its actions; it gets better with experience.
A learning agent improves from feedback. The performance element acts; a critic judges the outcome; the learning element updates what the agent believes works; a problem generator makes it try something new now and then, so it does not settle too early.
Here a support bot learns which reply style customers rate best over 40 conversations, without being told. Raise exploration to try other styles more often.
- Use it when
- Feedback arrives over time (ratings, outcomes, tests)
- The best action is not known in advance
- Conditions drift and the agent should keep up
- Skip it when
- Mistakes are expensive while it learns
- There is no reliable feedback signal
Run it
No model needed · CriogenAI engine in your browserThe run
- Press Run to watch the pattern work, step by step.
This run is the TypeScript code below, running on the CriogenAI engine in your browser (WebAssembly). Without a key, a scripted model stands in for MODEL; with your key, your provider answers, called from this tab. The tools return made-up data.
Build it with CriogenAI
Built from primitives:Memory (stores what was learned) + a hook that scores runsimport random
from criogenai import Storage
storage = Storage("sqlite://learning.db") # what the agent has learned survives restarts
styles = ["short", "detailed", "friendly + steps"]
async def known(style: str) -> Dict[str, Any]:
item = await storage.recall("styles", style)
return item["value"] if item else {"n": 0, "mean": 0.0}
async def reply(question: str, rating_of: Callable[[str], float]) -> None:
scores = {s: await known(s) for s in styles}
explore = random.random() < 0.2 # the problem generator: sometimes try something new
style = random.choice(styles) if explore else max(styles, key=lambda s: scores[s]["mean"])
reward = rating_of(style) # the critic: a customer rating, a test, a metric
s = scores[style]
s["n"] += 1
s["mean"] += (reward - s["mean"]) / s["n"] # the learning element
await storage.remember("styles", style, s)const storage = new Storage("sqlite://learning.db"); // what the agent has learned survives restarts
const styles = ["short", "detailed", "friendly + steps"];
type Score = { n: number; mean: number };
const known = async (style: string): Promise<Score> =>
((await storage.recall("styles", style))?.value as Score | undefined) ?? { n: 0, mean: 0 };
async function reply(question: string, ratingOf: (style: string) => number) {
const scores = Object.fromEntries(await Promise.all(styles.map(async (s) => [s, await known(s)] as const)));
const explore = Math.random() < settings.explore / 100; // the problem generator: sometimes try something new
const style = explore ? styles[Math.floor(Math.random() * styles.length)] : styles.reduce((a, b) => (scores[b].mean > scores[a].mean ? b : a));
const reward = ratingOf(style); // the critic: a customer rating, a test, a metric
const s = scores[style];
s.n += 1;
s.mean += (reward - s.mean) / s.n; // the learning element
await storage.remember("styles", style, s);
}