← All AI Engineer talks

AI Engineer Europe 2026

Feedback Loops are All You Need

Mehedi Hassan· Product Engineer, Granola10:11

Read the talk

Feedback Loops Are All You Need

Granola makes AI features easier to improve by exposing the agent’s decisions and turning its desktop interface into shareable web previews.

From a talk by Mehedi Hassan

Before you start: Basic familiarity with LLM tool calls, pull requests, and web front ends will help; Electron’s process model is explained in the article.

A summary that notices what you wrote down

How do you make meeting notes reflect what a person actually cared about? At Granola, that is a product engineering problem as much as a model problem. Mehedi Hassan approaches it from a career spanning jQuery, React’s reshaping of front-end development, and now LLMs. His focus here is the work around the model: making its behavior useful and making the resulting product easier to test.

Granola sits in the dock and captures both system audio and microphone audio to produce a real-time transcript. In the opening demonstration, Hassan uses a recording of the preceding talk. Alongside the transcript, users can write their own notes, giving the app a signal about what deserves emphasis rather than leaving it to summarize every topic equally.

When Hassan generates the summary, he points to how his note about twenty percent overlap influenced the output’s emphasis. The percentage belongs to the content of the preceding talk; it is not a measurement of Granola’s accuracy. The intended result resembles what the user would have written on a notepad, with the transcript supplying the detail. Hassan describes the ambition as best-in-class meeting notes across roles, delivered without getting in the user’s way.

0:150:28
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

0:15 · section reference included

A chat box meets specific expectations

That unobtrusive product philosophy becomes harder to maintain as AI features expand. Granola’s existing chat can answer questions about a single meeting, multiple meetings, or shared context. Hassan imagines building a version in one shot and shipping it in a fake Granola app. Getting the chat interface working is easy; the hypothetical users immediately expose what it does not understand.

Slide posing the production question beside a Granola chat response listing promised follow-ups.
What happens when you put a simple AI feature into production?

Their complaints span several different problems:

  • Task completion: It cannot produce the requested to-do list.
  • Latency: Web search takes too long.
  • Personal style: Follow-up emails do not sound like the person sending them.
  • Intent: A request for coaching about meetings produces an answer about a football coach.

These examples make the gap concrete: a general chatbot can respond fluently while still failing the particular job the product promises to do. Molding the model to that job becomes the difficult part.

1:522:03
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

1:52 · section reference included

One meeting, different useful outputs

Even when the information is correct, the output can miss the user’s needs. The opening summary suited Hassan, but another role might expect a different selection and organization of the same meeting content.

RoleExpected emphasis
SalesDeals
EngineeringAction items, blockers, Linear tickets
HRDifferent needs, left unspecified

One prompt generally cannot serve all of those expectations. The problem is not simply generating a good-looking summary; it is understanding why the model produced this summary for this use case. That requires inspecting behavior that otherwise feels opaque and difficult to steer.

4:014:12
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

4:01 · section reference included

Follow the agent from beginning to end

Granola’s response was to build its own tracing tools. This is a place where Hassan finds one-shot generation useful: it reduces the effort required to build internal software around the product. The trace exposes individual tool calls from beginning to end, recorded reasons for those calls, search trails, reasoning trails, and cost. Instead of seeing only the final answer, an investigator can follow the sequence that produced it.

The team tailored both the data structure and the interface to its own investigations. Engineering, product, data, and customer experience staff all need to use it; diagnosing a failure should not require writing complex CloudWatch queries. Hassan contrasts this with the earlier economics of internal tooling, when a team might have depended on a SaaS product because building a suitable interface took too much time. The displayed trace makes that interface concrete, showing reasoning, meeting search, calendar search, and expanded calendar results in one vertical sequence.

Slide pairing tracing guidance with a vertical trace showing reasoning, meeting search, calendar search, and expanded calendar results.
Tracing the agentic loop end-to-end.

The implementation he describes is deliberately small: wrap AI SDK calls, save records to a database, and build the front end around how people investigate failures. He also names OpenTelemetry and other providers as options. The related AI SDK telemetry documentation is an implementation reference, rather than a specification of Granola’s wrapper. The essential product decision is to make the collected data usable by the people who need to act on it.

Hassan describes Granola’s founder following an entire agent loop from front to back to find what went wrong. That changes the next iteration: a vague impression that an output feels wrong becomes an identifiable failure in the sequence. Tracing is valuable when it turns dissatisfaction into a specific thing to change.

4:394:49
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

4:39 · section reference included

Make desktop experiments easy to open

Inspecting model behavior addresses only part of the feedback loop. Users also experience the interface around the output. LLMs make it cheaper to build different features and multiple versions of the same feature, but those variants are useful only if people can try them. Granola’s desktop setup allowed one app instance at a time, which made testing variants in parallel awkward.

Previously, a tester had to install dependencies and run the Electron app locally. Sharing a change with a coworker meant asking that person to repeat the setup. Granola removed much of that friction by turning the Electron front end into an online web shell. Its CI now produces a preview link whenever a pull request opens, so colleagues can open the proposed interface directly. Hassan reports that this substantially sped up development.

The preview also gives an agent somewhere to exercise the change. In Hassan’s reported workflow, Cursor tests the preview after a pull request opens and uploads a screenshot to the PR. This adds visible testing evidence to the review; it does not establish that every behavior has been verified. The same accessible environment serves both human reviewers and the agent.

6:196:33
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

6:19 · section reference included

Separate the renderer from its desktop environment

The web shell depends on a boundary Electron already provides. Its main process handles native capabilities, while its renderer process supplies the web-based front end. IPC—inter-process communication—lets the renderer request functionality across that boundary; IPC is not itself a system API. Granola abstracted those calls so that the web environment could use web-standard implementations.

A small TypeScript example shows the shape of that boundary using a clipboard operation. The renderer receives one interface; the desktop entry point can supply its IPC-backed implementation, while the browser entry point supplies the Clipboard API:

typescript

interface ClipboardPort {
  writeText(text: string): Promise<void>;
}

function createCopyNotes(clipboard: ClipboardPort) {
  return async (notes: string): Promise<void> => {
    await clipboard.writeText(notes);
  };
}

// Browser entry point
const webClipboard: ClipboardPort = {
  writeText: (text) => navigator.clipboard.writeText(text),
};

const copyNotes = createCopyNotes(webClipboard);

const button = document.createElement('button');
button.textContent = 'Copy notes';
button.addEventListener('click', () => {
  void copyNotes('Follow up on the meeting action items.').catch(
    (error: unknown) => console.error('Could not copy notes', error),
  );
});
document.body.append(button);

Clipboard copying is an illustrative application of the abstraction, not a reported Granola feature from this demonstration. Browser clipboard writes require a secure context and are subject to browser permission and activation rules. The architectural point is that the consuming code does not need to know whether the implementation crosses Electron IPC or calls a browser API.

Granola applied the same separation to its React-facing infrastructure: routing, sessions, and the query layer moved to web standards. With those dependencies no longer tied to Electron, the renderer could run as a web app. The architecture slide brings the IPC and React abstractions together as the basis of the web shell.

Slide describing Electron IPC and React API abstractions alongside code for a web shell and environment-independent routing.
How the web shell works.

The payoff is the ability to experience several versions of a feature in practice. Instead of judging only a Figma design, the team can use each version, feel how it behaves, and compare alternatives before deciding what ships. More generated variants become more useful experiments because the cost of opening and testing them has fallen.

7:447:56
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

7:44 · section reference included

Build conviction through iteration

The useful improvement is a better feedback loop, not simply a better first generation. Hassan compares working with an LLM to playing tennis: the result develops through repeated exchanges. Traces make the model’s failures inspectable; accessible previews let people experience proposed changes. Together, they replace hoping a feature will work for customers with a stronger basis for believing it will connect. The desired experience can feel like magic to the user without remaining an unexplained black box to the team building it.

The closing platform question tests whether that approach requires replacing Electron with Tauri. Granola has considered the move several times and tried Tauri, but Hassan says Electron currently serves the team well. Hassan reports that Granola’s Tauri trials did not produce major performance gains, the team’s main criterion for the move. He also mentions changing APIs without identifying which platform he means. The experiments have not shipped: the practical improvement described here came from making the existing renderer portable and easier to test.

8:459:00
Suggest correction

This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.

8:45 · section reference included

Resources

From the talk

  • Meeting-notes application that captures computer audio and enhances notes without adding a meeting bot.

  • Explains main and renderer processes, preload scripts, and communication between desktop capabilities and web interfaces.

  • Introduces the architecture of Tauri applications and their use of operating-system WebViews.

Read the complete timestamped transcript
  1. 0:00

    [upbeat music] Cool.

  2. 0:15

    How's it going, guys? Uh, I'm Mehedi. Uh, we're gonna talk about some product engineering stuff that we've been doing at Granola. Uh, this is not gonna go deep into AI engineering stuff, so if you're here for me to, like, go into LLMs and stuff, it's not gonna happen.

  3. 0:28

    I'm warning you right now, uh, so you know what's coming. Cool. So I'm a product engineer at Granola. I've been, you know, coding since jQuery was cool. I've seen React kind of change front-end engineering, and obviously now experiencing LLMs change, um, engineering and everything else, uh, just like many of you.

  4. 0:45

    For those of you who don't know, Granola is an app for getting your work done. Essentially, we're a meeting notes app where we s- uh, s-sit on your dock, uh, like it is doing right now.

  5. 0:56

    Um, and it-- I have access to your system, uh, transcription, uh, system audio, as well as your microphone audio, which means we have real-time transcription, and then at the end of your meeting, we can give you really awesome notes.

  6. 1:07

    So I'm just gonna give you a quick demo. So I was, uh, recording the previous, um, talk right here, and you can see it picked up literally everything the presenter said.

  7. 1:16

    Uh, and the cool thing about Granola is that you can also write your own notes on top of what the transcription is saying. So the final result is more aligned to, like, what you'd normally actually write on a notepad.

  8. 1:27

    So I'll go ahead and generate the, uh, notes here, and you'll see that this will go ahead and write a really good summary. Um, and as you can see, like, I wrote down this twenty percent overlap thing, and it focused more on the output, right?

  9. 1:40

    So this is, uh, Granola. We have the best-in-class meeting notes, no matter what role you're in, and it doesn't get in your way, and that's been, like, our product philos-philosophy since day one.

  10. 1:52

    So we ship a lot of, uh, AI features, uh, in Granola, and our product is known to be, again, not to get in your way. So let's see what happens when you put a simple AI feature into prod.

  11. 2:03

    Uh, I'm gonna kind of give you an example with this chat feature that we have. This is a feature that already exists, uh, in Granola. You can ask questions about a meeting that you just had and across a bunch of different meetings, uh, or, like, shared context, uh, as well, and Granola will try to answer it to

  12. 2:17

    the best of your, uh, its ability. So let's say I built, you know, like I one-shot this, uh, chat system. It's very easy to do. Uh, and I put it into production in my fake, uh, Granola app.

  13. 2:28

    And then as soon as users hit it, you know, it's like it can't give me a list of to-dos. Uh, web search is too slow. Uh, it's not writing follow-up emails how I normally write my emails.

  14. 2:36

    I ask it to coach me about my meetings, and it's telling me meetings about my football coach. Obviously, these are very, uh, pro-- very common problems that you're gonna run into when you make a generate, uh, chatbot.

  15. 2:47

    So how do we get around this, right? So m-- what we've seen is, like, molding, uh, the LLM to work to a specific use case can be super hard.

  16. 2:56

    Um, and one of the examples is, is web search. So web search for most, uh, LLM providers looks like a line of code. You simply add the web search tool, and you expect it to just work.

  17. 3:06

    That's what the labs want you to be-believe, but once you get into it, there's lots of other complications. So for example, the token usage and token costs can bubble up quite a lot, especially for complex queries.

  18. 3:16

    It's gonna blow up your context, uh, and each chat could be costing you, like, ten pence. Obviously, at scale, when you have millions of users, this is not really feasible.

  19. 3:24

    Um, and then, you know, like, the web search providers are also, like, completely up to the labs as well. So for example, in, uh, in our, uh, development, what we see was, like, was we were using a model for a good amount of time, and then overnight they shipped an update, and for some reason web search degraded,

  20. 3:40

    uh, and it was completely out of our control. And we generally had no idea, like, what was going on apart from just, like, switching, uh, providers. But we wanna have more control over that because it affects our user, user experience.

  21. 3:51

    Um, and you know, like, there's literally billion-dollar companies who do web search. So that kind of tells you that it's what's much more than just adding a web search tool to your LLM pipeline.

  22. 4:01

    The other thing that's super important for apps like Granola is the output. So the summary that you saw was pretty good for what I would expect. But someone in sales might expect more of a deal focus.

  23. 4:12

    Someone in engineering might expect, like, action items, blockers, like Linear tickets. HR might want something completely different. And the thing is that one prompt can't generally serve everyone. And, you know, LLMs are stubborn, and we need to figure out how to get inside them and make them work how we want it to work. [clears throat]

  24. 4:30

    And yeah, as you, as you know, like, LLM behavior is largely seen as like a black box, but we wanna kind of go very deep into the details and figure out exactly what's going on.

  25. 4:39

    So what we did recently at Granola is we started building our own tracing tools, and obviously, thanks to LLMs, you can actually one-shot these things. And this is where one-shotting is kind of nice.

  26. 4:49

    Um, and so we built our tooling, uh, tracing tools here, where we basically have complete visibility on the tool calls straight from the beginning to the end. So we have full visibility over the individual tool calls, why it's making those tool calls, the search trails, the reasoning trails, the cost.

  27. 5:04

    It, it's structured exactly how we want it. And the most useful part of this is that we structured the data exactly how we want it, and the UI is built to, like, serve our, uh, our employees internally, not just, like, engineers, but also product, um, data, and, like, CX and everyone.

  28. 5:20

    So you don't have to, like, you know, go into CloudWatch and do, like, very complex queries to figure out why something failed. And that's been, like, the key, uh, for us to, like, figuring out this black box.

  29. 5:29

    Um, and previously, obviously, building this kind of tools would be, like, up to using a SaaS provider. Um, and it simply wouldn't-- You simply wouldn't have the time. But now you actually can spend time building this tracing tool that actually serves what you need.

  30. 5:43

    And this is obviously a very, um, basic example, but obviously you can use OpenTelemetry or, like, other providers. But we essentially just, like, save things, uh, to a DB, wrap around, like, AI SDK, uh, and then the front-end is, like, kind of the most important part 'cause that's what people are gonna use to figure out what, um,

  31. 6:00

    breaks and what doesn't. And we literally have, like, our founder literally goes into, like, the details, like following the agent, um, loop completely front to back to figure out exactly what went wrong.

  32. 6:11

    So then at the end of this, you can actually figure out, like, you know, this output feels off to, like, exactly what failed. And then when you iterate, you can improve on those things.

  33. 6:19

    But as I said earlier, this is gonna be more, more than just like basic LLM stuff. Um, and LLM behavior is obviously part of the picture. The how users interact and experience is, your product is also very important.

  34. 6:33

    So with LLMs, you can one-shot more things, and you can have more variants, which we like, 'cause we can experiment with different features. We can experiment with, like, one feature looking very, uh, different and for different users.

  35. 6:44

    But the problem for us specifically at Granola was that we are a desktop app, which means you can only run one instance of the app at a time. And there was a lot of friction when it came to, like, testing new features, different variants, uh, and actually testing those in parallel. [clears throat]

  36. 6:59

    So before, you know, um, before you'd have to like run the Electron app locally, install the dependencies, uh, and test things. If you wanted a coworker te- to test those changes, you'd have to get them to do those things as well.

  37. 7:11

    We have- we didn't have the same luxuries as like web apps do. So essentially what we did is we took our Electron app, and we turned the front end of the Electron app into a web shell, and this was deployed online.

  38. 7:22

    So now our CI, whenever we open a PR, we get a preview link, and we can go and test those things. And this generally sp- sped up our development time so much more.

  39. 7:31

    Uh, and like the cooler part of this is that because LLMs can now self-verify their work, these guys are now, like, once we open a PR, Cursor goes and tests it, uploads a screenshot into our PRs, which, uh, speeds up the testing so much more.

  40. 7:44

    And again, this is like, you might think that this is a lot of work, but it's actually quite simple. So what we did is, um, for those of you who are not familiar with Electron, there's obviously a main process, um, and a renderer process.

  41. 7:56

    The main process works with the system APIs, and the renderer process is basically your front end. Uh, and essentially, we abstracted our IPC APIs, which is the system APIs, uh, to fall back to web standards when we're in the web environment.

  42. 8:08

    And similarly with React APIs as well, like routers, sessions, and query layer, we moved those to the, um, uh, web standards. Um, and essentially, this just made the renderer agnostic of re- of Electron, and we could just simply run it as a web, web app.

  43. 8:22

    So essen- this has helped us, on top of the LLM improvements, uh, was like we were able to just like change, uh, like test like one feature in like multiple different variants.

  44. 8:31

    So like whatever the end product is actually feels super good 'cause we know that we've tried so many different variants, um, and we actually felt those, um, products in, in like in practice rather than just like seeing it in Figma.

  45. 8:45

    So essentially this, this is basically a long talk to tell you that the answer isn't to one-shot better. It's about figuring out how you can make that feedback loop where it kind of feels like playing a tennis game with LLM so the end product feels more like magic rather than just like a black box, and hoping that

  46. 9:00

    the feature that you're gonna release works well with customers, and having that conviction that what you are shipping is actually gonna connect to the users. Yeah.

  47. 9:09

    Thank you. Any questions? [clapping] Are you thinking about replatforming from Electron to Tauri? Um, we, we've thought about moving to Tauri, uh, a couple times.

  48. 9:26

    Um, I think the way Electron serves us right now has been super nice. Uh, like the API is changing quite, quite a lot. We've tried Tauri before as well, and we didn't really see, uh, massive performance gains, uh, which we, which is what we care about the most.

  49. 9:39

    Um, so yeah, it's been discussed before. We've played around with it but haven't shipped it.

  50. 9:48

    Cool. Thank you, guys. [clapping] [outro music]