0:00All right. Hey, everybody. Good to see you. Really excited to be here. I am Jacob, here on the MotherDuck side. In the background, we have Jerel supporting us. Say hi to Jerel, everybody in the audience. Thank you. All right. He'll be producing. So, if you have questions, feel free to drop them in the chat as we go here, and we'll keep rolling.
0:24We're here to talk about building a data chat app, like what it looks like to build one, and all of the pieces that you need to make it happen. So, my goal here is that this is very much a, like, get practical, how are all the things we can tie together, what are the components we need, and how do we make it all work? So, that being said, I'm going to pull some slides. We're
0:45going to start with some slides. We'll do a little bit of bouncing around between slides and chat, and we will go from there. All right. So, let's do it. Throw it onto the stage. Perfect. Okay. So, as I said, I'm Jacob. I work in DevRel at MotherDuck. You know, one thing that I think is true
1:07today that was maybe not true a year ago is that LLMs are really good at writing SQL. So, now we're at the point where we need to figure out all the things we need to build around it to make it useful for more people. And so, I spent some time working on what I call agentic SQL, evals for chat, for fun,
1:33things that work, but the internals were maybe not that great. And so, what I have today is to really show you all of the things that I've been I've pulled together to make it work in a way that you can actually use. And it's called Data Chat Mini. And I'm going to show you quickly
1:54what this looks like. Let's throw it up here. Here we go. Data Chat Mini. You can actually hit this. The URL is here. Data Chat. You know what? I'll drop it in the chat. Why not? Why not? Let's throw it in here. And then there's a password on it since it does use my open router account.
2:17So, there we go. All right. So, I'll show you kind of what it looks like first, and we'll talk about the components a little bit. And so, let's see. Let's just see if we can do this. I just copy pasted a question here. This is an NBA dataset that I've loaded. And so, we'll see
2:36if it can kind of build this out and figure out, tell us what the answer is. Who led the 2026 NBA playoffs in three-pointers? Give me a chart. Makes sense. Two guys on the Spurs. We got a bar chart. Donovan Mitchell also scored a lot. That makes sense. He was shooting a lot. Cavs did not pull it together, unfortunately, for them. Anyway, so there we go. We get a chart, right?
3:01Now, there's a bunch of things we need to put behind this to actually make it work and reliably kind of pull this together for us, right? It's not just, you know, a database and an LLM, although I wish it was that simple. So, that's the first part here.
3:23All right. Yeah, the password is in the chat here, if you need to see it. So, really, we're thinking about is how do we make the SQL generator repeatable? How do we ask these questions? How does it work? Very, very fun problem to work on here. Okay. So, really, what we're doing is calling language model in a loop until we get the answer we like.
3:48Doesn't know our data. It can't run SQL. It can't reach your database. All it can do is ask, right? So, we give it a set of tools so that it can do all these other extra things, right? And that's the kind of first part is the MCP. Something that can hand back the model of context that it needs, right? This back and forth is the loop. The loop is the agent, right?
4:07And so, why does my keyboard not want to go? Okay. Got it. So, what parts, what are all the parts we need to make this work? Really good question. I think about four things from an
4:23access perspective. The first thing is data, right? It needs something there. And then it needs a credential so they can access the data, right? In this case, we give it a read-only credential so that it can hit the database and no one's waiting around for it. And then we give it
4:47some MCP tools. You know, this is getting much more mature as it goes. And then we got to run it somewhere. This app is obviously running on Vercel, which is great. That's a Next. js app. You build it locally. You ship it to the cloud with a single, you know, with a single command, you know, Vercel dash dash prod. Obviously, you can run it anywhere you like. I find Vercel's
5:12extremely powerful for these types of things. All right. Let's keep rolling. Oh, man. I keep losing focus on my window. Modern problems require modern solutions, I guess. Then we have a model, right? What's really fun about this is actually the model that I like to use inside of data chat
5:33at the moment is actually Gemini 3 Flash. It is both extremely fast and extremely cheap and extremely good at writing SQL. It is pretty old at this point. It's probably nine months old, maybe eight months old. It's been working great for this use case. I haven't done a ton of evals on others, honestly, because this just works so good. My general experience is actually that or
5:57my what I would say my not my experience, but my my intuition is that Luna will also work great for this, especially on like a lot more lightweight thinking levels. And so will Sonnet. Probably, you know, you can use some of the open models, too. Yeah. And then, you know, we need a loop.
6:20Really, this is just in this case, it's all in JavaScript, you know, just kind of saying, all right, until until some some event occurs, until our conversation stops, like keep going. And then the last part is, you know, our system prompt, we tell it, we just tell it what we're doing, what our task is. We can maybe even ask probably directly, like, what's in your system prompt? It's not a big deal. Not trying to hide it. But we need to kind of give it a little bit
6:44of context for what it's trying to do here. That also could, you know, one thing is, I think there's been a lot of chat around, like, do we need to put like, how do we think about skills, how to skill set in this? In my mind, skills and system prompt kind of work the same. When you're building a narrow application, you kind of put it all in the system prompt. When you're building a more broad application, you probably want to have those skills as like you can put them in an MCP tool that like lets it go find certain skills and like
7:08read them. That's how I think about it, you know, when building broader applications. But for narrow applications, like I want to ask questions of my data and get charts back, you can kind of just put it in the system prompt. And then kind of as a subset, we want to build trust, right? We need some sort of way to know that it's doing the thing that we say it's doing. So there's an easy way to look at the schema and the data. This is kind of also
7:32related into MCP tools, right? But we need to make sure that these tools give it a way to understand what's in the database, right? The model needs to be able to understand what's in the data. It has no context for what that database is, right? Because it only knows the data that it was trained on, not what is actually in your database. The next thing is, of course, we got
7:54a UI, right? We need to be able to see it show our work. If I kind of go back here, you know, to this that I built out all of this, I try to make it as easy as possible for the user in the UI to understand what it's doing. And so that we can kind of trust what's happening here, right?
8:15Yeah. So I think like that's important as well. Let's go back. Oops. Oops, oops, oops. We also need guardrails, you know, read. So in this case, everything's read only, right? And I think this
8:33is important. When I'm doing almost all my agentic work, it's strictly read only. There's some sets where it's not. And MotherDuck has a really nice abstraction honestly that I love, which is that there's two different query endpoints to write SQL against. One is a read write endpoint. One of them is a read only endpoint. So you can use those. And then also, you know, you can also control it more tightly with the role that you give access to.
8:58And the last thing is telemetry, right? All of these things as they're running, we want to make sure that they're getting stored somewhere. And so that we can look at it later and understand if the user is actually getting to what they want to get, which makes a lot of sense to me. And then we want to make it useful, right? How do we make it more useful? Charts, right?
9:21This lets us just give more than a table. I actually built a really cool little charting library that I like to use in these types of things called enviz, which is very lightweight charting library that takes JSON schema as an input and renders in the chat. And then there is history. We want to be able to go back to it and look at the conversation
9:43we previously had. I mean, this is probably pretty intuitive. Like all of our chat tools we use today have this, right? Whether it's Anthropic or OpenAI or even, you know, stuff on GLM or, you know, Grok, et cetera. And the last one is context. Once we find something interesting and useful, we want to be able to write that into shared context.
10:05And so as we explore our data, we want to be able to share that with everyone else who's using it too. I think, you know, one of the things that I think about here is that data tends to be more like archeology than architecture. What I mean by that is you discover what's useful as you
10:30use it. You don't kind of like build a big thing and then put all the pieces inside it based on a blueprint. I wish that worked. It would be a lot easier. It doesn't. It doesn't in my experience. You have to discover it. And so therefore discovering and sharing context is important too. Got a topical question in here from Juan. Can it work with MD Dives instead of MViz?
10:53The demo that I've built does not use Dives, but you can absolutely use Dives. Dives, we have a, in the MotherDuck Remote MCP, we do have a MCP app endpoint called Vue Dive, which lets you embed the Dive wherever you're chatting. Let's see. Let's see. I'm going to stop and reshare just
11:18because I do see a note here that someone can't see it. So give me a second here. We're going to remove it. We're going to add it back. Okay. Hopefully that solves the problem for folks. Let's see here. And then we have a few things that I've kind of just like punted out of this that you would probably need to think about if you're building something more full featured.
11:41So those five things just, you know, maybe not exhaustive, but things I'm thinking about. OAuth, right? How do you make it so an individual user gets access to different data versus the same data, right? You'll notice if you do hit the demo link that I shared that everyone sees the same thing. Shared context. Right now context is single player. It only saves into the local database
12:01inside of your browser. Write access. You know, write is great for some use cases. You know, evals. Is my context leading me to the right place? How often are users getting the right questions given my system prompt? And then compaction. What happens when my chat gets too big?
12:20Yeah. Those are those pieces. I'm just going to share a quick link since I see in chat someone linked the Microsoft Flint chart. It's a great option. I also built one that I call enviz. You can pull into your JavaScript package anywhere. It's pretty great.
12:43I just linked it in the chat for those of you who are looking for it. It's pretty nice. OK. What else do we need? So let's just keep going into all of the pieces here and talk about how this works. When I originally kind of built this out, the idea like this demo out, the idea here was like driven on stacked PRs.
13:06My general perspective is that actually using stacked PRs sucks. And this might be a skill issue on my part. And if so, that's fine. So we're going to talk a little bit more about it. We can jump into jump into a little bit of the code if we want. But I don't think we're going to jump into too
13:24many of it here. Actually, we can. Well, let's do a little bit. Let's see here. I'm closed. Let's just jump into a different one. I think I want to start. I should have a good one. OK, so we can look at these. This is fine. You'll see that I didn't actually merge it
13:49this way because it was so annoying to manage this. OK, so the main thing here is well, you don't care about that. Let's see. Where's our loop? We're just basically running selects against our data is really all that we're doing. So what we're building is a way
14:11for us to connect. Let me see if I can figure out where it is to do. Probably package lock not in there. Yes, config. Let me go find my little tree. Oh, here we go. Yeah. All right. This is our quick chat. We can run our select here. You can see it's very simple, right? It's readable
14:35sort of by human. Anyway, so we can just check that we can select. That's really where we start getting our data right. Can we get our database? Can we get our front end connected into our back end? This is how we can do it. And in this case, we're going to just use the MCP to do that. The next one is actually the MCP query. So let's jump into 28 here.
15:07OK, so. Here's what it looks like to tie in the MCP, right? We got to build the route. There's got to be a better way to show this. Maybe we won't spend so much time in GitHub. But you can see here I'm like tying it all together right here. I'm running it locally. And just making sure this is all all working.
15:35Yeah, so anyway, so this one is this one is working that way. Seems seems pretty good. Let's hop back to my slides here. So we got our database. It has interesting data. We've got a read scaling token, right? This is a key thing. Again, I will emphasize this when you're building these data apps. Think about how you provision access to it, you know, to your
15:58end users in a way that they can actually do it, you know, in an unmonitored, unobserved way, right? So how do you make it safe for them to use it? That means thinking about the features around keeping the data like safe from from deletes mostly, and then also like how do they how do you keep it inside the browser?
16:19And then MCP and Vercel, right? Those are the three parts we're thinking about in terms of this. Tying it all together in terms of getting access into the data. Now we kind of need to think a little bit about behavior, the model. So in this case, I'm using Gemini three flashy open router. I talked about this a little bit earlier.
16:41I think the main thing that I found with open router is it's really nice to be able to just like have one interface that you can swap and test models between right as you're working on these things. And then, you know, with Gemini, Gemini three flash, just extremely, extremely fast, extremely, extremely cheap. Again, I think that a lot of the models that have came out more
17:05recently are more intelligent, but in general, like figuring out what a user's intent is and, you know, tying that into a database in a very narrow scope is not something you need, you know, best of breed for. So it's not super, super expensive to run these things kind of,
17:22you know, and see if they work. So we talked a little bit about the loop. I'm going to pull the, let me see if I can pull up this a little bit, our agentic loop here in the chat. I'm going to see if I can just actually find the code instead of pulling up the PR since we're just kind of on a, on the stream is a little bit challenging to kind of look at it. Data chat mini.
17:47Let's see here. Agentic loop. Here we go. Here's our loop. All right. This is much better. So here we can see our actual loop, right? Now, one thing I'll call out that is
18:11important here is, is we're not going to look too, too tightly at this code, but like the max iterations basically is just saying, Hey, we don't want to like run this thing forever. So I'm actually setting, I think my max iterations to 40 inside this code, right? And this, this lets me just make sure that I don't loop forever on making all of these tool calls, especially on
18:35more complex questions. It can be a little bit challenging. And so that's why, that's why that's in there in terms of looping. You know, I think there's been this notion of at least on like Twitter and a little bit on LinkedIn, we're like, Oh, we need loops, right? Like, yes, we've had loops for a long time. We, they're very, they're fairly easy to, you know, write with whatever
18:57coding language you want and expose that or make that a feature of your product or, you know, run it on top of an AI model. This is the way that I've been thinking about it. You can see how I'm defining things in here. Again, we linked, did we link to the repo yet, Jerel? Jerel, can you throw a repo link in the chat just so people can see it there and they can
19:18follow along? It might be a little easier for them to see there. So we're going to pull out of the agentic loop, but you can see it's like, it's a very simple while like this, this whole, this whole file is actually longer than it probably should be, but it's about, you know, I think a hundred lines for the loop. The, the, the thing to think about here is,
19:45where was I going with that? I try to keep these things as simple as possible. There's a whole bunch of things in here actually also to make the, to make the user experience a little bit more interactive and like stream that stream the text in. So there's a little bit more complexity to make a nicer user experience. But in general, you know, it's fairly, fairly simple. Um,
20:07let's look at our system prompt as well while we're here. Um, since we talked about it earlier, I think it's in here. System prompt. Yep. Great. Um, here we go.
20:21So you can see what we're writing in here. Let me close that so we get a little bit. Um, it doesn't wrap the way that I would like. Maybe I should have used something different. That's no for future me. Um, you can see it. We're kind of just listening. Hey, here's the context. We're in. Here's how we're doing this. Um, you know how we're how we're communicating with, uh, with our M. C. P. and running turns, right? Um,
20:45uh, you know what tools we have available, right? It pulls in that list. Um, it's telling it, hey, don't render html. This is actually really, really kind of important thing as we think about, like, making this easy for our users to understand and use, right? Is that, um, the reason I built the mbiz library was because you can get a really inconsistent experience across different L. L. M. S. In terms of how they visualize data. Um, you know, Claude will do it inline for you now. Uh, I don't know what Gemini does. I have no idea.
21:15I haven't used it enough. Um, you know, chat. You can do the same thing, you know, whether you're in codex or classic chat. Um, this just gives you a unified way to say, all right, well, regardless of what model I'm using under underneath, I have like this tool that's built here. Otherwise it will definitely write html. And then what I will say is that for like things around design sensibilities, you know, I talked earlier about, hey, like the models, models are pretty good at writing sequel, even at like the smaller end or the less less parameters.
21:43Um, actually doing visual design is still pretty hard for smaller models in my experience. And that's where we're having a model like, you know, the latest opus or Fable or Sonnet on the on the chat.
21:57Um, so, uh, I give it a few more, a few more, a few more points, right? Hey, like, go explore the schema. Like, don't guess. Um, sometimes if you don't give the right context, it will guess and hallucinate. Like, oh, like this data looks like this other data that's in my training set. So therefore, it's not going to work.
22:15Um, uh, you know, and then I, I love doing this, like establish grain results. You know, we do a few things to like that, that, um, that help us, um, help us set up the models. Right. There's a lot of, there's a lot of, you know, uh, there's a lot of, stuff that you can do.
22:38Um, again, this is mostly tuned on Gemini three flash, but in general I found that these work pretty well across all models. Um, especially because I would say Gemini three flash, if you classify it, you know, across the other models in terms of intelligence, it's, you know, in the middle at best, uh, not, not the smartest model. And so these, these models are great.
22:57Um, you know, telling it, read the room is super funny. You can tell this was like written by, by Opus for Gemini. Um, very funny. Um, but yeah, uh, you know, there's a few things in here. Uh, there's, there's a few things that we kind of recommend.
23:11Uh, you know, we put some notes here, Hey, like DuckDB, DuckDB and Postgres are different. Here's how they're different. Uh, here's some things we know, but we know about that you can use differently that it was running into on traps. So we just give those, give it very simple hints. So then when it's using this, we, it doesn't run into any of those things.
23:27You know, uh, we can save some turns, uh, in general and then how to display the data, right? Here's an example. Like I was saying earlier, here's what, like the Jason schema looks like for, um, brand is. And so it's a very, very simple way for it to explain and show information.
24:12Um, okay. So that's the system prompt. I'm spending a little more time here just because like the system prompt is really going to define like what the behavior is that really matters for your users. And so spending a lot of time tuning it and evaling it, you know, even if it's a vibe based eval, which means you're using the product, um, is important.
24:34All right, we're gonna go back to the slides. Um, we talked about the system prompt. How do we trust? Um, you know, again, this, this was, this was also baked into the, into the, um, into what we showed in the system prompt, but I'm just going to reemphasize it.
24:49You know, we build trust by showing, not telling, right? A lot of this stuff, a lot of the hard parts with using LLMs in complex workflows, you know, even things that are, um, in general, pretty rote, like data analysis. Um, we need to be able to see what is, what is doing. And like the beautiful thing about, for example, Excel and other spreadsheets is that once the data is input, all of the calculations on top of it very clearly flow through from there.
25:19And I think like that is an important thing that I'm always thinking about when I'm designing these, like, how do we make sure that our users trust this information so that they will continue using it? Right? The more they use it, the more our, our logs and traces are going to improve. The more we can run better evals against that data. We can build synthetic sets. We can run evals against all these things that we can only do the more users we have. And we start with trust.
25:41Um, and that's why I told it, you know, Hey, like do schema exploration, always do this, right? Um, obviously we have a UI. You guys saw the UI. We'll look more at that in a little bit. Um, and then, you know, we, we enforce, you know, read only. And then we only have a tool allow list, right? There's a bigger, a bigger set of, of MCP tools that are available in the MotherDuck MCP that were integrated onto on top of. We will only allow a subset of those tools, right? We don't want everything. We just want some of it.
26:07Um, and then everything is logged. Um, now what I will say in the one that is published here, there's actually logging is turned off. I'm not retaining any data. Ask whatever weird questions you want. Um, I will never see it ever. Um, but when you're building this for prod, there's a little switch kind of in the back end in this feature set that you will see that says, Hey, do you want to write this log to, to MotherDuck? You can turn that to yes. And then it will be able to, um, uh, give that data to you so that you can look at it and eval and all these, all these things that, that you really need to kind of affirm that this thing is working.
26:37Um, all right. Lastly, we can, we talked about charts a little bit. I linked to it earlier. I love, I love charts. Um, you know, history. I'm going to just show this quickly. I'm going to zoom out slightly. So on the left hand side, you can see here's all of my chats that I had. Again, this is all, um, stored locally here in my browser. I'm not writing it back.
26:57Um, uh, but I can jump into any of these conversations that I've had and kind of, you know, zoom back, back through them and see what's in here, which is really cool. Um, lots of, lots of fun questions. What data is in here? Um, what, what, what, which of these have, you know, negative margin, whatever. Right. We have all this in here. Um, really cool. We have the chat, uh, because I'm keeping it locally. It's also really fast, which is just a great experience. I kind of like that. Um, you know, really, really fun.
27:24Um, and then on the right hand side, we do have context. So in this case, I'm in this one. Uh, I can see that I built, uh, some context into my browser here that says, Hey, like, here's how we calculate gross sales for this data set. Here's how we, we calculate cogs. This is a different one than immediate data set. This is, um, uh, the Jacobs econ company. For those of you who clicked on the link, you can check it out. Um, uh, uh, let's see here. Um,
27:55yeah. So here you can see it, it built out its own, its own little context, which we can, um, we pull in there, but I am going to zoom back in. So we don't see that. Um, all right. So that's that part. Um, yeah. Context, right. We can teach it. We can teach you information. I see a comment here. I'm just going to pull up. Um, this is a great example of where we think about how I think about context. Uh, this question from Rafiq. Um, yeah, I got some time that air and relevant charts first. Totally. Yes.
28:21This is exactly the experience that you get. Um, and then once you, uh, once you refine it and say, all right, you figured out what the query is and you've got the thing that you like, then you can tell it to say, Hey, like save this context. So the next time, or if I ask you about another player, it will know, Oh, I see that if I ask about this type of a question, here's the, here's the joins to use, here's how to filter it. Um, and that way you, you can get that knowledge used, um, for next time. Right. Um, I think that's, that's, uh, uh, that's a, that's a good call out.
28:51Right. Like, um, these things are not going to come to you fully formed, right. As they're used, right. As the archeology occurs and we dig, we figure out what things are worth saving and what things are worth discarding. Um, so thank you. Thank you for looking at it in real time and giving the feedback. That's awesome. Uh, I'll hide that one. Let's keep it rolling here.
29:11Um, so yeah, exactly. It must learn as you learn. Right. Like the magic here is that we can put all of these things that we learn about our data into, uh, into the tools we're building. Right. Um, uh, this is reminding me, there's a really, uh, fun Marshall McLuhan quote about, you know, our, uh, our tools shaping us. Right. Um, it is, uh, I'm totally not doing it justice, but, um, Jerel can pull it up and find it and put it in the chat.
29:38But, um, uh, you know, we really want to improve. These things should improve over time. Right. The promise of AI is actually, uh, you know, from my perspective is that, uh, every interaction that we have with the tools we're building is an opportunity to improve them. Right. Um, I think that that is really cool to me.
30:00Um, okay. So now we build it. I, you know, we talked a lot about a lot of these details, um, you know, in terms of what it looks like to pull it all together. Um, I'm thinking from, for the sake of, for the sake of this, um, you know, we, we really talked about all the parts and how these, how these fit together. So we're going to skip that. Um, and then we're just going to jump into, um, let's see.
30:27Yeah, you can deploy. It's very simple. Um, this is what it looks like to deploy, deploy this. You need a MotherDuck key and you need a, um, uh, you need an open router key. Uh, yeah. And let's see. That's it. Um, I want to show one more thing here since we do have some time. Um, and then we can take some questions about specifics or general. Um, let me see if I can pull this up. I'm going to stop sharing for a minute.
30:57Um, pull this up. Let me just go to, that's the wrong one. Uh, not that, uh, uh, quack bot. So inside of open a new window, let me throw this in here. Um, I know a lot of you probably use slack and I use slack and I find it quite useful.
31:27And so I am going to, Oh, share an example. Also in the same repo that we linked for labs using all of these same primitives, we can reuse these for a slack bot, which is new since I, um, new since I, uh, kind of built the original, uh, um, demo. Let's see. Is this the right one? That looks right. Okay. Um, let me see if I can kind of make this bigger. Okay, perfect.
31:57All right. So just like we saw this, we can do the same, you know, um, okay, don't do that. Uh, who made the most, uh, three pointers in NBA playoffs, 2026, uh, make a line, make a bar chart with top 10. Um, and so what this will let you do is, you know, take this and put it into a, um, okay, come on, wake up.
32:26There we go. Um, put it into, put it into, in this case modal, you can also use fly. You can use lots of different ways to, to, um, persist this. Um, but this one is actually using Kimmy on modal, uh, and it is doing a little bit of research, figuring out what's going on. And then it should, uh, should give us a bar chart. Hopefully we'll see. We'll see how it works. Um, but my point is, once you have this first, uh, thing built out, it's very easy to then, uh, extend this into other modalities, right?
32:55Slack teams, uh, whatever the other chat apps you work, your discord, all of these things can bear are very easy to kind of interact with in this way. And I think like, that's the key thing that, that I'm really getting to, uh, around a lot of this, uh, is that we can extend all of these things, uh, into, um, into all the different ways.
33:17I don't think this is right. 61. We'll find out. Um, okay, great. And it gave us a chart. Let's see what the chart looks like. Perfect. Okay, great. Um, let's just see, uh, double check this. Um, this is actually a really good example of where I think maybe the context is not right, but we'll find out. Um, it looks like it's the same order, but they're different numbers than we had before.
33:45Maybe we had a joint issue previously. I don't know. Um, uh, check, check the number of periods and how many games played anyway. So we can kind of just like, you know, keep having these conversations, uh, with our bot as it goes. Um, and it will, it will spin this up. What's really cool. This is all serverless too. So you can scale out to as many users as you want and you can, uh, when it's not running, it doesn't do anything, which is pretty cool.
34:12Um, okay. So that's kind of the data chat data chat overview. Um, it's very, very easy to get your quack bot rolling, um, with your data. Let's see. Uh, cool. Hey, it gives us a table. It renders the markdown now in, uh, in slack. That's new ish.
34:33That's so nice. Jerel, did you know it could do that? I didn't know it could do that. Um, all right. Very cool. Uh, distinct games. Yep. Okay. Great. Great. Great. This makes sense. Um, nice work. Uh, who led the lead or who led in steals and blocks?
34:52Just top one for both. I think it's probably Victor Mignogna, but who knows? Um, all right, I'll stop sharing. Um, it'll tell me and it will tell me and none of you will know the answer. Um, no, I'll tell you. Uh, this is really great. So this is where this, this is kind of what I'm thinking about. Um, uh, so, uh, let's take, let's go to questions.
35:16Um, happy to take them. Let's see our leaders, by the way, and steals were case and Wallace and Victor Mignogna. Okay, great. That makes sense. Got a question here from Patrick. Let's see. In this chat example, can a user add a file and interact with the MD data? Okay, so I'm going to ask that question in two parts, uh, or answer that question in two parts. Um, uh, the first part is, can a user add data with the file? Not with how I implemented it.
35:43Could you do that very easily? Yes. Could it read data from an S3 file? Yes. Could they upload a CSV? No. Um, and that's not because it's not possible. It's just because, uh, M. C. P. does not have an interface for loading files.
35:58So you'd have to build one that didn't use the M. C. P. Right. Um, let's see. Uh, let's see where did the for the second part you can, you can interact with any mother databases you want. You can even tell it, hey, attaches other database.
36:17Um, uh, you know that maybe I, that is not attached yet. It can manage its own workspace. It can do all those things if you wanted to. Um, so those are all possible. Um, explain the setup. Let me throw this one in here. Great question from Lucas here.
36:36Explain. So you mentioned MotherDuck key plus something else. I'm just gonna pull this up in in my browser. You close this out. Okay. What is happening with my window? All right, there we go. Get hub dot com slash MotherDuck db slash labs. And let me just share this just quickly. If I can find the button.
37:01Every app is slightly different, of course. Okay, so I'm gonna go into data chat mini. And if we go to our dot envy dot example, we'll see that it is, um, MotherDuck and open router API key. Um.
37:20Yeah, uh, just those two things. And away you go. Um. Yeah, if you want to, you can use a different model. You can use a different provider. You can set these things by unpinning them. Um. So, yeah. Uh.
37:44Yeah, that's how that part works. Um. Very, very, very simple. I think if I go back to my, you know, again, this is built on Vercel, so you, um, it will be more complex to deploy somewhere else. But here's kind of the dependencies we're building on.
38:05Um, not too many in the scheme of things. Although, well, who knows? Who knows how many are downstream of here? Don't look at the don't look at the package lock file.
38:15Um, let's just see. Oh, that's not horrible. Who knows how many factors are in here? Quite a few. Okay, maybe it is bad. Um, obviously, you can simplify that as you need to stop sharing for a minute. Um. But, yeah, those two keys, those two keys, and then you run the Vercel CLI, and it will work for you. Um.
38:39In this case, just when you are using MotherDuck, the easiest way to do this is to, um. Uh. I don't know that, um.
38:55Anyways, you should. Oh, from a mother perspective, you want to run that in a service account. And so you if you were going to make this available, wasn't kind of a semi unauthenticated endpoint like I did. You want that service account to kind of be isolated to only have access to the data you want to give it to, which totally makes sense. Um.
39:15Anyways, let's go into this one here from hitting. How did the slackbox set up with Kimmy? Did not get how that part of the integration works. Great. Um. So in that case, what we're doing is instead of using Next.js and Vercel is we you build a slack app. And so you have to add a slack app to your slack instance.
39:34And basically, what that does is it puts a, um, it makes an HTTP endpoint available that you can send and receive messages to and from. And so what we do is then we use something like modal or fly dot IO to run another to run our server. Um, and that server just simply facilitates passing messages from slack, right? It receives a message from slack and then it will pass it into that server.
39:59And then get the message back from the LLM and pass it to Slack, right? And so that is the architecture there. It's not that complicated. Everyone inside of MotherDuck has access to QuackBot now. And there's a way – so in my case for QuackBot, I did authentication as bound to the bot, right? So QuackBot authenticates as QuackBot.
40:21For other agentic use cases, what you probably actually want to do is do a pass-through authentication so that you tie in Slack and OAuth together so that when I ask a question to QuackBot, it authenticates as me and asks a question as me, right? Or to a smaller part of me. Henning, I hope that is close enough for what you're getting at. Jerel also linked to the projects in QuackBot, which I will just show quickly.
40:45It's all in this MotherDuckDB slash labs. The way that I recommend thinking about and reasoning about these is they're good reference implementations, but how you want it to work on your side is up to you. They're very, very fast to get working with AI of your choice
41:09and say, hey, here's a reference implementation that ties things into Slack. Can you help me do this too? And that's been a very powerful pattern. This QuackBot project that Jerel linked, thank you, Jerel, for doing that, is used by some of our customers. So that's where it kind of started.
41:32That's where it linked in here. And I'm just going to put in chat, Henning, a follow-up with you. Please link the tools here you mentioned. Vercel.com for hosting.
41:46MotherDuck for DB, MCP, OpenRouter. com for AI models. Oh, that looked horrible in the chat. Well, sorry. I did do line returns between each row. Sorry about that. Anyways, by the way, there was a question earlier about steals.
42:11Alex Caruso ranked 13th and Dort ranked 69th. Only had seven steals in 15 games. That's pretty surprising. Maybe they were officiating him differently. Too many fouls. Anyways, that's what we have for today. I'm happy to hang on for a little bit here, take more questions, see where everyone wants to go with this.
42:34I think the idea here is we want this to be a jumping-off point for what you can build inside of your own company. Let's see here. Got some good questions here. Let's see. Can you detail in the memory component a bit more? Is it limited to a specific thread slash conversation? Okay, great question. So in the case of how it's built here,
42:56it's only local to the user. In the time since I've built this demo, MotherDuck has released something called Guides, which is a set of MCP tools to allow shared context. That's the way that I recommend you use this in the future. You obviously could also connect into any other MCP
43:20or build your own version of it, but I started with just local for the user, just to kind of keep this simple. If I want to make this a demo that I can share and have other people use, what I don't want to do is be accountable for your data, and so basically everything stays local in this demo kind of as a feature of the demo. I don't want your logs. I don't want your traces.
43:44I don't want to know you logged in. All I know is the kind of observability stats that comes along with Vercel. And so, yes, it is limited, but that's not because it's not possible. That's because I don't want to be holding your data, right? But it's a fair question. What can I actually connect this to? DuckDB Parquet? Absolutely.
44:07So the MCP could definitely be swapped out with the MotherDuck MCP or, sorry, with the DuckDB MCP, or you could use any MCP that you want, right? I'm sure a lot of other databases have MCPs, and it would be fairly easy to use the MCP that you want. We published the DuckDB open source MCP that you could use to plug into this.
44:28Again, I'm sure there's others that would work great with this. You know, in general, what I like about using MotherDuck for this is that each user can get their own database, and so that as you scale up your service, it becomes very easy to keep it scaled. And so if I have one user writing really bad queries with their agents,
44:49they don't block other users, for example. That's kind of a feature of our architecture that is helpful, especially as people kind of just start, you know, doing wild stuff with MCP. Let's see. Next one here. What's the best MotherDuck pattern for ingesting externally generated CSV, JSON, L, Parquet while preserving governance and schema accessibility for agents?
45:13This is a good question. The best pattern. Okay, so what I generally see people do is they'll put those files into S3, and then you can either make, like, a tool available that lets the agent run, like, S3 list and query them directly with MotherDuck
45:33or load them into a database that is, you know, keeps references to, like, you know, the metadata where this information was sourced from. There is also a OpenLineage plugin for DuckDB that I've seen people use. I really think it depends on the exact use case,
45:54but in general, I would do one of those two. I would load it into MotherDuck with an associated metadata table that says, hey, like, these rows came from this source. That's fairly common. Or I would not even keep it in MotherDuck at all and just keep it as, like, a temporary session
46:16so when the agent is connected that it just can pull the data that it needs when it needs it. But, again, for repeatability, I don't know what your use case is, so, like, if you want to be able to, like, share that with someone else, you just need to make sure that it would keep all of those queries, like, in a view
46:40so that when the view is shared, that, like, the view contains the provenance. Let's see. Question here. If I ask a question from a chat interface, will the MCP look at both guides and semantic layer? How does the MCP know how to handle guides and the semantic layer? This is a great question. So in MotherDuck, we think about guides as the overarching component that handles both your kind of business context
47:04and your information about how the data is connected, joins, and what your metric definitions are. We've actually done quite a bit of writing about this. Jerel, can you pull the blog that Alex wrote, the most recent one, about semantic layers and drop it in the chat here? What we've discovered is that when you start introducing
47:26non-SQL into your database agent, that it starts getting a lot slower and more expensive and less accurate, which is a little bit counterintuitive. And the reason we found that in the evals is that there's basically 50-plus years of training on how to write SQL in the corpus,
47:48and I think there's a lot of RL happening in the labs, too, because it's very useful for the agents to write really good SQL. And when you start doing something that looks kind of like SQL but isn't exactly SQL, like semantic layer languages, let's say like DAX or MDX on the Microsoft side or, you know, whatever they use in other tools. Names are escaping me at the moment. Need more coffee, apparently.
48:11They just start getting, like, really hung up on how to do it the right way, and you lose flexibility, which is, I think, the goal to some extent, although what I would say, I would almost describe a semantic layer is an extremely overfit context layer, right?
48:31So if we just overfit the crap out of our context, we end up with a semantic layer. Yeah. So I think that's how I think about this at the moment. Our research has shown that. I think what we're seeing is all the BI tools
48:53are starting to add their own context layer, semantic layer. They sometimes call it confusing things. Snowflake, for example, has a semantic something, but they call it. . . The definition of. . . They have something called semantic views, which aren't exactly a semantic layer, and then they talk about context layer and semantic layer interchangeably in their marketing,
49:15which is very fun and annoys me, but that's, you know, that's fine. One more question. Do you confirm this is just an interface? We control all the work through MotherDuck MCP, so we can replicate the question answer in VS Code Codium and just attach MotherDuck MCP? Yes, absolutely. This is just an interface. Thank you, Lucas, for the comment. Like, I'm not trying to tell you this is the exact pathway to do it. What I want to do is give you a pattern that I know works, right? Actually, one of the most powerful things that we use internally in MotherDuck
49:39is our development team built something we call SuperDuck, which looks a lot like what I showed you with QuackBot and has access to a bunch of different parts of our stack and can impersonate the user. And so what that means is we use it all the time for all sorts of tasks in the company. It might be asking it, hey, like, what was the reason for the spike in signups yesterday?
50:03And it might be, you know, hey, like, why are we seeing slow response times from the MCP right now or something like that, right? Those are all things that are possible kind of in this single interface if you think through how to tie the tools together. But it's just, you know, it's just chat. You know, we all enjoy and love chat.
50:23It's super powerful, but especially with the right tools put together. Okay, we shared a bunch of links. I really appreciate everybody joining us. I don't see any more questions to answer, so we're going to wrap it up now. You know where to find us? Find us on motherduck.com or LinkedIn or X. You can always find me on those platforms. I am at MattsonJ on Twitter.
50:47You can find my latest musings and things I'm talking about and harass me about what I'm writing about and how I think about problems. Really appreciate everybody today and looking forward to seeing where this goes in the future. All right, we're wrapping up.