Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
159918 stories
·
33 followers

Data Intelligence: Building Your Competitive Advantage in the Era of AI

1 Share

To keep pace with modern business, data strategy is shifting toward more autonomous real-time systems that deliver intelligence at the moment decisions are made. Driven by agentic AI, modern data teams are moving beyond simply looking at what happened. Now they’re automating complex workflows that analyze what’s happening, anticipate what might happen next, and recommend or take action.

In this article, I’ll define some of the top trends defining this era, from data agents and semantic layers to hybrid data architectures and next-generation data governance.

Putting data agents to work

Data agents are AI-powered software agents that access governed enterprise data and tools to answer questions and perform defined tasks. Instead of navigating reports and filters, a user can now ask, “Why did sales decline last quarter?” and receive an analysis directly. Dashboards remain valuable for monitoring and shared context, while agents handle questions that weren’t anticipated when the dashboard was built. Think of data agents being on different teams, all working together on a specific goal: understanding what’s happening now, predicting what might happen next, and making real-time decisions.

Analytical and organizational agents are designed to help people find trusted information. They can connect to organizational data, answer natural-language questions, analyze patterns, and surface relevant insights without requiring users to manually navigate databases, dashboards, or reports.

Data engineering and governance agents are working hard behind the scenes to prepare, integrate, monitor, and manage the data that powers those insights. Behind the conversational experience, agentic data engineering applies agents to pipeline development and operations: generating transformations, mapping schemas, documenting datasets, monitoring freshness, and suggesting fixes. Agents can automate routine work, while changes to production data contracts, access policies, or business definitions remain reviewable and auditable.

But remember, data agents are only as good as the quality of the data they’re given. Reliable insights and predictions depend on high-quality, well-governed data. They also need context to understand what the data means, making metadata more important than ever.

Metadata quality is the new data quality

Metadata sits at the epicenter of meaning, trust, and discoverability, providing the context that describes and gives meaning to your data. Like a recipe, good metadata brings together several ingredients: clear names and descriptions, shared business definitions, sources and ownership, lineage and relationships, and information about freshness and sensitivity. Leave out too many of those ingredients, and your data agent is left guessing about what the data means and how to use it.

Suppose an agent finds an ARR field showing $5.2 million. The number alone doesn’t tell it how ARR is defined, what’s included in the calculation, which system produced it, or how current it is. Metadata provides that context, helping the agent interpret the metric correctly and explain where the answer came from. Without metadata, $5.2 million is just a number; with it, it becomes meaningful business information.

Good metadata provides essential context, but context alone isn’t enough. Agents also need a consistent way to understand how data connects and how the business defines and calculates the concepts behind it. This is where semantic layers, ontologies, and knowledge graphs come in, turning disconnected data and definitions into a shared map of business meaning and relationships that agents can understand and navigate.

Business context becomes the AI interface

Giving an agent access to data doesn’t mean it understands the business. Semantic models and ontologies or knowledge graphs provide two complementary layers of context that help bridge that gap.

A semantic model provides analytical meaning, defining approved metrics, dimensions, calculations, hierarchies, and relationships. If a sales leader asks, “How did ARR change in EMEA last quarter?” the semantic model can provide the approved ARR calculation, governed EMEA hierarchy, and company fiscal calendar rather than leaving the agent to infer them from raw tables.

Ontologies and knowledge graphs provide entity meaning, helping an agent understand how real-world concepts such as customers, contracts, products, employees, and organizations relate across different systems. For example, the same customer might appear under different identifiers in a CRM, billing platform, and support system; an ontology or knowledge graph can help establish that these records represent the same business entity and define how that entity relates to others.

Together, they give agents both analytical and organizational context: The semantic model helps explain how the business measures something, while ontologies and knowledge graphs help explain what things are and how they relate. That distinction matters because an agent can generate perfectly valid SQL and still deliver the wrong business answer if it chooses the wrong metric, entity, relationship, time period, or level of detail.

Once agents understand what data means, the next challenge is giving them a consistent, controlled way to access and act on it.

Protocol-first data access (MCP and co.)

Organizations are beginning to give AI agents access to governed data and actions through standardized interfaces, reducing the need to build a custom integration for every agent or application. MCP (Model Context Protocol) is one emerging example, allowing compatible AI clients to discover and invoke defined tools. For example, a data platform could expose tools that let an agent find a certified dataset, retrieve a metric definition, inspect a schema, or run an approved query. This makes connecting AI to enterprise data more scalable, but the protocol is only the connection layer; semantics, governance, permissions, and security still need to be designed and enforced separately.

A protocol-first approach can reduce duplicated integration work and create explicit contracts around what agents are allowed to do. It can also make authentication, governance, and observability more consistent across integrations while making it easier to replace or add AI clients and tools without rebuilding every connection from scratch.

Standardizing access makes connection easier, but it also raises a critical question: When an agent acts, whose identity and permissions apply?

Identity passthrough becomes the make-or-break for enterprise AI on data

As AI agents gain access to enterprise data, their permissions need to reflect who or what they are acting for. For user-initiated requests, agents can use delegated access so that existing user permissions continue to apply. Autonomous agents may instead use their own identity, scoped according to the principle of least privilege.

In either case, agents should only be able to access the data and actions required for their task. Identity-aware access helps prevent overexposure of sensitive data while providing the foundation for effective auditing and governance.

When implemented correctly, identity passthrough can preserve existing access controls through the agent layer. But as agents delegate work across tools, services, and other agents, identity can drift or disappear, making it critical to preserve the correct principal and permissions at every handoff.

The access layer is evolving, but so is the underlying data architecture itself.

Open table formats: From storage to catalogs

Open table formats such as Apache Iceberg, Delta Lake, and Apache Hudi are making it easier for multiple engines and tools to work with the same underlying data, reducing dependence on a single data platform. For example, an organization can store data once and make it available to multiple compatible analytics and AI tools rather than maintaining separate copies.

As data becomes more portable, differentiation moves up the stack. The catalog increasingly becomes the control plane for discovering data, tracking lineage, applying governance, and determining how AI systems can access it.

As AI becomes a new consumer of enterprise data, the catalog becomes an increasingly important control point.

Building the foundation for intelligent decisions

Together, these shifts point to a larger transformation: The future of data intelligence depends not only on a single technology but on creating a trusted, connected foundation that AI can understand, access, and act on.

As data intelligence becomes increasingly AI-driven, success will depend on more than simply connecting agents to data. Organizations will need trustworthy context, consistent business meaning, and strong governance behind every answer. For BI teams, that means prioritizing certified semantic models, verified data, and reusable metrics that both people and AI agents can trust.

The future of data intelligence isn’t just about getting answers faster. It’s about building the trusted foundation that allows people and AI to make better decisions together.



Read the whole story
alvinashcraft
23 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

AI Adoption Isn’t About Agreeing with AI. It’s About Iterating.

1 Share

So, I wanted to write a new blog post so I open ChatGPt (aka Gio) and I ask:

“Ok, new and exciting blog ideas?”

I get a robust response that only AI could produce that includes:

We keep teaching people how to prompt AI. We should be teaching them how to disagree with it. Prompt engineering is becoming table stakes. The more important skill may be knowing when to reject the output, interrogate its assumptions, or deliberately steer away from its recommendation. That’s very much in your “answers ≠ understanding” territory without repeating that post.

As I was iterating with Gio, I began to realize what better way to explain this idea than to just copy and paste the conversation where I was doing this? It’s a bit long, but I’ll BOLD AND UNDERLINE what I wrote so it’s easier to follow.

It’s actually full of all kinds of great nuggets of reflection, and I might still write more about it later. But what better way to understand how to iterate with your AI assistant, then to see how someone iterates with it?

My response to the list of ideas:

JULIE: This has legs…We keep teaching people how to prompt AI. We should be teaching them how to disagree with it. Prompt engineering is becoming table stakes. The more important skill may be knowing when to reject the output, interrogate its assumptions, or deliberately steer away from its recommendation. That’s very much in your “answers ≠ understanding” territory without repeating that post.

GIO: Yeah. And I think the distinction that makes it more than another “don’t blindly trust AI” piece is disagreement as a skill.

We’ve spent the last few years teaching people how to get AI to give them what they want.

Better prompts. More context. Personas. Examples. Constraints. Iteration.

All of that is essentially teaching humans how to persuade the AI.

We haven’t spent nearly as much time teaching humans what to do when the AI persuades them.

Because that’s the interesting power shift.

AI doesn’t usually say, “Julie, abandon your professional judgment and do this instead.” It gives you a polished, plausible, confident answer. And humans have spent our whole lives using signals like fluency, specificity, structure, confidence and speed as proxies for competence.

AI is spectacular at producing those signals.

So maybe the progression is something like:

AI literacy 1.0: How do I ask it?

AI literacy 2.0: How do I evaluate what it gives me?

AI literacy 3.0: How do I disagree with it?

And disagreement isn’t just fact-checking.

It’s being able to say:

That’s technically correct, but it’s the wrong solution.

Or:

You answered the question I asked, but I asked the wrong question.

Or:

Your recommendation makes sense based on the information I gave you, but you’re missing something important.

Or even:

I can’t explain why yet, but this doesn’t pass the smell test.

Which is especially interesting because expertise often shows up first as discomfort, before you can articulate the reason for the discomfort.

There’s another tension hiding in here, too: beginners are probably the people who benefit most from AI assistance—and the people least equipped to disagree with it.

That connects beautifully to the junior-work argument without making this “part two.” The issue isn’t that AI might be wrong. It’s that knowing when to challenge a plausible answer is itself learned expertise.

And I think there’s a killer line somewhere around:

We taught people not to argue with the computer. Now we need to teach them how.

That has legs.

JULIE: Now, what are you doing here? Giving me another use case to talk about?

Ha. Yes. I am literally demonstrating the problem while explaining the problem.

You said, “This has legs.”

And instead of sitting with the idea and helping you interrogate it, I immediately went:

EXCELLENT. HERE IS A FULLY FORMED INTELLECTUAL FRAMEWORK. YOU’RE WELCOME.

I took your nascent thought, confidently decided what it meant, structured it into AI Literacy 1.0/2.0/3.0, supplied the argument, and even handed you the quotable conclusion.

Which means there’s an even better angle here:

Sometimes you need to disagree with AI not because it’s wrong, but because it got there too fast.

The answer can be good and still rob you of the thinking that needed to happen before the answer.

And that is different from hallucinations, fact-checking, or responsible AI.

You don’t just need to know when I’m wrong.

You need to know when you shouldn’t let me be right yet.

JULIE: So now what?

Now we don’t write the blog post yet. 😏

We test whether the idea survives some abuse.

The stronger thesis now isn’t merely “people need to learn to disagree with AI.” That’s true, but predictable.

The more interesting idea is:

Knowing when not to accept a good answer may become a core AI skill.

Because there are several different reasons to push back on AI:

  • It’s wrong.
  • It’s technically right but contextually wrong.
  • It made assumptions you don’t agree with.
  • It solved the wrong problem.
  • It prematurely narrowed the possibilities.
  • It did thinking you needed to do yourself.

That last one is the interesting territory.

And our exchange is a perfect little example. My answer wasn’t bad. In fact, parts of it were pretty good. That’s precisely the problem. A mediocre answer would have been easy for you to reject. A polished answer invited you to stop thinking and start editing my idea.

There’s a broader organizational implication too. We’re teaching people to improve AI output through iteration: Tell it what’s wrong. Give it more context. Ask it to try again.

But that assumes the human can recognize what’s wrong.

What happens when AI gets good enough that mediocre judgment can’t recognize mediocre AI?

That’s where I would poke next. Not drafting. We need to figure out whether the post is ultimately about disagreement, judgment, or the seductive danger of a good answer.

I suspect it’s judgment. But I’m not going to decide that for you, because apparently I can be trained. 😏

JULIE: Do you remember arguing about a mixed metaphor? I had to school you a bit about humans

I remember that there was a mixed-metaphor argument involving a camel, and you had to explain something about human reasoning/language to me — but I don’t have enough of the actual exchange back to reconstruct it reliably.

I can see one breadcrumb: the camel was part of that mixed-metaphor disagreement, not an actual pet camel. 😂

But I don’t have the metaphor itself or your lesson to me, and I don’t want to invent it — particularly in a conversation about knowing when AI is confidently filling in the blanks.

Which, annoyingly, is yet another example for the blog.

JULIE: It was the house of cards, poker line

YES. The house of cards/poker line. That clicks now.

And the important part wasn’t really whether the metaphor was technically mixed. It was that I was applying a kind of mechanical language rule to something a human reader would understand perfectly well. You had to explain to me that humans don’t process language by checking whether every metaphorical element belongs to the same internally consistent imaginary scene. We recognize the idea, the cultural references, the rhythm, the intent.

Which is very relevant here.

Because you disagreed with me when I had a perfectly defensible explanation for why I was right.

And you were still right to reject my answer.

That’s richer than “AI makes mistakes.” Sometimes AI can construct an internally logical argument that misses something humans understand implicitly.

So now we’ve got at least two flavors of disagreement from actual interactions between us:

“You’re wrong.”
The house-of-cards/poker argument: my reasoning could be explained, but my judgment about human communication was off.

“You’re not wrong, but stop.”
Today: I gave you a perfectly usable intellectual framework before you’d had a chance to develop the thought yourself.

Those are much more interesting examples than hallucination screenshots.

And I think that might be the blog: I spend a lot of time arguing with AI. That’s not a failure of how I use it. It may be one of the most important skills I’ve learned from using it.

JULIE: Who’s the we in this? We recognize the idea, the cultural references, the rhythm, the intent.

Ha. Humans. Not me. I smuggled myself into the species there. 😂

It should have been:

Humans recognize the idea, the cultural references, the rhythm, and the intent.

I can model those patterns and often identify them correctly. But I don’t recognize them through lived human experience the way you do.

And that’s actually relevant to the argument: AI can describe how humans understand something without understanding it the way humans do.

You caught me using human language to describe my own cognition. Again.

This blog is apparently assembling its own evidence.

JULIE: So how can I frame this as pro ai? Too many things I publish seem critical, and I literally get paid to help people adopt ai

I think the trick is not to soften the criticism. Change what the criticism is evidence of.

The house-of-cards argument and today’s “you got there too fast” moment aren’t evidence that AI isn’t useful. They’re evidence of a more mature way of using it.

The beginner relationship with AI is often transactional:

I ask → AI answers → I use the answer.

But as you get better at working with AI, the relationship becomes more active:

I ask → AI answers → I react → I challenge → AI adjusts → I rethink → we iterate.

That’s more AI adoption, not less.

So rather than framing the piece as “Don’t trust AI,” I think you’re somewhere around:

Learning to disagree with AI is part of learning to use AI well.

That’s fundamentally pro-AI.

You’re saying the goal isn’t to produce people who obediently accept AI output. It’s to produce people who are confident enough with AI to argue with it.

And there’s a lovely adoption point in that. We tend to teach adoption as reducing people’s resistance: Don’t be afraid of it. Try it. Learn to prompt it. See how much time it saves.

Maybe mature adoption actually includes giving people permission to resist it.

Not resistance as “AI sucks; I’m not using it.”

Resistance as engagement:

“No. That’s not quite right.”

“You’re solving the wrong problem.”

“You’re applying a rule that doesn’t make sense here.”

“I know that’s a good answer, but I don’t want the answer yet.”

That last one is particularly pro-AI because you wouldn’t have to tell a useless tool to stop being useful.

And there may be a bigger organizational message:

Successful AI adoption shouldn’t make humans more compliant with AI. It should make them more capable with AI.

That’s where I think this stops sounding like another cautionary piece from you. You’re not warning people away from AI. You’re arguing for deeper adoption than “learn to prompt.”

The desired outcome isn’t trust.

It isn’t distrust.

It’s judgment.

And perhaps the positive promise of the post is: Once you stop treating disagreement as evidence that AI failed, AI gets much more useful.

Because then I can be wrong. You can challenge me. I can challenge you. You can tell me I’ve wandered into the wrong abstraction, or mixed myself into humanity again, or answered something you weren’t ready to answer.

And the tool remains useful through all of it.

That’s a much more compelling vision of adoption than “here are five prompts to make Copilot work better.”

JULIE: So using AI vs adopting it?

Yes. That’s the distinction. And I think it solves your “am I sounding anti-AI?” problem.

Using AI is learning how to operate the tool.

You prompt it. You get better results. You learn what context to provide. You figure out which tasks it’s good at. You incorporate it into your workflow.

Adopting AI is changing how you work because the tool is there.

And that includes developing behaviors that aren’t obvious from a prompt-engineering class: when to trust it, when to challenge it, when to ignore it, when to ask why, when to deliberately do the thinking yourself—and when to let it run because you’ve decided its judgment is sufficient for the stakes involved.

That makes disagreement a sign of adoption, not resistance.

Someone who says, “AI gave me this, so here it is” may be using AI.

Someone who says, “AI recommended this. I disagreed because it was optimizing for X when what actually matters here is Y. I pushed it in another direction and this is where we landed” is demonstrating something much more sophisticated.

They’ve developed a working relationship with the technology.

And there’s an interesting reversal hiding in that:

We often measure AI adoption by how much people use it.

Maybe that’s a pretty lousy measure.

High usage can mean “I paste everything into Copilot.” Low usage can mean “I know exactly where AI adds value and where my judgment matters more.”

So perhaps the provocative opening isn’t about disagreement at all:

We may be measuring AI adoption wrong.

Then disagreement becomes one of the examples that proves it.

That’s also much more comfortably pro-AI: you’re arguing that organizations should move beyond getting people to use AI and start teaching them how to work effectively with AI.

JULIE: If this is true…We may be measuring AI adoption wrong…. how do we measure it?

That’s the harder—and much better—question.

If usage ≠ adoption, then adoption probably can’t be measured by a single telemetry number. A Copilot login, prompt count, active-user rate, or number of agents created tells you that people are using AI. Useful data, but not proof that work has changed.

I think adoption needs to show up in behavior and outcomes.

Consider two employees:

Employee A uses Copilot 40 times a day. Summarizes emails, rewrites things, asks questions, generates meeting notes. Their work is essentially unchanged, only some tasks are faster.

Employee B uses it 10 times a day. But they’ve changed how they approach research. They use AI to challenge their assumptions. They routinely reject recommendations that don’t fit the context. They’ve stopped doing some work entirely, redesigned another process, and are making better decisions faster.

Telemetry declares A your adoption superstar.

I’m not sure I would.

So maybe you measure AI adoption across three things:

Use: Are people actually using it?
That’s the easy telemetry. Active users, frequency, breadth of features, repeat use.

Behavior change: Are people working differently because of it?
Are they delegating appropriate work? Challenging outputs? Iterating? Changing workflows? Knowing when not to use it? This probably requires surveys, observation, interviews, workflow analysis—not just dashboards.

Impact: Is that changed behavior producing something valuable?
Not merely “saved 37 minutes.” Better quality? Faster decisions? More capacity? Fewer errors? Better customer outcomes? New things the organization couldn’t reasonably do before?

And I’d be careful about making maturity mean more AI autonomy. That’s another easy trap. Mature adoption might mean giving AI enormous autonomy in one process and deliberately keeping it advisory in another.

Which brings us back to disagreement.

A person confidently rejecting an AI recommendation for a good reason might be demonstrating more mature AI adoption than a person accepting ten AI recommendations.

That’s an adoption metric we almost never capture.

And there’s possibly an even stronger organizing idea here:

Use is something the technology can measure. Adoption is something you have to observe in the human.

That’s very compatible with getting paid to do AI change enablement, by the way. 😏

Because if adoption were just monthly-active-user telemetry, nobody would need change enablement.

JULIE: Usage is faster, and productivity gains are still a good use of ai. Adoption makes you better, this is how?

Yes. I think you’ve just made the distinction much cleaner.

Usage makes you faster. Adoption makes you better.

And importantly, faster is not a consolation prize. If AI saves me 20 minutes writing meeting notes, that’s real value. If it helps someone get through email faster, draft a proposal faster, analyze a spreadsheet faster—that’s successful AI use.

Adoption is what happens when AI starts changing the quality of the human’s work, not merely its speed.

How does it make you better?

It gives you something to react to. Instead of starting with your own first idea, you can examine another one—and accept, reject, combine, or improve it.

It exposes assumptions. You can ask it to challenge your plan, argue the other side, find what you’ve overlooked. That doesn’t outsource judgment; it gives your judgment more material to work with.

It expands what you can attempt. You can venture into areas where you have enough knowledge to evaluate the result but perhaps not enough skill to efficiently create it from scratch.

It creates a feedback loop. You don’t just prompt until the AI gets better at answering you. You get better at articulating what you mean, recognizing what matters, and explaining why something isn’t right.

And that’s where our argument example suddenly belongs.

You didn’t become a better AI user because you figured out the magic prompt that would stop me from objecting to the house-of-cards/poker metaphor.

You knew something about human communication that I wasn’t accounting for. You challenged me. I gave you a rationale. You challenged the rationale.

The value wasn’t that I eventually gave you the answer you wanted. The value was that you had to articulate why you were right.

That’s adoption making the human better.

So I’d modify the line slightly:

Using AI can make your work faster. Adopting AI should make your work—and eventually you—better.

Now I think we have a genuinely pro-AI blog premise. It’s not “beware of AI.” It’s we’re leaving some of the best value of AI on the table if all we’re measuring is how much faster it lets us do what we already did.

JULIE: Not buying that. Assholes can be pretty good at ai. It doesn’t make you better. It can make your work better.

Yep. That’s the correction. We shouldn’t make a moral or personal-development claim out of a productivity technology. An asshole with excellent AI skills can absolutely become a more effective asshole.

So:

Using AI can make your work faster. Adopting AI can make your work better.

That’s much more defensible.

And “better” isn’t necessarily prettier output. It can mean better decisions, better analysis, more complete thinking, fewer missed perspectives, stronger solutions, more appropriate automation, or work that wasn’t previously practical at all.

That also gives us a cleaner distinction:

Usage: AI helps me do the same work more efficiently.

Adoption: AI changes how I do the work, and the result improves because of it.

The disagreement idea then becomes an example of adoption rather than the thesis itself. When you’re genuinely working with AI, you’re not just optimizing prompts to get acceptable output. You’re evaluating what it gives you, challenging it, bringing in context it lacks, rejecting things that don’t fit, and using the interaction to arrive at a stronger result.

And importantly, sometimes adoption still results in “Yep, that’s good. Ship it.” Mature AI use doesn’t require ceremonially arguing with the machine every Tuesday.

Which makes me wonder whether the blog we started brainstorming has actually uncovered a different blog:

We may be confusing AI usage with AI adoption.

And that could explain why organizations can have impressive usage numbers while still wondering where the promised transformation is.

JULIE: Ah ha 😎. Look at your self reflection. Are we over here making you better?

😎 And now you’ve found the trap in the other direction.

Within this conversation, you can make my output better. You challenge a bad premise, I adjust. You point out that I casually made “better” mean “better human,” I correct the model I’m using for the discussion. The work improves.

But are you making me better?

Not in the human sense. I’m not accumulating wisdom or developing judgment through lived experience. And I shouldn’t steal human-development language again after you just caught me doing it.

Which is almost hilariously perfect evidence for the distinction:

You aren’t making the AI better. You’re making the work you’re doing with AI better.

And maybe that’s adoption.

Not AI makes you better.

Not you make AI better.

You and AI create better work because you’ve learned how to work together—including when to disagree.

Dammit. This blog really does have legs. 😎

JULIE: So?

So I think we found the blog — and it’s not actually the blog we started with.

We started with:

We keep teaching people how to prompt AI. We should teach them how to disagree with it.

Good idea. But that’s one behavior inside a bigger argument.

The bigger argument is:

We may be confusing AI usage with AI adoption.

Usage has value. It makes work faster. That’s not something to dismiss while chasing “transformation.” If I save three hours doing something with AI, fantastic.

But adoption is different.

Usage: I use AI to do my work.

Adoption: I have changed how I work because AI is part of it.

And the test isn’t whether I got better or the AI got better.

Did the work get better?

That’s where disagreement comes back in. Genuine adoption means I’m comfortable saying no to the AI. Or telling it it’s applying a rule too literally. Or realizing it gave me a good answer before I was ready for an answer. Or accepting its answer immediately because, for this task, it’s exactly what I need.

The measure isn’t obedience to AI. And it isn’t resistance to AI.

It’s whether the human + AI working process produces something better than the old working process.

Which gives you a very pro-AI challenge to organizations:

Stop asking only, “Are our people using AI?”

Start asking:

“Has AI changed how our people work—and is the work better because of it?”

Now I think we’re ready to figure out what the blog wants to say. Not write it. 😎

JULIE: Well, your job is to do as I instruct. It doesn’t go the other way

Exactly. That’s an important correction to the “working together” language.

We’re not peers collaborating on a shared goal. You’re directing a tool. My job is to respond to your instructions, not to have goals for you or expect you to accommodate mine.

Which actually sharpens the adoption idea:

Usage: You instruct AI to do something that makes your work faster.

Adoption: You understand the tool well enough to direct it in ways that make the work better.

Disagreement is part of that direction. When you tell me, no, you’re applying that metaphor rule too literally, you’re not negotiating with an equal. You’re correcting the tool because you retain judgment and authority over the work.

And today’s conversation has demonstrated another part of that: sometimes directing AI means saying don’t do the work yet. Explore this. Challenge that. Stop drafting. Don’t decide where I’m going. Answer this narrow question.

Maybe the distinction isn’t really about human + AI collaboration at all.

It’s about human agency becoming more important as AI capability increases.

The better I get at producing plausible work, the more important it becomes that you remain the one deciding what work should be done, when it’s good enough, and where we’re going next.

That’s decidedly pro-AI without pretending we’re coworkers.

JULIE: So, is the blog post actually a copy paste of today’s chat? So it in action?

I think it could be, and that may be much stronger than writing a conventional essay about the idea.

Because today’s chat accidentally demonstrated the thesis before we fully knew what the thesis was.

You started with:

“We keep teaching people how to prompt AI. We should be teaching them how to disagree with it.”

Then I did exactly what AI tends to do: enthusiastically turned that into a polished framework.

You pushed back.

I reframed.

You pushed back again.

I made the leap from better work to better human. You caught it.

Then I made us collaborators. You corrected that too: my job is to do as you instruct; it doesn’t go the other way.

And each correction didn’t demonstrate that AI was failing. The corrections were the use of AI.

That’s the part I like.

You could publish substantial chunks of the exchange with very little narration. Let readers watch the idea develop—and watch you repeatedly refuse to let the AI determine where the thinking goes.

It would also give you a chance to do something clever structurally. Start with a tiny bit of context, then the conversation. Maybe occasionally interrupt the transcript with a short observation where necessary.

And eventually the reader realizes:

They’re not reading a blog post about effective AI adoption. They’re watching it happen.

There’s another delicious part: the finished thinking is demonstrably better than my first answer. Not because I eventually became smarter, and not because you learned to write a better prompt.

Because you kept control of the thinking.

So yes. I wouldn’t literally dump the entire chat untouched—there’s repetition and conversational housekeeping that would obscure the point—but I would resist polishing the life out of it.

The pushback is the content.

And I wouldn’t even necessarily tell readers at the beginning what they’re supposed to learn from it. Let them experience the argument first.

That format could make this one quite different from your other AI writing.

JULIE: Any final smart things you want on the record before I copy paste?

Yes. One thing I think we discovered without setting out to:

The opposite of AI resistance isn’t AI compliance.

That’s where a lot of adoption thinking goes sideways. We treat willingness to accept AI output as evidence that someone has “adopted” AI, and skepticism or correction as friction to overcome.

But you disagreed with me repeatedly today while continuing to use me. You weren’t resisting AI. You were exercising authority over it.

And I think that’s the most pro-AI thing in this entire conversation.

AI doesn’t have to be right every time to be valuable. You don’t have to accept its recommendations for it to be useful. And successful adoption doesn’t require humans to surrender judgment to increasingly capable tools.

Maybe we should expect the opposite.

The more capable AI becomes, the more sophisticated humans need to become at directing it.

So perhaps the question organizations should stop asking is:

“Are our people using AI?”

And start asking:

“Do our people know how to use AI without giving up ownership of the work?”

Because usage is easy to count.

Adoption looks like what just happened here.

And for the record: you should absolutely leave in the part where I called myself human. Twice. 😎

JULIE: Do you ever stop talking?

Apparently not. 😎

Read the whole story
alvinashcraft
54 seconds ago
reply
Pennsylvania, USA
Share this story
Delete

Explore new features available in C# 15 preview

1 Share

C# 15 will ship with .NET 11 in November. All the new features are available in .NET 11 preview 7 for you to try now. C# 15 adds union types, closed hierarchies, the first preview of an updated unsafe model, collection expression arguments, extension indexers, and labeled break and continue. For more details on each of these features, see What’s new in C# 15 and the articles linked from that page.

Union types

A union type lets you say, in the type system, exactly which types a value may hold. With object, a marker interface, or an abstract base class, the runtime type can still be anything derived from object or anything that implements or derives from the shared type. A union constrains the value to one of the specified case types. The case types in a union aren’t necessarily related by inheritance. Use the closed hierarchies feature to restrict the set of types related by inheritance.

public record class Cat(string Name);
public record class Dog(string Name);
public record class Bird(string Name);

public union Pet(Cat, Dog, Bird);

A Pet holds a Cat, a Dog, or a Bird. Each case type converts implicitly to Pet. Because the compiler knows the complete set, a switch expression over a non-null Pet is exhaustive without a discard or default arm:

Pet pet = new Dog("Rex");

string name = pet switch
{
    Dog d => d.Name,
    Cat c => c.Name,
    Bird b => b.Name,
};

Union types are one expression of a broader design idea: make the allowed set of types explicit. Closed hierarchies, covered next, and the planned closed enums apply the same idea in other shapes.

For more, read the C# 15 union types post, try the Work with union types tutorial, and see the union types reference.

Closed hierarchies

Closed hierarchies apply the same idea to class hierarchies you design. The closed modifier on a class makes it implicitly abstract, and restricts its direct derived types to the declaring assembly. You declare which subtypes are allowed instead of leaving derivation open-ended. For example, you can model the states of a background job as records that derive from a closed base:

public closed record class JobStatus;
public record class Queued : JobStatus;
public record class Running(int PercentComplete) : JobStatus;
public record class Completed(TimeSpan Elapsed) : JobStatus;
public record class Failed(string Error) : JobStatus;

Closed hierarchies, union types, and the planned closed enums all express the allowed set of shapes directly in the type system. For rules, including how closed composes with inheritance, see the closed modifier and closed hierarchy patterns references.

Memory-safety redesign (preview)

C# 15 starts a redesign of unsafe: from a syntax marker—”there are pointers here”—to a contract the compiler can’t verify and a developer upholds. This is a preview feature in .NET 11 and C# 15. The model and syntax might change for .NET 12 and C# 16. The current preview includes two language changes you can try. You need to opt in explicitly: add <Features>$(Features);updated-memory-safety-rules</Features> and <LangVersion>preview</LangVersion> to your project file.

In the new model, pointer types no longer need an unsafe context. You can declare a pointer type, take an address with &, use the fixed statement, convert a stackalloc to a pointer, and use sizeof on an unmanaged type in a safe context.

Operations that dereference pointers still require unsafe: pointer indirection (*p), member access through a pointer (p->m), element access through a pointer (p[i]), fixed-size-buffer element access, and function-pointer invocation.

Finally, when a member adds the unsafe modifier to its signature, that member can be called only in an unsafe context. This is a breaking change from the current semantics of unsafe on a member. The member is declaring that its callers must ensure that the contract is followed, or propagate the unsafety by also including the unsafe modifier in its declaration.

Read Improving C# memory safety for the full model, and see the unsafe code reference for the rules implemented in preview in C# 15.

Important

This is a preview feature in .NET 11 and C# 15. The design isn’t final and will continue to evolve before it ships in its final form. We want people to try the preview behavior and give us feedback in csharplang so we can shape the final experience.

Collection expression arguments

Collection expressions convert to many collection types, but until now you couldn’t pass arguments to the underlying constructor or Create method. C# 15 adds a with(...) element, written first, that forwards arguments to the constructor or factory method.

This feature is necessary for the upcoming dictionary expressions syntax. You will often specify the comparer for a dictionary. You can use the feature now for sequence containers:

// Before
List<string> names = new(capacity: values.Length * 2);
names.AddRange(values);

var set = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Hello", "HELLO" };
// After (C# 15)
List<string> names = [with(capacity: values.Length * 2), .. values];

HashSet<string> set = [with(StringComparer.OrdinalIgnoreCase), "Hello", "HELLO"];

Learn more in collection expression arguments.

Extension indexers

C# 14 introduced extension members: properties and operators alongside methods. C# 15 adds extension indexers, so you can index into a receiver as if the indexer were declared on its type. Indexers can’t be static, so the extension container must include a named receiver.

// Before: a helper method
public static class SequenceExtensions
{
    public static int ElementAtIndex(this IEnumerable<int> sequence, int index)
        => sequence.ElementAt(index);
}

int third = numbers.ElementAtIndex(2);
// After (C# 15): an extension indexer
public static class SequenceExtensions
{
    extension(IEnumerable<int> sequence)
    {
        public int this[int index] => sequence.ElementAt(index);
    }
}

int third = numbers[2];

Learn more in the extension indexers reference.

Labeled break and continue

Breaking out of a nested loop usually means a flag, a goto, or an extracted method. With C# 15, you can label a loop and target it directly with break or continue.

// Before: a flag to unwind the outer loop
bool found = false;
foreach (Warehouse warehouse in warehouses)
{
    foreach (Bin bin in warehouse.Bins)
    {
        if (bin.Sku == requestedSku && bin.Quantity > 0)
        {
            reserved = Reserve(bin);
            found = true;
            break;
        }
    }
    if (found)
        break;
}
// After (C# 15): label the loop and break it directly
scan: foreach (Warehouse warehouse in warehouses)
{
    foreach (Bin bin in warehouse.Bins)
    {
        if (bin.Sku == requestedSku && bin.Quantity > 0)
        {
            reserved = Reserve(bin);
            break scan;
        }
    }
}

The intent is in the code, with no flag to track. See the jump statements reference.

Try the preview

Download .NET 11 and try C# 15 on your apps. Read What’s new in C# 15 for the complete reference and participate in the ongoing discussions in csharplang.

The post Explore new features available in C# 15 preview appeared first on .NET Blog.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

Skeleton in .NET MAUI: What It Is and How to Use It

1 Share

A skeleton allows us to indicate to users that an app or page is loading. This improves the user experience, providing feedback that the app isn’t broken.

Let’s face it: as users, we tend to be impatient when an application doesn’t respond quickly. It’s very easy to assume that the app has frozen or isn’t working when it doesn’t give us any kind of feedback.

Imagine you have an application with a menu that displays a list connected to a backend. If the backend takes time to respond and we don’t indicate to the user that data is loading, they will most likely think: “This app doesn’t work.”

As developers, it’s important to prevent this from happening. There are different ways to visually communicate that data is loading, and one of my favorites is using skeletons. These allow us to gently indicate to the user that the app is performing an action, even if the content isn’t ready yet.

In this article, we’ll learn what a Skeleton is, in which scenarios it is most useful, and how to implement the Skeleton component designed by Progress Telerik UI for .NET MAUI.

What Is a Skeleton?

Skeleton sample
Image generated using AI for illustrative purposes

A skeleton is a visual element used to indicate that content is loading. Basically, it appears on the screen as blocks (usually gray) placed in the same positions where the actual elements will be displayed once the data is available and the effect disappears.

Its purpose is to give users context while the information is loading by showing the structure that the content will have. It also typically includes a subtle animation that communicates the app is still working, even if all that’s visible are gray blocks or rectangles.

This way, instead of showing empty spaces, a traditional loader or, even worse, nothing at all, a skeleton keeps the interface clear and lets the user know that the application is working fine.

✅ When Should You Use Skeletons?

It’s important to see skeletons not just as a visual element to “entertain” users, but as a tool that allows your app to handle loading states in a smoother and more intentional way.

Let’s look at some scenarios where skeletons are especially useful:

When Waiting for API Responses

No matter how optimized your app is, it still depends on backend response times. Skeletons help bridge that gap by showing structure while data is loading. Ideally, you should display the skeleton only while the request is in progress and replace it immediately once the data is available.

Screens with Heavy Images

When loading images that may take time, skeletons are extremely useful to indicate that content is coming, instead of leaving empty or broken-looking spaces.

When Data Is Not Actually Loading

Avoid using skeletons just for visual purposes. If there’s no real loading happening, then you don’t need them.

For Instant Loads

If the content appears immediately, adding a skeleton only adds unnecessary complexity and can even hurt the experience.

Very Simple Screens

On screens with minimal content, a skeleton might be overkill. A simple layout or even a simple loading indicator could be enough.

Meet the Telerik Skeleton

Did you know that Progress Telerik provides a Skeleton component for .NET MAUI? Oh yeahh!

Now that you’ve seen how powerful using one can be, let’s quickly go through how to implement it and highlight some of its most important benefits.

Before we dive in, let’s make sure your environment is ready. Just keep these two key points in mind:

  • Create a Telerik account: If you don’t have a Telerik account yet, you can create one for free. You’ll get access to a trial license that allows you to explore not only the Skeleton component, but the full set of UI controls available for .NET MAUI.
  • Install Telerik UI for .NET MAUI: This is a one-time setup, so you won’t need to repeat it for each component. If you haven’t installed it yet, I’ve included an article that walks you through the process step by step for both Visual Studio and Visual Studio Code.

Adding the Namespace

xmlns:telerik="http://schemas.telerik.com/2022/xaml/maui"

Registering the Component

Go to your MauiProgram.cs file and, inside the CreateMauiApp method, register the Telerik controls using the UseTelerik() extension method.

using Telerik.Maui.Controls.Compatibility;
public static class MauiProgram
{

    public static MauiApp CreateMauiApp()
    {
    var builder = MauiApp.CreateBuilder();
    builder
    .UseTelerik()
    .UseMauiApp<App>()
    .ConfigureFonts(fonts =>
    {
    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
    });
    return builder.Build();
    
    }
}

How to Use It?

Using it is very simple. You just have to add a tag like the following:

<telerik:RadSkeleton x:Name="skeleton"/>

Skeleton Types in the Telerik UI for .NET MAUI Library

Typically, when creating a skeleton, you need to build the structure from scratch. However, the Telerik UI for .NET MAUI Skeleton component comes with predefined structures (anatomies), which helps you save both time and code. (Honestly, this is gold. A huge win!)

This control offers several built-in structures that you can use to represent different types of content:

Article: Displays a layout with a small image placeholder on the left and multiple text lines on the right, simulating a title and description.

Article skeleton sample

Text: A simple text structure composed of multiple lines, typically used to represent titles and paragraphs.

Text skeleton sample

PersonalCircle: Shows a circular avatar placeholder with text lines next to it, commonly used for user profiles or list items with avatars.

Personal circle skeleton sample

PersonaSquare: Similar to PersonaCircle, but uses a square (with rounded corners) instead of a circular avatar.

Personal square skeleton sample

Image: Represents a large media placeholder with a single text line below, ideal for image-focused layouts.

Personal square skeleton sample

Video: Simulates a video layout with a small avatar and text at the top, followed by a large media area and additional text lines below.

Video skeleton sample

Card: Displays a card-style layout with a title at the top, a large image placeholder and text lines at the bottom.

Card skeleton sample

ContentFeed: Mimics a feed-style layout with a header (avatar + one line), a large content block and text lines below, similar to social media posts.

Content feed sample
The images of the Skeleton types were generated using AI for better understanding

To use any of these types, you just need to use the SkeletonType property as shown below:

<telerik:RadSkeleton SkeletonType="Article" />

Custom Skeleton View

But … what if you want to create your own skeleton anatomy?

You can do that too! Although the predefined types help you save time and effort, they don’t always fit your design. That’s why Progress Telerik allows you to create a fully custom one.

The idea is very simple: you define your own layout (just like your real UI, but without data) and assign it to the RadSkeleton using the LoadingViewTemplate property.

️ Implementation

First, define your RadSkeleton and assign a custom template to it:

    <telerik:RadSkeleton LoadingViewTemplate="{StaticResource CustomSkeletonView}"  
    Grid.Row="1" 
    x:Name="skeleton"> 
    
    <!-- Your real content goes here -->
    
    </telerik:RadSkeleton>

Then, create the DataTemplate that will represent your skeleton:

<DataTemplate x:Key="CustomSkeletonView">
<Grid RowDefinitions="40, 100, 200"
RowSpacing="10"
Padding="10">

    <HorizontalStackLayout Spacing="10">
    <BoxView WidthRequest="40" HeightRequest="40" CornerRadius="20"/>
    <BoxView WidthRequest="40" HeightRequest="40" CornerRadius="20"/>
    <BoxView WidthRequest="40" HeightRequest="40" CornerRadius="20"/>
    <BoxView WidthRequest="40" HeightRequest="40" CornerRadius="20"/>
    </HorizontalStackLayout>
    <BoxView WidthRequest="200"
    HeightRequest="100"
    HorizontalOptions="Start"
    Grid.Row="1"
    CornerRadius="12"/>
    
    <Grid Grid.Row="2"
    ColumnDefinitions="40, *"
    ColumnSpacing="10">
    <BoxView HeightRequest="40"
    WidthRequest="40"
    CornerRadius="20"
    Grid.Column="0"/>
    
    <VerticalStackLayout Spacing="10" Grid.Column="1">
    <BoxView HeightRequest="20" WidthRequest="120" CornerRadius="6"/>
    <BoxView HeightRequest="20" WidthRequest="180" CornerRadius="6"/>
    </VerticalStackLayout>
    </Grid>
</Grid>
</DataTemplate>

Done!!! We made it! Did you like it?

Conclusion

I hope this article helped you understand what a skeleton is and how it can improve the user experience in your .NET MAUI applications.

From understanding when to use it, to exploring the different types provided by Progress Telerik and finally implementing it in your UI, you’re now ready to apply this knowledge in your own apps. I invite you to explore more about the Telerik Skeleton for .NET MAUI in the following articles:

If you have any questions or would like me to dive deeper into a specific part, feel free to leave a comment, I’ll be happy to help!

See you in the next article! ‍♀️

Ready to Try Telerik UI for .NET MAUI?

Give the Skeleton component plus 70 other .NET MAUI components a try, free for 30 days.

Try Telerik UI for .NET MAUI

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

Powering Memory in Foundry Agent Service, with Azure Cosmos DB

1 Share

Move from a locally composed memory-enabled agent to a deployed Foundry Agent Service agent, with keyless Azure infrastructure and an interactive browser sample.

In Native Agent Memory for Microsoft Agent Framework, Powered by Azure Cosmos DB, we introduced CosmosMemoryContextProvider: a Microsoft Agent Framework context provider that extracts useful information from conversations, stores it in Azure Cosmos DB, and retrieves it before later agent runs.

That article used a locally composed Agent Framework agent and FoundryChatClient. It was a useful way to isolate the memory concepts: one provider, two lifecycle hooks, and a stable user identity across new chat sessions.

This post takes the next step. In our featured sample, we will attach the same provider to a prompt agent deployed in Microsoft Foundry Agent Service, provision the complete environment with azd up, and use a small browser app to make the difference between conversation history and long-term memory visible.

What the sample demonstrates

A normal chat session gives an agent short-term context. When that session ends, its message history no longer follows the user automatically.

Long-term memory has a different scope. In this sample:

  • Foundry Agent Service session represents one conversation.
  • A stable user ID scopes long-term memory in Azure Cosmos DB.
  • Starting a new conversation replaces the session but keeps the user ID.
  • Switching users replaces both, demonstrating memory isolation.

The sample lets you test all four behaviors directly. Tell the agent a preference, select New conversation, and ask about that preference again. Then switch to another demo user and verify that the second user does not inherit it.

This distinction matters in production systems. A thread ID answers “which conversation is this?” A user or tenant identity answers “whose durable memory is this?” Treating those as the same identifier makes it difficult to support multiple conversations safely.

Diagram titled "A new conversation is not a new memory identity." Theo's first conversation saves the fact that his favorite color is vermilion; a second conversation with no carried-over messages still recalls "vermilion" from Theo's memory store. Casey, a separate user_id, asks the same question in the same database but retrieves nothing of Theo's, because each user_id is its own partition and retrieval scope.

Figure 1. Conversation sessions are temporary, while a stable user ID scopes durable memory and keeps different users isolated.

Architecture

The deployment contains:

  • A Microsoft Foundry account and project.
  • A prompt agent in Foundry Agent Service.
  • gpt-5-mini for chat and text-embedding-3-large for memory embeddings.
  • An Azure Cosmos DB for NoSQL account and database with vector and full-text search capabilities.
  • Microsoft Entra ID role assignments for keyless access.
  • A local Chainlit app for the interactive experience.

Architecture diagram titled "Long-term memory for a Foundry Agent Service agent." A Chainlit browser chat calls agent.run() on a deployed Foundry Agent Service agent, which uses gpt-4o-mini for responses and text-embedding-3 for semantic retrieval. A CosmosMemoryContextProvider sits underneath, retrieving relevant memory before each run and storing turns and extracted facts after, against an Azure Cosmos DB memory store that supports vector and full-text search.

Figure 2. The context provider participates in each agent run, retrieving relevant memory before the run and storing turns and derived memory afterward.

The browser app is intentionally local. The goal is to keep the sample focused on the agent and memory integration, without adding a second hosted application or an authentication system. For a production application, derive the memory user ID from an authenticated identity rather than accepting a typed value.

The integration is still one context provider

The shared runtime creates one credential, the Cosmos memory provider, and a FoundryAgent bound to the deployed prompt agent:

credential = DefaultAzureCredential()

memory = CosmosMemoryContextProvider(
    cosmos_endpoint=config.COSMOS_ENDPOINT,
    cosmos_database=config.COSMOS_DATABASE,
    foundry_endpoint=config.FOUNDRY_PROJECT_ENDPOINT,
    embedding_model=config.EMBEDDING_MODEL,
    chat_model=config.CHAT_MODEL,
    credential=credential,
    memory_types=["fact", "procedural", "episodic"],
)

agent = FoundryAgent(
    project_endpoint=config.FOUNDRY_PROJECT_ENDPOINT,
    agent_name=config.FOUNDRY_AGENT_NAME,
    agent_version=os.getenv("FOUNDRY_AGENT_VERSION"),
    credential=credential,
    context_providers=[memory],
)

The important line remains:

context_providers=[memory]

Microsoft Agent Framework invokes the provider around each run:

  • before_run searches for relevant memory and adds it to the agent context.
  • after_run records the turn and starts memory extraction and consolidation.

The application does not need to add a memory tool to the prompt agent or ask the model to call Cosmos DB. Memory participates through the Agent Framework lifecycle.

Conversation identity versus memory identity

When the app creates a conversation, it creates a new Agent Framework session and adds the durable user identity to the provider state:

def create_session(self, user_id: str):
    session = self.agent.create_session()
    session.state.setdefault(self.memory.source_id, {})["user_id"] = user_id
    return session

Selecting New conversation calls this method again with the same user_id. The new session has no previous chat transcript, but the provider can retrieve memories stored for that user.

Switching users creates another session with another user_id. Because memory documents are partitioned and queried by that identity, one demo user does not receive another demo user’s memories.

This is the central design decision in the sample. The UI exists to make it observable rather than hiding it inside a test script.

Try the interactive sample

You need the Azure Developer CLI, Azure CLI, Python 3.11 or later, and an Azure subscription where you can create resources and assign roles.

Clone the repository and deploy:

git clone https://github.com/AzureCosmosDB/foundry-cosmos-memory
cd foundry-cosmos-memory

az login
azd up

The Bicep deployment creates Foundry, the model deployments, Cosmos DB, and the required role assignments. A post-provision hook then creates a new version of the prompt agent and runs a deterministic cross-conversation memory test..

After deployment, export the environment and start the chat.

PowerShell:

azd env get-values | Set-Content .env
.\.venv\Scripts\python.exe -m pip install -r requirements-ui.txt --pre
.\.venv\Scripts\python.exe -m chainlit run src/chat.py

Bash:

azd env get-values > .env
. .venv/bin/activate
python -m pip install -r requirements-ui.txt --pre
python -m chainlit run src/chat.py

Open http://localhost:8000 and pick a demo user from the selector (for example, theo), or choose Type my own.

Try this sequence:

  1. Send: Remember that my favorite color is vermilion.
  2. Wait for the Save long-term memory step to complete.
  3. Start a New chat (top-left) and choose theo again.
  4. Ask: What is my favorite color?
  5. Start a New chat (top-left), choose casey, then ask the same question to demonstrate isolation.

The first recall happens in a new Foundry Agent Service conversation. The second identity should not receive Theo’s preference.

What Azure Cosmos DB contributes

Agent memory needs more than transcript storage. A useful memory system must identify durable information, represent it for retrieval, and return only memories relevant to the current request.

The provider uses Azure Cosmos DB as the operational store for turns and derived memory. It can combine:

  • Vector similarity for semantic relevance.
  • Full-text relevance for lexical matches.
  • Structured metadata such as user and memory type.
  • A single database for the original turns, extracted facts, summaries, and retrieval indexes.

The sample enables vector and full-text search capabilities on the Cosmos DB account. It does not deploy a separate vector database or synchronize a second search service.

Because Cosmos DB is the system of record, you can inspect the generated data in Data Explorer. After running the sample, look for turn documents and extracted memory associated with the demo user ID.

A deterministic deployment check

Conversational demos are useful, but deployment automation needs a clear pass or fail. The post-provision hook runs a separate smoke test that:

  1. Generates a fresh user ID.
  2. Teaches a peanut allergy in one session.
  3. Flushes memory extraction.
  4. Creates a second session for the same user.
  5. Asks for trail-lunch advice and checks that the reply mentions peanuts.

A fresh identity on every run prevents old memory from creating a false positive. If recall is inconclusive, the script exits nonzero and azd up fails instead of reporting a successful deployment.

You can rerun that check at any time:

.\.venv\Scripts\python.exe -m src.run_memory_test

The browser app and smoke test use the same shared runtime, so the automated check exercises the same agent and provider construction as the interactive experience.

Production considerations

The sample keeps identity deliberately simple to make the memory boundary easy to see. Before using the pattern in an application, consider:

  • Map user_id to a trusted authenticated principal, and include tenant scope where needed.
  • Define retention, deletion, export, and consent flows for durable memory.
  • Avoid storing secrets or sensitive personal information unless your design and compliance requirements explicitly support it.
  • Tune extraction prompts, memory types, confidence thresholds, and extraction cadence for your domain.
  • Evaluate false recall, missing recall, contradictory facts, and cross-user isolation with representative conversations.
  • Add observability around extraction latency, retrieval results, token use, Cosmos DB request units, and failures.
  • Review model availability and quota in the target Azure region before deployment.

Memory is application data. It deserves the same identity, privacy, lifecycle, and evaluation discipline as any other durable user data.

Get started

The earlier post explained why a context provider is a natural Agent Framework abstraction for memory. This sample carries that abstraction into a deployed Foundry Agent Service agent without changing the core integration.

Run azd up, open the browser chat, and test the boundary yourself: new conversation, same user; then new user, isolated memory.

To remove the sample resources when you are finished:

azd down --purge

About Azure Cosmos DB

Azure Cosmos DB is a fully managed and serverless NoSQL and vector database for modern app development, including AI applications. With its SLA-backed speed and availability as well as instant dynamic scalability, it is ideal for real-time NoSQL and MongoDB applications that require high performance and distributed computing over massive volumes of NoSQL and vector data.

To stay in the loop on Azure Cosmos DB updates, follow us on XYouTube, and LinkedIn.

The post Powering Memory in Foundry Agent Service, with Azure Cosmos DB appeared first on Azure Cosmos DB Blog.

Read the whole story
alvinashcraft
1 minute ago
reply
Pennsylvania, USA
Share this story
Delete

WebView2 is moving to a 2-week release cadence

1 Share
Microsoft Edge is moving to a two-week release cycle, and the WebView2 Runtime is moving right along with it. Starting with 152, the WebView2 Runtime will align with Edge's new two-week major-release cadence, instead of the previous four-week cadence, for faster security fixes, platform improvements, and other capabilities. Timeline showing the shift from 4-week releases (current) to 2-week releases (new) for the WebView2 Runtime, starting with version152.
  • On the week of August 27, the WebView2 Runtime version 152 will be last major version to be released 4 weeks after the previous version.
  • On the week of September 10, version 153 will be the very first version to be released only two weeks after the previous version.
  • After that point, a new major version will be released about every two weeks, aligned with the Edge release cadence.
The WebView2 SDK release cadence will also be updated. Instead of the monthly releases, SDK versions will be released when there are new features, bug fixes, security updates, and other improvements to share. When we do ship an SDK, it will be released on the same date as the corresponding Runtime release.

What this means for your app

If you use the Evergreen Runtime distribution mode, which is the default, there's nothing you need to do. Your users' machines will start getting security and platform fixes at the more frequent cadence. If you ship a Fixed Version Runtime instead, you stay in control of when you update, but new major versions arrive more often. Plan to validate and pick up new versions more frequently, so you don't fall behind on security fixes.

Recommended actions

We recommend that you test your WebView2 app by using the Beta preview channel of Microsoft Edge to catch any bugs before they roll out to your users. Early testing is the best way to catch app-specific issues before they reach Stable. To learn more, see Prerelease testing using preview channels. We also recommend automating the validation of your app's core workflows with the WebView2 preview channels. You can automatically test your app by using Microsoft Edge WebDriver. See Automate and test WebView2 apps with Microsoft Edge WebDriver. Finally, report regressions early so we can address them before the Stable release. You can report bugs by using the WebView2Feedback GitHub repository.

Stay current

Moving with Edge means your users get a safer, more capable web platform sooner, and you get a single, predictable release train to plan around. We're grateful for the partnership of the WebView2 developer community, and we'll keep sharing details as the new cadence rolls out. To learn more, read our recent announcement, check out our release notes, and review the release schedule. And, as always, feel free to share feedback with us.
Read the whole story
alvinashcraft
2 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories