AI Engineer World's Fair 2024
Running AI Application in Minutes: Quick Start with AI Templates
Read the talk
From a Chat Template to a RAG Application You Can Evaluate
Build and deploy a Python chat app, add retrieval over database rows or documents, and follow the engineering decisions that turn a working demo into a testable application.
From a talk by Pamela Fox, Harald Kirschner and Gabriela de Queiroz
Before you start: Familiarity with Python, environment variables, and a terminal will help; following the deployment steps also requires GitHub and Azure access.
Getting an application running before building everything yourself
How do you get an AI application running when you have an idea, limited resources, and little time to assemble the infrastructure? Microsoft’s Build with AI templates supply an application skeleton, while its startup program supplies credits, tools, and guidance. Gabriela de Queiroz introduces Founders Hub as accessible to people with an idea, not only established companies. She describes up to $150,000 in Azure credits, alongside third-party tools, GitHub, Microsoft 365, and LinkedIn Premium. Model options include OpenAI, Llama, Cohere, and Mistral offerings.
The support also includes volunteer one-on-one sessions about hiring and technical decisions. Build with AI provides the templates; programs such as Pegasus address later co-selling and go-to-market work, alongside partnerships with Y Combinator, Neo, and The Alchemist. These offerings address four practical constraints: time to market, resources, scalability, and access to guidance.
Pamela Fox takes the workshop through three application paths, beginning with the smallest one that can establish a working development and deployment loop.
| Template | Data it uses | Purpose |
|---|---|---|
| Basic chat | Conversation messages | Verify model access and application deployment |
| Postgres RAG | Database rows | Answer product questions, with SQL filter building |
| Document RAG | Blog posts or internal documents | Retrieve relevant passages before answering |
The two retrieval-augmented generation, or RAG, applications add data access after the basic chat app works.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Establish the account and model connection
The original workshop instructions open as a Word document in the browser. Following them requires a GitHub account and a Microsoft account. The workshop’s Azure Pass provided $50 of credit valid for seven days. These credits, temporary proxy access, account restrictions, and model choices belong to the recorded workshop setup; current repository instructions and service terms may differ. Before redeeming anything, check the Microsoft identity already signed into the browser—Fox has seen attendees accidentally use their children’s Minecraft accounts. A new personal account is an option if needed.
The redemption procedure keeps two identities distinct: GitHub identifies the attendee receiving a code, while the Microsoft account receives the Azure subscription.
- Follow the document’s check-in link and sign in with GitHub.
- Copy the individual promo code and choose Get on board with Azure.
- Confirm the Microsoft account before entering the code. Fox recommends a personal account because corporate accounts can restrict deployments.
- Redeem the code, then open the Azure portal’s Subscriptions page.
- Confirm that Azure Pass - Sponsorship appears, and select that subscription when deploying.
Fox’s redemption attempt fails because she has already completed it. The workshop’s assurance that attendees will not personally pay for deployment depends on using the sponsored subscription.
Next comes model access. The workshop uses a proxy to avoid waiting for the Azure OpenAI application-and-approval process Fox describes. Signing into the proxy with GitHub yields an API key and endpoint. This is a temporary exception to her preference for avoiding keys; ordinary application keys still need protection.
The proxy playground provides an immediate connection test. Fox changes the system message to request pirate jokes, enters the key, selects a model, and asks it to explain OpenAI. The response combines the informational request with pirate phrasing. Available choices include GPT-3.5 Turbo and GPT-4; she describes GPT-4 as better but slower in her experience. She discusses GPT-4o as her preferred vision option over GPT-4 Turbo with vision, while the hands-on applications use GPT-3.5 and embedding models. The playground also exposes the response-token limit, temperature, top_p, and input/output token usage. Temperature and top_p affect sampling; the workshop’s description of them as creativity controls is an informal intuition.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Open the template and understand its async backend
The AI App Templates Workshop supplies proxy-specific READMEs for all three applications. Start with the OpenAI Chat App guide, choose Open in GitHub Codespaces, and create a Codespace. Using these instructions matters because the proxy configuration differs from the repositories’ ordinary Azure OpenAI setup. Codespaces opens VS Code in the browser with a development environment for the repository.
Startup includes building a Docker-based environment, installing dependencies, and potentially synchronizing editor extensions. The build logs make that work visible. Harald Kirschner points out that Codespaces prebuilds can move preparation ahead of the interactive session; Fox has enabled them for the third repository, but not this first one. All three examples use Python backends. The initial chat app has vanilla JavaScript in a script tag, while the later applications use TypeScript, React, and Microsoft Fluent UI.
The source folder leads to a Quart application. Its Flask-like interface makes the async programming model familiar: an async function is a coroutine, and awaiting an I/O operation lets the server handle other work while the operation is pending. This matters when a model request takes several seconds. Async does not make that model generate faster; it prevents waiting for the response from monopolizing the request-processing path. The templates use Quart or FastAPI for this reason.
The essential Python pattern is an awaited request through an asynchronous client. A helper can accept the configured client and deployment name, leaving connection setup separate from message handling:
python
from openai import AsyncOpenAI
async def answer(
client: AsyncOpenAI,
deployment: str,
question: str,
) -> str:
response = await client.chat.completions.create(
model=deployment,
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": question},
],
)
return response.choices[0].message.content or ""
The await is the point at which the coroutine can suspend while the model service responds.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Configure the connection and make the chat app your own
Create .env from .env.sample, then populate the proxy endpoint, API key, and deployment name. The workshop endpoint ends in /v1, and its deployment is gpt-35-turbo. If the terminal disappears during Codespaces setup, the terminal panel’s plus button opens another one.
An Azure deployment name is distinct from a model name. Azure can host multiple deployments of the same underlying model, each with its own name and capacity allocation. The application must address the deployment it intends to use. In this workshop, the deployment and model naming happen to align, but that is not a general assumption to build into connection code.
Run the guide’s Quart command in the Codespaces terminal, allowing clipboard access if the browser requests it. The server is local to the remote development container, not to your laptop, so copying its raw localhost address into a separate browser tab does not reach it. Instead, modifier-click the terminal link or open Ports and use the forwarded address or globe icon. Making the port public allows development sharing; the forwarded URL is still a preview, not the deployed application.
The first test asks about the weather in San Francisco. The assistant declines to supply information it does not know. Fox then replaces the generic helpful-assistant system message with instructions to make pasta jokes. Asking about the weather again produces a response about saucy weather and feeling like a soggy noodle. The edit demonstrates that the application is connected, that changes reach the running server, and that system instructions affect responses. It does not add a weather data source.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Deploy with a separate environment configuration
Once the local app behaves as intended, authenticate the Azure Developer CLI:
bash
azd auth login
Inside Codespaces, the demonstrated login uses a device code and browser flow. Select the same Microsoft account that redeemed the Azure Pass.
Codespaces is convenient for a workshop because it reduces differences between attendees’ machines. You can also run the repository in a local Python virtual environment after installing its requirements, or use VS Code’s Dev Containers extension for the Dockerized environment on your machine. The speakers settle on a stated 60-hour monthly Codespaces allowance during the session; treat that as the workshop’s account guidance, rather than a current entitlement for every account.
Next, create a named azd environment. Its variables live under .azure/<environment>/.env, separate from the root .env used by the local server.
| Configuration | Used by | Purpose |
|---|---|---|
.env | Local application | Development model connection |
.azure/<environment>/.env | azd | Deployment configuration |
Set the deployment variables from the workshop guide: disable creation of an Azure OpenAI resource, then supply gpt-35-turbo, the proxy key, and the proxy endpoint. Configuring the local server does not automatically configure the deployment. Inspect the environment file before proceeding.
Run azd up, choose the sponsored subscription, and select a region. The first template packages the code as a Docker image for Azure Container Apps. Provisioning then creates the container app, container registry, Container Apps environment, and Log Analytics workspace. Another template uses Azure App Service.
Infrastructure as code makes the deployment repeatable. Bicep declares the resources, their connections, and role assignments, so provisioning can recreate the intended arrangement. The same approach can connect a larger stack containing Postgres, Key Vault, Redis, and application hosting. Terraform is an alternative, but these examples use Bicep. Progress appears in the terminal and Azure portal.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Recover from region and naming constraints
The live deployment encounters a constraint: Fox already used Central US for an earlier demonstration. She describes the workshop pass as allowing one container app per region. To recover, she creates another environment, copies the configuration, changes the region to West US, selects the new environment with azd env select, and runs azd up again. The working app she then opens was deployed previously; its Container Apps URL distinguishes it from the Codespaces preview.
The Bicep files are handwritten, with core modules copied from a shared repository. Fox describes a planned move to Azure Verified Modules, or AVM, to use maintained modules incorporating security practices. Bicep modules can come from a public registry, private registry, or local folder. For workshop troubleshooting, short environment names without symbols avoid some naming problems; azd env new starts a fresh environment when necessary. Naming rules, regional restrictions, and account constraints are the recurring failure categories.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Ground answers in retrieved database rows
The pasta assistant is entertaining but unreliable as a source of facts about Fox: asked what she likes to code with, it invents Spaghetti-Python. A blog-backed assistant first declines an ambiguous question, then answers a more specific question about her Python frameworks with citations. The difference is access to a relevant knowledge source.
The core RAG sequence is straightforward:
- Receive a user question.
- Search a database or search engine for relevant material.
- Place matching sources alongside the question in the model request.
- Instruct the model to answer from those sources.
The PostgreSQL RAG template applies this to product rows. Asked for the best shoe for hiking, it searches the database and produces an answer with citations that the user can inspect.
The interface’s Thought process view exposes the application’s retrieval stages, rows, and prompt. A separate model call first cleans up the user’s wording: Please tell me about the best shoes for hiking now becomes best shoes for hiking. Retrieval uses that shorter query. The final answer request then includes the original question, retrieved sources, and instructions for formatting citations. The two model calls have different jobs: one prepares the search, and the other synthesizes the answer.
This template can run against a local Postgres database before deployment. Its React frontend adds a richer interface, but the workflow remains familiar: configure the application, test locally, set deployment variables, and deploy to Azure.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Turn documents into searchable, citable chunks
Documents require an additional preparation stage. The Azure Search OpenAI demo indexes material such as PDFs, Word documents, and spreadsheets. Fox describes a sample developed over more than a year and deployed by thousands of developers, including production users. Its features include speech, voice, vision, and user access control. She demonstrates versions backed by her blog and an internal company handbook, with clickable citations.
A 31-page handbook illustrates why the application retrieves passages instead of sending the entire document. Fox discusses context windows of 8K, 32K, and 128K tokens, but fitting the input is only part of the problem. Lost in the Middle examines how the position of relevant information affects long-context performance. Evidence can become harder to use when buried among other material. The retrieval goal is therefore to supply the most relevant chunks, not simply the largest possible prompt.
The ingestion pipeline has four responsibilities:
- Extract text. Azure Document Intelligence reads the source document.
- Split it. The sample uses chunks of roughly 500 tokens.
- Embed and index it. Store each chunk and its embedding in Azure AI Search.
- Preserve provenance. Retain the source file and page alongside the chunk.
At question time, search returns those records, and only the selected chunks enter the answer prompt. File and page metadata make the resulting citations navigable. Ingestion can run locally or in the cloud; its processing and additional infrastructure make these templates slower to deploy than the basic chat app.
Much of the sample’s ingestion code was written before the current range of libraries was established. Fox would now consider a LangChain splitter, and names LlamaIndex as another ingestion option. The crucial property is token-aware chunking, especially for multilingual documents: a character count does not reliably predict the token budget. A Chinese passage with a seemingly modest character count can consume much more context than expected. Anthony Shaw’s analysis of Chinese, Japanese, and Korean text adds a second requirement: preserve character boundaries while measuring token length, rather than cutting blindly through encoded token sequences.
After splitting, the OpenAI SDK can embed multiple chunks in a batch before they are stored in AI Search. Extraction remains format-specific. Besides cloud Document Intelligence, the sample has local options: pypdf for PDFs, a custom CSV parser, and Beautiful Soup for HTML. Fox uses Beautiful Soup to extract her blog’s text. A reusable splitter helps with chunk boundaries, but it does not eliminate the need to understand the source format.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Understand what changes when infrastructure changes
An audience question about replacing Bicep modules leads to the distinction between a module and a deployment. Bicep compiles into Azure Resource Manager, or ARM, JSON. An ARM deployment compares requested resource configuration with existing resources and applies the necessary changes. Moving to AVM is intended to reduce module maintenance, but it still requires reviewing the resulting resource configuration. Fox points to Azure CLI deployment what-if support for previewing changes; she does not establish an equivalent azd dry-run command during the session.
azd orchestrates the larger workflow. The repository’s azure.yaml maps application code to a host; infrastructure definitions describe the resources. The CLI combines packaging, infrastructure provisioning, and code deployment. AVM supplies reusable infrastructure modules within that process. This separation lets a similar development workflow target Container Apps, Functions, App Service, or Kubernetes, while the actual resource definitions and deployment host vary. Fox’s example catalog marks repositories that already support azd.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Make quality observable and testable
Deployment opens the production questions: how will the application behave under load, and how will you know when it fails? The document-RAG repository includes a productionizing guide and integrates Application Insights through OpenTelemetry. Fox also names Langfuse as an observability alternative she likes.
Production preparation includes scaling, balancing OpenAI capacity, VNet deployment, user authentication, and load testing. Answer quality needs its own tests. A few successful demonstration questions—or a prompt edit that improves one answer—cannot establish overall improvement. Fox recommends roughly 200 evaluation samples as a minimum in her practice. That is a practical starting recommendation, not a demonstrated statistical threshold.
Kirschner describes Copilot Chat as several retrieval systems working together. Its @workspace path uses a local sparse index; another path uses a semantic index maintained by GitHub, with LLM-based ranking. Query keywords can be generated before retrieval. The evaluation cadence has two layers: a smaller regression-oriented set on pull requests and a larger daily set covering repositories across languages. Previously observed failures become regression cases. He identifies evaluation as an early major investment because prompt-crafting intuition is easy to mistake for dependable behavior. The local sparse implementation uses TF-IDF.
Fox’s blog evaluations combine model judges with deterministic checks. The judge compares a new answer with a synthetic reference answer, using an example-bearing prompt and a one-to-five rating scale. Groundedness and relevance use these GPT-based metrics. Her preferred simple check extracts citations and verifies that the generated answer includes the citations expected from the reference. The discussion also identifies passing code tests as another evaluation method for code tasks.
The experiment axes include text-only search, vector-only search, hybrid search, and hybrid search with a ranker; retrieving three, five, or ten results; and changing the prompt. Fox reports that her prompt tweaks had not produced enough aggregate improvement to justify changing the sample prompt. Retrieval parameters and switching from GPT-3.5 to GPT-4 made more meaningful differences in her experiments. This gives evaluation a concrete job: decide which changes deserve to become the new baseline.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Inspect the failures behind retrieval scores
Choosing a vector store or chunk size becomes easier when the evaluation material is familiar. Fox starts with aggregate results, then compares individual answers between the baseline and experimental runs. Filtering for changed citation matches helps identify cases worth reading. Domain knowledge is needed to determine whether the answer improved—and whether the evaluator itself made a sensible judgment.
The Azure AI Search team’s retrieval experiments motivate comparing hybrid retrieval with semantic reranking. Fox then tests retrieval choices on synthetic questions about her own blog, reported in Doing RAG? Vector search is not enough. These are generated-answer groundedness scores on a one-to-five scale, not retrieval accuracy:
| Retrieval mode | Groundedness |
|---|---|
| Vector only | 2.79 |
| Text only | 4.87 |
| Hybrid | 3.26 |
Text-only retrieval performs strongly in this application. Basic hybrid retrieval merges text and vector rankings using reciprocal rank fusion, but including vector results also introduces distracting material.
The failure examples are concrete. Fox has seen near-empty text embeddings match too broadly. In a customer’s vision-enabled application, a blank blue page embedded with an Azure Computer Vision model appeared repeatedly among results. Such candidates can occupy context that should contain useful evidence. Adding vector search therefore creates another retrieval path whose output must be inspected, not an automatic improvement.
Hybrid retrieval with the semantic ranker produces the best result in Fox’s comparison. Her published table gives groundedness of 4.89 for hybrid with ranker, versus 4.87 for text only. That is a small groundedness difference; it should not be read as a several-percentage-point gain on that scale. The complete comparison shown on screen includes groundedness, relevance, answer length, and citation match.
Fox describes the semantic ranker as a cross-encoder trained using human judgments of query/result relevance, also used in Bing. It evaluates the query together with candidate results and reorders them. Her preference for text search over vector-only search is specifically conditioned on Azure AI Search’s strong full-text retrieval. The brief uncertainty about SQLite is not a reason to rule it out: SQLite FTS5 provides full-text search, and this discussion establishes no measured SQLite-versus-Azure comparison.
The full-text discussion names Lucene, text analysis such as tokenization, and BM25 ranking, with Copilot’s TF-IDF index as a comparison point. These are related lexical-search techniques, not interchangeable algorithm names. Fox also explains the origin of the sample’s roughly 500-token chunks: the cited Search experiments used 512-token chunks. Treat that configuration as a useful starting point to evaluate on your documents, rather than a universal optimum.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Update embeddings deliberately, and retrieve code by structure
Vectors need updating when their source content changes. Changing the embedding model is broader: the corpus must be embedded again in the new model’s space. Fox proposes a separate AI Search index to evaluate the new text-embedding-3 family, with dimensionality as another experimental choice. She has not yet tested the improvement herself. The discussion mentions 256 and 512 dimensions without settling a final configuration. Kirschner recommends testing, including customer A/B tests where available; the reindexing work remains part of the migration.
The next demonstration makes code retrieval visible inside VS Code. Inline chat applies natural-language requests directly to code, while side-panel chat can discuss a selected region. Kirschner selects tests and asks about them; the response includes highlighted references and navigation to dependencies. Selecting relevant code gives the assistant an explicit context boundary.
For repository-wide questions—such as which tests exist or how benchmarks run—he invokes @workspace. In the demonstrated setup, the repository is primarily searched locally; he describes GitHub-maintained semantic indexes as available for Enterprise and some open-source repositories. The local sequence expands the query with repository-relevant words, applies stemming, retrieves through TF-IDF, and reranks the results. Kirschner reports that this approach often outperforms vector-only retrieval in their experience. He tentatively identifies the reranker as another GPT-3.5 call, while emphasizing ongoing experimentation.
The retrieved chunks are inspectable. For supported languages, custom semantic chunkers follow functions and code blocks rather than cutting solely by length. Kirschner identifies this structural chunking as a major source of improvement. The team’s language expertise helps it implement these boundaries; a preexisting online semantic index can also reduce retrieval work.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Manage prompts and budget evaluation runs
A .prompty file in the editor prompts a discussion of Prompty, introduced at Build. It gives prompts an explicit artifact format: YAML metadata at the top and a Jinja template beneath it. Variables can be supplied to the template instead of scattering multiline prompt strings across application code. Fox names Promptflow and Azure AI Studio as users of the format and discusses LangChain integration as available or forthcoming. Her evaluation interface is a custom CLI and UI built on the Promptflow evaluation package, which also provides its own tooling.
The evaluation repository runs a smoke test against a target URL. Extending that to every application’s CI build requires reaching the correct deployed build and its Azure resources. Authentication and VNet isolation complicate access: the evaluator must work with the application’s real deployment topology. Fox has a working example, but describes a general solution across all repositories as unfinished.
Evaluation also has a different cost profile from ordinary unit tests. Each case can invoke the application’s model calls, followed by additional judge calls for groundedness and relevance. Those calls add latency and expense. Kirschner describes caching within the testing infrastructure: unchanged prompts and test inputs reuse previous responses, while changed inputs trigger another run. Fox notes that this is harder when an evaluation repository targets an application maintained elsewhere, because the remote application may change independently.
That test-response cache should be distinguished from both application answer caching and seeded generation. The OpenAI seed documentation describes best-effort reproducible sampling, not replaying a cached answer. Kirschner clarifies that his cache belongs to the testing infrastructure, not Copilot Chat itself. Repeated test inputs make reuse predictable; a user-facing RAG app may see fewer identical questions.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Separate model compatibility from reliable output
An evaluator that calls a deployed application URL can remain independent of the underlying model provider. The starter templates themselves have a narrower integration contract: they are configured around OpenAI models and the OpenAI SDK. Fox considers the newly introduced Azure AI Inference SDK as a possible way to support additional hosted models, but has not tried it. The tradeoff is broader Azure model access versus the portability already available through the OpenAI SDK. Supporting hosted Mistral or Llama models would also require Bicep provisioning changes, not just swapping a client library. Requests in the issue tracker help prioritize that work.
Fox says the samples already work with Ollama, including local Phi-3 models. But being able to make a request is different from satisfying the application’s output contract. In her experiments with small local models, answers could synthesize information yet fail to follow instructions reliably. Kirschner responds that different models require different prompts. Fox’s local capacity limits her tests to models up to roughly 7B parameters; trying a 70B model is a future intention.
The visible failure is citation formatting. The frontend expects square-bracket citations so it can turn them into clickable source links. A fluent answer without that syntax breaks part of the product. Fox also reports more fabrication on off-topic questions in her local tests. Kirschner suggests narrower jobs for small models, such as reranking or judging, where they need not produce a full answer with strict citation formatting. Predictable output syntax and function-calling support still need to be assessed for the particular model and runtime.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Use computation when the question spans the whole dataset
Retrieving a few passages is appropriate for answering from selected evidence. Counting or analyzing an entire database calls for a different operation. Fox describes a PyCon application in which a user uploads a CSV and asks about the top restaurants. The model generates pandas code, and the application executes it in a sandbox. SQL aggregate functions provide another route. The critical shift is that computation covers the dataset instead of asking the model to infer an aggregate from a few retrieved rows. Generated code must run within a safe execution boundary.
For a CSV where each row represents one restaurant observation and the restaurant name is in a restaurant column, the computation could be:
python
import pandas as pd
def top_restaurants(csv_path: str, limit: int = 10) -> pd.DataFrame:
observations = pd.read_csv(csv_path)
return (
observations["restaurant"]
.dropna()
.value_counts()
.head(limit)
.rename_axis("restaurant")
.reset_index(name="count")
)
This counts all applicable rows before selecting the top results. The surrounding application, rather than the generated pandas expression, must enforce sandboxing and permitted data access.
The final discussion returns to structured output. An attendee describes supplying a TypeScript definition for the desired answer and type-checking the response. Fox connects this approach to TypeChat. She describes experiments using TypeChat with local Phi-3 as an alternative to OpenAI function calling, but says those attempts struggled; further prompt work is proposed.
The exchange does not resolve Phi-3’s JSON response-format support. The attendee clarifies that the successful example of explicitly requesting JSON used GPT-3.5, not Phi-3. That leaves a concrete requirement for whichever model powers the application: verify that its output satisfies the format the consuming code expects. The workshop closes by inviting attendees to keep deploying with their remaining seven-day pass access—continuing from a working template into experiments with their own data, retrieval choices, and output constraints.
Suggest correction
This note stays in this page until you copy or download it. Nothing is submitted; reloading clears the draft.
Resources
From the talk
Proxy-specific workshop guides for a basic chat app, PostgreSQL RAG and document RAG.
A database-backed chat application with Azure deployment instructions.
Document RAG sample combining Azure AI Search retrieval with generated answers and citations.
The June 3 article explains hybrid retrieval and compares answer quality on questions about Pamela Fox’s blog.
Anthony Shaw explains multilingual tokenization and recursive splitting that respects token budgets and character boundaries.
Microsoft’s retrieval experiments comparing keyword search, vector search and semantic reranking.
Experiments on how the position of relevant information affects long-context question answering and retrieval.
Prompt asset format and tools for managing, debugging and evaluating prompts.
Further reading
- OpenAI seed parameter and reproducible outputsDocumentation
Archived guidance on seeded sampling, backend fingerprints and the limits of reproducibility.
Read the complete timestamped transcript
- 0:00
[upbeat music] Thank you so much for coming to the workshop.
- 0:17
My name is Gabriela de Queiroz, and I'm director of AI at Microsoft. I have Pamela here.
- 0:25
I'm Pamela, and I'm a Python cloud advocate. [laughs] So well done on those of you who said Python. Um, but, uh, I also, I worked in JavaScript before then for quite a long time, and I generally like lots of languages.
- 0:38
And then we got Harold. Here we go.
- 0:40
Hi. I'm Harald. I'm a PM on VS Code and GitHub Copilot Chat, so...
- 0:48
Awesome. Um, so today we are going to be t- talking or showing you how to run a AI application in minutes. So we are going to have a lot of, like, hands-on, so be ready to do, like, some coding.
- 1:05
Not coding, but, like, h- going through some coding, uh, using different tools, uh, GitHub Codespaces, Azure, and, and other tools that we are going to be talking about. But, uh, just to give a, a, a overview of, like, the agenda, I'm going to be talking about Microsoft for Startups a little bit, some of the partnerships, some of
- 1:25
the pain points, and then we go through the AI templates and hands-on. Uh, so Microsoft has a program for startups. So if you have an idea, if you have a startup, uh, you can apply to this program.
- 1:42
And what I always tell people is you don't have to have a startup per se, but if you have an idea, that's enough to apply for this program. And you get a lot of benefits, and benefits that can be, um...
- 1:55
I'll just skip. Uh, it can be, like, credits. So you get up to $150,000 in Azure credits. You also have third-party benefits, like a lot of, like, different tools that you can use.
- 2:06
And then of course, GitHub, Microsoft 365, LinkedIn Premium, and more. Uh, you can use all the different models from OpenAI, but also, like, Llama, uh, models from Cohere, uh, Mistral, and so on.
- 2:22
And the, the piece that I like the most is about the sessions, that you can get one-on-one sessions with people like me or Pamela, uh, that, uh, we volunteer our time to share our knowledge with founders.
- 2:35
Uh, we can talk about maybe, like, I don't know, you are hiring, and then I'm an expert in hiring, so you come and talk to me, and I say, "Hey, these are some of the best practice for you when you are building your team."
- 2:46
Or you can go to technical sessions and ask more, like, technical pieces, um, as well. And inside this platform, we have, like, several things other than the benefits that I mentioned and the guidance that I just mentioned.
- 3:00
It's what we call Build with AI. And inside, we have some AI templates that the idea is, like, you, you, you... we can help you accelerate, um, the, the AI application piece with some kind of, like, skeleton in a way.
- 3:17
Um, so, so you have something up and running in, like, f- few minutes.
- 3:24
Um, so again, you get cr- cloud credits. You have access to dev tools. You have the AI templates. You have the one-one, one-on-one guidance. Um, and no matter where you are in your journey, if you have an idea, if you are already building or if you're scaling, this program is for you.
- 3:47
Um, you have access to all the cutting-edge AI tools so you can innovate and streamline your AI development. And on top of, like, the Founders Hub, this program that we have, we also have, like, different programs, um, that it kind of like, it's like the next step.
- 4:04
Like, let's say you are now scaling, growing, and then you use all the credits. What is next? There is a next. Like, you know, we try to guide you through the whole process.
- 4:15
So there is something called the Pegasus program, um, where we help you to co-sell, go to market, and so on. And then there are some, like, strategic VC partners and, like, accelerators that we partner with.
- 4:27
So we have partnership with Y Combinator, Neo, The Alchemist, uh, et cetera.
- 4:34
Um, pain points for startups, there are a bunch of them. Uh, one of them is, like, you don't have time. You cannot wait to go to market. You have to go r- like, as fast as you can.
- 4:46
You have a lot of, like, resource constraints. We have some issues with scalability. You have... You don't have the support and guidance, and that's where we are trying to, um, help you with.
- 4:57
So now we are going to go to the fun part. It's, like, the AI templates. So that's where Pamela is going to show you all the amazing things that you can do with all the different tools.
- 5:12
All right. So our goal today is potentially having you deploy maybe even three different templates.
- 5:21
Three?
- 5:21
Okay. [laughs] Um, uh, so we have three different ones. I'll, like, just, um, you know, show in the, in the browser which ones we're gonna be deploying, right? So we have starting, we're gonna start simple with this chat application here, just to make sure everything's up and working.
- 5:38
And then we've got two different RAG applications. One of them is a RAG on a Postgres database, like RAG on a Postgres table that does, uh, SQL filter building.
- 5:47
And then we have RAG on a unstructured document. So here I've got a RAG on my personal blog [laughs] or, like, a RAG on, you know, internal company documents, whatever it is that you're gonna, whatever kind of documents you're gonna RAG on.
- 5:59
So those are the three templates we're gonna be looking at today, and we have it all set up so that you should be able to deploy those templates without spending any of your own money, and doing it all through our credits, which is yay.
- 6:13
All right. So- Um, the first thing you need to do is get this URL. So everybody open this URL on your computer. So it's aka.ms/aie-workshop. It should open up a, a Word document in the browser that looks like the screenshot you see here.
- 6:33
So you can either type in the URL or scan that QR code and get that open on your machine.
- 6:42
So let's make sure everyone's got it open.
- 6:49
Welcome, welcome. So go ahead, and once you've got your computer ready, put this, uh, put this URL in your browser. Harald, maybe you can just memorize it and then help anyone who doesn't have it.
- 7:02
Yeah, aie-workshop. [laughs] Uh, okay. So then let me go to the actual doc here.
- 7:12
So the first thing you need is a GitHub account. Does anybody here not have a GitHub account?
- 7:19
Okay, so everyone here has a GitHub account, great. If you don't have a GitHub account, you can sign up for one for free right now, and um, and that should be fine.
- 7:28
Um, the next thing you need is an Azure Pass. So this is something that we've got for this workshop, for this conference, and this is gonna let you deploy stuff on Azure without spending any of your own money.
- 7:40
So we got passes for 50 bucks, and they're valid for seven days, so if you do wanna keep hacking after the workshop, you can keep using your pass and, uh, after seven days it'll disappear just like Cinderella and the pumpkin.
- 7:54
Uh, so in order to get that Azure Pass, you do need to have some sort of Microsoft account. So you can use your, like, uh, you could use a personal Microsoft account if you have one.
- 8:07
Uh, so if you're, if y- like, how do you tell which one you're l- logged into right now? I guess if you just go to outlook.office.com, maybe you would know what Microsoft account you're currently logged into.
- 8:16
Um, and then you can see. Some people in the last workshop were, like, logged into their kids' Minecraft account, so [laughs] just, uh, just you d- you need a Microsoft account, and you might wanna double-check to see which one you're currently signed into if you are signed into a Microsoft account.
- 8:29
If you don't have a Microsoft account, no big deal. You can make one on the spot. I made one this morning. So, uh, if you do need to make one, you can just make up a new Outlook address and set it up that way.
- 8:40
Um, so you can also make it as part of this progress. So we're gonna go to this AZ check-in URL, and that's linked from this doc here. So if you don't have this doc, if you just came in, we can help you get this doc open so we can get this URL.
- 8:52
And, uh, we're gonna spend 10 minutes making sure we get through this step since it can be a little, uh, a little tricky. So when you go to this check-in URL, right, we put this in the browser.
- 9:03
It loads. This is what you're gonna see, and it says I can either create a GitHub account or log in with GitHub. So I'm gonna log in with GitHub 'cause I already have a GitHub account and I'm logged into this browser with it already.
- 9:14
So I'm just gonna click on that. And so what that's gonna do is create a pass for my GitHub account. And so we get a pass, so each of us will get a different code based off our GitHub account.
- 9:28
So this is my, you know, ba- basically my Azure Pass promo code, so I can copy that, and then there's this button here that says Get on board with Azure.
- 9:37
This is the next step, is to click this.
- 9:43
And then we get this screen which says, okay, this is, you can start.
- 9:49
And when I click this here, it says what my currently logged-in account is, so this is where you should check to make sure you're happy with what account you're logged in with and you don't wanna switch.
- 9:59
Um, I don't recommend using a corporate account. If you do have a corporate account, like, don't... just don't use it. It's gonna be problematic [laughs] for various reasons, 'cause corporate accounts may have restrictions that won't let you deploy things.
- 10:11
So we do recommend using some sort of personal account or making up a new account, so that's why you see I'm using my Gmail instead of my Microsoft. Uh, so I'll confirm my account, and then I can enter the promo code, and that was from this screen, so I still have this screen open, so I just go
- 10:28
there. I paste it in, and then we go S, uh, six, X, Y, Y, K. I think it's case insensitive.
- 10:41
Submit. And then it's, uh, gonna actually fail for me because I've already set this up on, on this, uh, thing here. Um, and this, if you see this, it's because you've already actually gone through this stage.
- 10:52
Uh, so for you, it should work the first time. And then, uh, it'll create the Azure account for you. And if it works, then what we can do is go to portal.azure.com, so portal.azure.com.
- 11:08
And we'll see what it, how it loads in.
- 11:12
Does a bunch of redirects. And then we can click on Subscriptions, and what we should see is there should be at least one subscription that says Azure Pass - Sponsorship.
- 11:24
So that's our key that we have done this correctly, and as long as we use this subscription when we're doing our deploys, we will not get charged any money.
- 11:33
Well, Microsoft will, but you won't. That's the important part. Okay, so we're gonna spend 10 minutes to make sure that we can get everyone through this, this stage so that we're all on the same page going forward.
- 11:43
So if you already got it, that's awesome. You can, um, you know, like, look at Harald's, like, uh, Facebook profile or something. [laughs]
- 12:01
So once you have that set up, the next step is the proxy
- 12:08
Um, so I'll just show that, uh, so that you can start playing with that. Uh, so here's- It's the next link in here. So the reason we have a proxy is because normally when you're using Azure OpenAI, you actually have to fill out a form and say how you're gonna use Azure OpenAI, and then somebody says, "Oh,
- 12:25
okay, yeah, that's a good use of OpenAI," because Microsoft doesn't want people to use AI willy-nilly. So we, you know, check to make sure that something adheres to our responsible AI principles.
- 12:36
Uh, we don't have enough time for you to go through that process while we're in a workshop, so we've set up a- an Azure OpenAI proxy that you can use during the workshop with the repos, and we have special instructions for how you can use this proxy with the repos since you can't use the actual Azure OpenAI.
- 12:53
Uh, so this- you can follow the link from the doc and log in with your GitHub account. Uh, I'll log out so I can show that.
- 13:03
Log in with GitHub. Okay, and it says I'm logged in.
- 13:11
And then we have an API key and a proxy endpoint, and that's all we need to be able to, uh, to use an Azure OpenAI instance. Now, normally I don't like to use keys, and I tell everybody to avoid them, but, uh, in this situation we are gonna be using keys.
- 13:31
And, uh, yeah, and these keys will expire at a certain point, so we don't have to worry about them being exposed. Uh, typically with keys we'd have to protect them very fiercely so that nobody was using them.
- 13:43
So you can go ahead and log into this and see your registration details, and then you can even play around with the playground. This is really similar to the Azure OpenAI playground or the openai.com playground if any of you played around with this.
- 13:56
Uh, you can see here you can play with the system message. That's how you like say like, "Oh, you're an AI assistant that constantly makes pirate jokes."
- 14:10
Yar. Uh, and then we update the system message. [laughs]
- 14:15
Oh, private. [laughs] I wonder what it'll do. [laughs] Uh, there we go. And then, um, let's see. Oh, enter my API key. Okay, so we need to enter the key. I actually have never used this before.
- 14:29
Uh, so we're gonna enter the key, not save it. Select a model. Okay, so we select a model over here.
- 14:37
Uh, so we've got 3.5-Turbo. Oh, I didn't know we had 4 too. You set up 4 as well? Cool. We can use 4. 4 is better. All right. And [laughs] 4 is slower but better.
- 14:51
Uh, okay, and then, uh, please, uh, tell audience about OpenAI.
- 15:01
Okay. All right, and you can see different parameters that we send, and these are all getting sent to the OpenAI SDK. So we say the model. Right here we've set up two models, gpt-3.5-turbo, gpt-4.
- 15:14
Those are often the ones you're picking between with OpenAI, although now you've got gpt-4o. That's a good choice if you're doing something with vision, something multimodal. I wouldn't use it otherwise just based off of some experience we've had with it.
- 15:28
Um, but it is a great one. Gpt-4o is good for vision. Uh, so here you can see, you know, with the combination of the system message and the user message, so this is what we call user message, this is what we call system message, those combined together we get back a response like this where it describes OpenAI
- 15:47
with lots of Rs and mateys and stuff. Uh, we can, you know, change different parameters here, like how many tokens it should send back. The temperature is roughly the creativity.
- 15:58
Um, top P is also roughly about creativity. And there's some more advanced stuff there, and you can see how many tokens you used on the way out and how many tokens you got on the response.
- 16:10
So you can play around with this playground to, uh, you know, to try stuff out and make sure that, uh, that you're able to, to use the key. So this is just linked off of, um, off of this workshop, right?
- 16:24
So if you go to the workshop proxy, you log in, you'll get your key and your endpoint, you can go to that playground, and you can play around with the playground to check that that's working.
- 16:35
But we just want to make sure everybody now has an Azure pass and is logged into the proxy so that you have a key and an endpoint. So we'll just check to see if anyone had any issues with that.
- 16:45
This step is hopefully long. Okay. All right. So here's the... Like he- these are... If you're looking for the models, this is generally the, the page to check. Um, so, you know, gpt-4o, gpt-4.
- 16:57
Or- And going down, those are the GPT-4 models. Gpt-5. You're saying there's a gpt-3.5 that supports vision? No, no. The 4.0-
- 17:08
Oh, 4-turbo with vision. Uh, this one. This one? Yeah. So we were using that one, but it's a lot s- slower. Yeah. So that's why we- I've started using 4o.
- 17:19
Where? Or this one. This is the latest one. This is the GA- Oh ... version of GPT-4. Oh. Okay. All right.
- 17:28
Yep. So you just want to compare those. So we'll just be using the basic gpt-3.5 and gpt... Uh, just gpt-3.5 today actually, and then also the embedding models. Okay, so is everybody set up with the proxy?
- 17:39
Okay. All right. So now we're gonna actually get something working. So we have this repo here, so you can follow the link from the doc, and it has readmes for the three different projects that we can deploy, and these readmes are specific to using them with the Azure OpenAI proxy.
- 18:01
Uh, so normally you can just use the, the readmes that are on the repos itself, but because we are using this Azure OpenAI proxy, we do have to use a slightly different setup.
- 18:10
So we've made readme specific, uh, for this, for this workshop. Uh, so we can start off on this, uh, OpenAI Chat App Quickstart and make sure that that's all working.
- 18:22
So the first step is to open in GitHub Codespaces. So you can do that by clicking this button here. Have any of you used Codespaces before?
- 18:32
Okay, couple people. So Codespaces will open a VS Code in your browser with a developer environment for that repo. So you can actually use Codespaces on any GitHub repo.
- 18:44
So you go to a, any GitHub repo, you click on Code, and you can make a Codespace for it. So it's a way that you can start hacking on any repo, uh, very quickly.
- 18:53
So you can open this button here to open in Codespaces,
- 18:58
and, uh, I'll just go ahead and make a new one.
- 19:03
And I'll say Create codespace. So this is gonna take a few minutes to load, 'cause what it's doing is that it's creating the environment for this repository, it's opening VS Code in the browser, and it's also just setting up VS Code.
- 19:23
So if you actually have, like if you use VS Code locally, and you've got like extensions that you use locally, it's actually potentially syncing those extensions and, uh, enabling them, them here.
- 19:34
I should probably just not do that, 'cause then it would load faster for me. [laughs] Um, but yeah, you can see in the bottom here as it's setting up, and we'll just wait for it. [laughs]
- 19:46
So this is, you know, the slowest part of using Codespaces is just the loading.
- 19:52
You have a tip?
- 19:54
If you want faster Codespaces, there's prebuilds available as well.
- 19:58
Yeah, and I do have them on the third repo-
- 20:00
Yeah
- 20:00
... but I think I don't have it on this one.
- 20:02
It's okay.
- 20:02
So I, I should have remembered to do prebuilds-
- 20:05
Yeah
- 20:05
... for all the repos.
- 20:06
Right. And the slowest part is probably installing all the dependencies and the builds. It's basically i- it's doing all the things you would do when you install it locally, just automated-
- 20:15
Mm-hmm
- 20:15
... and with a progress bar, and at some point it will just light up.
- 20:19
Yeah. Let's see what the... You can even watch... Can we watch the logs for this one? Building Codespace, Code. Whoop.
- 20:30
There we go. So you, if you like this sort of thing, like if you like watching Docker containers build, [laughs] 'cause that's what it's actually doing. Everything's a Docker container.
- 20:38
So you can actually watch it as it, um, builds everything here. [laughs] And now it's downloading all the requirements. So these are all the Python requirements. So all the examples that we're going through today have a Python back end, and then some sort of JavaScript front end.
- 20:54
Uh, this one has what we call like a vanilla JavaScript front end, as in I just wrote some JavaScript in a script tag. Uh, but then the other ones are much fancier, so they've got a full TypeScript, and a build system, and React components, uh, using the Microsoft Fluent UI, uh, you know, web framework.
- 21:10
So you can s- kind of see the range of front ends there. Okay. So you can see it's, you know, it's still going through the process, but at least now, uh, we can see the file explorer has loaded, so we can, uh, explore the files here.
- 21:26
And, uh, and I'll show, I'll go ahead and show the, the code. If you're interested in the code, uh, it is in the source folder. Uh, we're using a Quart application, and I think nobody has heard of Quart, but, uh, has anyone here heard of Flask or used Flask?
- 21:42
Great. So Quart is just the async version of Flask. So it's literally built on top of Flask, and one day it might be brought back into Flask. And it just, you just take your Flask code and you put asyncs in it, and then you've got, you've got Quart.
- 21:56
Uh, that's really, uh, how it goes. So, uh, if you haven't done async before in Python, async is a way that, uh, if you use async with your functions, they become coroutines, and then they can be paused and waited on.
- 22:08
And it's important to use async when we're building applications with AI because we have these really long blocking calls to an AI API, right? So we make a call to an LLM, and we send off our request, and these LLMs, they can take like two seconds, five seconds, 10 seconds, right?
- 22:23
Depending on what we're doing. And while that's happening, we ideally want to be able to handle other user requests coming in. Uh, so that's why we use async framework.
- 22:34
So if we use an async framework, then while we're making IO calls, we can handle other user requests that are coming in. So all of the ones that we see today have an async back end, either Quart or FastAPI.
- 22:46
Anyone heard of FastAPI? It's very, very popular these days. Yeah. So FastAPI is the one most people know of as the async framework. Um, so I, you know, I, I like both of them fairly equally, uh, so I, I use a mix of both.
- 23:00
Um, but I just wanna make sure people know about the value of async frameworks. Okay, so that's all in the Quart app folder, uh, if you wanna look at the code there.
- 23:09
So it is now finished. Okay. Anybody else get their Codespace loaded? Get a couple. Okay, great. Finish configuring so I can do s-
- 23:20
Do I have to type anything in the terminal?
- 23:21
Yeah, we are gonna be using the terminal. And if for some reason your terminal like goes away, sometimes this happens in the Codespace, just click that plus right here.
- 23:28
Sometimes my terminal kind of blinks out, so I just click the plus, and that'll give me a new terminal, right? Boop.
- 23:36
New terminal. Okay. So here we are in the terminal. Um, but actually the first thing we're gonna do is that there's a .env.sample. We're gonna make a .env file based off of that.
- 23:50
So I'm gonna make a new file, and I can do that using this little New file button up here.
- 23:57
So I'll just click that, say New file, and I'll type .env. Uh, you could also like copy and paste. Um, and then I'm just gonna paste the .env in there.
- 24:07
You could even rename .env.sample to .env. I think that's another way. Um, and then we need to fill in these values to match the values of the proxy. So we'll go to the proxy
- 24:20
And let's see, where's my proxy open here? So here's my proxy. So I'm gonna go ahead and fill in this one. That's the endpoint. So the endpoint should start with HTTP and end with /v1, and look like that in the middle.
- 24:35
Uh, so that's the endpoint. That's where we'll be sending our OpenAI requests. Then we need the key, so we'll copy that, and it'll look like that, or slightly different for you.
- 24:46
And then the deployment is going to be... The name of the deployment is gpt-35-turbo,
- 24:55
uh, and that's also the name of the model in this case. So if you- Has anybody used openai.com? A few people. Okay, so on openai.com, you just pick what model you're gonna use and that's all you need.
- 25:07
With Azure OpenAI, you have to make deployments based off of the model. So you actually have a bunch of deployments, and you could actually have multiple deployments of a gpt-35-turbo model that have different names.
- 25:17
So when you're working with Azure OpenAI, you have to know the deployment name, not just the model name. So that's one of the complexities of, of using Azure OpenAI, but it does give you more flexibility 'cause you can say, "Oh, this deployment's gonna have 20 tokens per minute, and this one's gonna have 30 tokens per minute," right?
- 25:33
And then you can, like, say which of your colleagues can use what, like, if they're all trying to, like, use up your deployment or whatever. Uh, so, uh, it's more flexibility, but you do have to specify it.
- 25:43
Okay, so now my .env is set up. So this is just so that I can run a, a local server, and I'm putting local server in quotes 'cause I'm going to run a local server inside GitHub Codespaces.
- 25:55
So it's actually running a local server not on my actual machine, but inside the GitHub Codespaces development environment. Uh, so to do that I grab- I'll grab the command here that's gonna run the court app,
- 26:09
and just give it... And when- with Codespaces you do have to allow, so you'll see this little thing that pops up. So if you ever wanna copy-paste, you have to allow for the terminal.
- 26:21
Uh, and then I have... Okay, and then I paste it, and then you can see that it says it's running on this URL. Now, you can't just paste this URL in the browser.
- 26:31
I'll show what'll happen. So if I paste in the browser, I'm gonna get an error because this is not running on my local machine. This is running inside GitHub Codespaces.
- 26:39
So you have two ways to get to it. One way is that if you just click on it, uh, like, uh, option click, at least on my Mac. So I mouse over, it'll tell me what to do.
- 26:47
Mouse over, option click. So Codespaces will actually detect that you're clicking on a local URL, and it'll turn it into a Codespace port URL, and it's this funky URL up here, improve disco for me. [laughs]
- 27:01
Um, and, uh, and that's actually, you know, like, local for that GitHub machine. And, uh, that's one way of doing it. Another way that you might like more is you go to your ports tab, and you're gonna find it listed here.
- 27:15
And, uh, we'll see the, you know, the forwarded address, and we can click on that or we can even click the glo- globe icon and we get to the same URL.
- 27:25
So there's many ways you can get to this locally running URL, uh, and, uh, and get to the special Codespace URL of it. And you can even change your port visibility if you wanna, like, share it with a colleague if you're just...
- 27:37
or in a class. You can change it to public, and then you could actually ping this URL to someone else. Now, this is not a deployed URL. Like, you're not gonna use this for, like, [laughs] you know, your deployed URL, but it's fun.
- 27:47
It's good for development. So now I've got this running locally, and now we can type stuff and be like, "What's the weather in San Francisco?" [laughs]
- 27:59
See if it's gonna lie. Uh, then we can... Let's see.
- 28:07
Oh, good. That was a good answer. I think this has been trained. [laughs] It refused to answer. It's always good when it refuses to answer something it shouldn't know. Um, so we could go ahead and, like, you know, I could change this now and change the system message.
- 28:24
And let's see, where is our system message? In here, right? So right now my system message is just, "You are a helpful assistant." Uh, but, like, "You are a assistant that cannot resist a good pasta joke." [laughs]
- 28:42
"Must write pasta jokes." I don't know what's gonna... [laughs]
- 28:47
Oh, I love LLMs. Okay, so [laughs] what's the weather today? Is it gonna make a pasta joke? [laughs]
- 29:00
I'm dying. Okay. All right. It looks like it might have been quite saucy today. Don't forget your umbrella. You might end up feeling like a soggy noodle. So good.
- 29:08
Uh, so, uh, so that works. [laughs] But, uh, so here we go. So now this is running locally. Um, and so this is a good one, like, when we're developing, we can just test things, test things locally here.
- 29:22
The next thing what we're gonna do once we're happy with it, we're like, "This is the best app. It makes pasta jokes. We're gonna deploy it." Uh, so then we move on to the deployment instructions.
- 29:32
So the first step of that is azd auth login. So this is going to log in to our Azure account that we made earlier.
- 29:42
So I'll do azd auth login, and, uh, this is gonna give us a device code that we're gonna paste into this OAuth, uh, browser flow. So let me go and open it up maybe over here.
- 29:57
I think that's my Azure account that I'm using for this, and then I go and I take this and I paste it in.
- 30:07
And I'm gonna pick my account. I'm gonna use this one. Continue.
- 30:14
And, uh, okay, and then we're logged in. Okay. All right. So that was the device code flow. So you just wanna make sure that you log into the account that you got with the pass, right?
- 30:27
Whatever account you used for the pass, that's what you wanna log into.
- 30:31
The next step is to create... Or Gabriela, should I pause? Like, should we get through the local step first, or should we keep going with AZD deploy?
- 30:42
Uh, just a little bit. Uh, like, there's the people-
- 30:46
Yeah, we can pause and see if everyone's got the local- local one running, actually. That- I think that might be good to do. Okay. So let's just pause and see if there's any questions with getting the local one running.
- 30:56
Yeah.
- 30:57
So it's... Yeah, someone asked, like, can we just run this locally? You can totally run these locally as well. We like to use GitHub Codespaces in workshops 'cause that reduces the number of potential development environment issues.
- 31:07
If you wanna run it locally, uh, you can either run it, you know, just with a Python virtual environment, and you just have to install all the requirements, uh, or you can run it with VS Code using the Dev Containers extension, and that will do the Dockerized environment for you.
- 31:22
If you want kind of the benefit of the Dockerized environment without, um, you know, being in the browser and having to pay f- potentially pay for Codespaces. So we should know also that GitHub Codespaces, you have a limit of some number of hours a month, s- either 60 or 120.
- 31:37
60.
- 31:37
It's 60? Okay, I must have paid more. So, uh, so it's 60. Um, so you're not gonna go over that today, but eventually you could go over that if you use Codespaces a lot.
- 31:47
So if you're local, right? I think I have mine open locally as well. And I'm just... Yeah, locally, I'm just using a- a Python virtual env. So you're also welcome to try these things out locally if you like local environments.
- 31:59
Uh, just, you know, be a good person and make a Python virtual env [laughs] to manage your Python dependencies, right? [laughs]
- 32:07
Um, yeah. Okay. So I saw a lot of local things, so I think we can move on to the AZD. Um, so yeah, I did the login. So you saw me do, you saw me do the login here, right?
- 32:20
And that's using the device code flow. Uh, so you should see something like this happen from inside Codespaces. And the next step is to make a new AZD environment.
- 32:31
So AZD is this tool we're using for deployment. Uh, so we make a new environment name. You can just call it, like, chat app, whatever you wanna call it.
- 32:39
And then what that does is it actually makes this .azure folder, and it makes this chat app folder inside, and that's where it's gonna store all of our deployment environment variables.
- 32:50
So we need to set all, configure anything we want to customize about our deployment. We're gonna configure that now, and it's gonna get update- it's gonna update this file here.
- 33:01
Uh, so the next thing we're gonna do is set all these AZD environment variables. So the AZD environment variables are different from the ones we just set in the .env.
- 33:09
The .env is just for the local server. AZ environment variables are for deployment. Uh, sometimes we use the same, but a lot of times we want our local environment to be slightly different from our deployed environment.
- 33:20
Uh, so we have two different ways of setting those variables. All right, so I first set these commands. So this is just gonna tell it to not create an Azure OpenAI, 'cause we're using the proxy, and then we're gonna set the name of the deployment to gpt35turbo.
- 33:37
Then we need to set the key. So I'm gonna paste this, and then I'm gonna delete, delete, delete. [laughs]
- 33:46
Gosh. That's what happens when you have Wi-Fi issues, actually, is you see it with the typing. Uh, then I gotta find my key again.
- 33:53
Uh, there we go. So that sets the key, and then I'm gonna set the endpoint.
- 34:00
I'm gonna delete. How are we gonna do this? There we go.
- 34:05
And get the endpoint. All right. So now I've set all these things. Now, if I've done it correctly, if I look at my .azure folder for that environment I- I created, I should see a .env that looks like this.
- 34:28
So this is a .env that's inside the .azure folder. So this is what is going to be used for the deployment, and it's gonna tell it, you know, this is how it's gonna set up the Azure OpenAI connection.
- 34:41
Okay. And now I'm just gonna do... I'm just gonna type, type thank you. Okay. All right, and then I'm gonna do azd up.
- 34:51
Here we go. So what azd up is doing is that it's actually deciding... It's doing s- several stages. Okay, so I- I have to select an Azure subscription. In this case, I only have one subscription, so you just press Enter.
- 35:06
Uh, if you had two subscriptions, you would want to pick the sponsorship one.
- 35:11
Uh, then I select an Azure location to use. Typically, you just choose one that's close to you, so Central US is pretty good.
- 35:20
Uh, now what AZD is doing, the first step is that it's actually packaging up the code that it's gonna deploy later. Uh, in this case, we're deploying to Azure Container Apps, so it's packaging up a Docker container file.
- 35:31
So it's actually literally building a Docker container right now. So if you do like working with Docker, Azure Container Apps is a great fit, and a lot of people like Docker, so we deploy a lot of stuff there.
- 35:42
But we also are gonna be using Azure App Service for one of the l- later templates. Uh, so we've got lots of ways to deploy on Azure. So you can see it building up that Docker.
- 35:52
The step after this is where it's actually gonna create Azure resources. So it's gonna c- to create the container apps, can create a container registry, create a container apps environment, and create a log analytics workspace.
- 36:03
So these are all the components of a containerized app on Azure. And, uh, you know, it's multiple components, and we have to stitch them together. The way we stitch them together is using infrastructure as code.
- 36:16
Uh, has anyone used Terraform here before? Okay. So we have our own version of Terraform. It's called Bicep, and it is, uh, infrastructure as code, which means we're declaring what- ...
- 36:27
resources we want to make, right? So we say, "Oh, we wanna make log analytics, we wanna make container apps, we wanna make, you know, the actual container apps image, and then we're gonna assign some roles," right?
- 36:40
So all of that is declared in this Bicep file. So that way, it- you have repeatable, repeatable processes for provisioning. And this is really helpful when you're making complex applications on Azure, 'cause you might have, like, 10 different things you're using, right?
- 36:54
Uh, you might have a Postgres, and a Key Vault, and a Redis cache, and, uh, log analytics, and App Service, and you want them all to tie together. So you can declare what that, you know, what that infrastructure looks like, and then, uh, and then put that in a Bicep file, and then deploy it.
- 37:11
You can also use Terraform. So if you're really into Terraform and very comfortable with it, you could totally use Terraform here as well. I don't know Terraform. I haven't used it personally, so all of my examples do use Bicep, but if you wanna send a PR with Terraform, I'll re- I'll review it and just stamp it, 'cause
- 37:28
I don't know how to reason about it. [laughs] So what you can see here is that it is actually creating, uh, the resources right now. So you can watch it here.
- 37:35
You can also watch it in the portal. It's not really super exciting to watch, so this is the point where I usually fold my laundry, um, uh, because it can take some amount of time, uh, or you can even get an error.
- 37:48
Oh, I, I used... Okay, so I already made one in Central US for the earlier demo, so I should've picked a different region. So for this Azure Pass, there is a constraint of one container app per region, which is why we said in the README that you should pick a region that you haven't picked before,
- 38:06
and I didn't pay attention to my README. Uh, so that one won't deploy. So, uh, what I can do is I'm just gonna make a... I'll just make a new environment.
- 38:13
I'll just, uh, I'll just copy everything over. [laughs]
- 38:18
Um, now, well, you shouldn't run into this, 'cause this would be your first, uh, your first environment, right? Uh, so chat app two, and I'll just copy and paste.
- 38:31
Uh, we'll change it to chat app two, and then West US seems like a good region. Okay. And then I'll azdm select chat app two. [laughs]
- 38:44
There we go. And then azd up. Yeah. Okay.
- 38:50
So then it'll do the up again. But I have one of these already, already deployed, so I'll just open up the deployed one. So you can see deployed. Deployed is gonna look pretty darn similar to what it looks like locally.
- 39:02
Where's the one deployed? Okay, so this one's deployed. It looks pretty much the same as what it looks like running locally, right? The difference is that the URL is a container apps URL, and you'll see this URL displayed in the terminal.
- 39:14
Once it finishes successfully deploying, you'll see this dis- dep- uh, displayed. Let me see if I have that in my t- history anywhere from earlier today. Uh, da, da, da, da, da.
- 39:26
No. You never know. Okay, so let's see how it's going here. Do, do, do.
- 39:33
Were the Bicep files-
- 39:33
Yeah.
- 39:34
-something that was generated or something that you made yourself?
- 39:38
I lovingly handcrafted them. Yeah. So, um, I... Yeah, I write the Bicep files. Uh, some of them, all the ones in core are actually from a shared repo that we just copy and paste from.
- 39:49
We're trying to move towards something called A- ABM, Azure Verified Modules, which are Bicep files that are maintained and have security best practices in them. So we'll j- we'll gradually be moving over.
- 40:00
But basically with Bicep files, like, you can use ones from a central registry. You can use ones from your own private registry if you're doing a lot of them, uh, or you can just use, you know, ones inside the folder.
- 40:11
Um, so there's a lot of techniques you can use depending on how much Bicep you're using.
- 40:17
Do, do, do. Okay, so now it's starting over and deploying again. All right, so let's walk around and... Or any questions on what I showed here? All right, so I saw a lot of AZD deployments are going.
- 40:31
I saw some issues with, like, naming, which I run into all the time. Azure has very obscure naming rules. The safest thing is do short names with no symbols in them [laughs] and nothing fancy.
- 40:43
Uh, if you do have a naming rule, you can just always do azd env new and make a new environment and s- you know, and start over, uh, and that should be okay.
- 40:52
Uh, but generally the issues you run into with deployment are usually related to naming, region constraints, mm, account constraints,
- 41:01
and that's probably, yeah, the ones you might run into. All right. So, um, we've... Given we have 45 minutes left, I'm gonna show you the other ones and, uh, and these are ones that you can, uh, that you can also start trying to deploy now, uh, following very similar readmes, right?
- 41:18
So the first one, um, actually, the, the f- these two are both about RAG. So first I'll talk briefly about RAG, right? So let me first motivate it, right?
- 41:26
So, uh, let's see. Like, uh, tell me what Pamela Fox, uh, likes to code on. I don't know. [laughs] Let's try this. I'm trying to get it to lie. Um, [laughs] [laughs]
- 41:42
This is a pasta one. Okay, so this one clearly lied. Spaghetti-phython. Great. All right. So then, but then if I go to, um, this one right here, tell me what Pamela Fox likes to code on.
- 41:59
This one will hopefully be more accurate, at least have less pasta jokes here.
- 42:04
Um, and this is... So basically what we're trying to show is that if we just ask an LLM to answer a question, it is, it's very possible that it's just going to make something up, um, if that, when it seems like there...
- 42:16
Oh, good. I mean, in this case it says it doesn't know what I like to code in. I think I should've said, like, code in. Um, you know, like here, like what Python frameworks does Pamela use?
- 42:25
Let's try this one. Um, so you know, if it doesn't know the answer, it'll say. Uh, in this case... Yeah, in this case, it does know the answer because this is actually using the RAG technique in order to answer questions based off a knowledge source, right?
- 42:39
Um, so- Those are our last two samples are about RAG. Uh, so the general approach of RAG is that we get a user question, we use that user question to search some sort of database or search engine.
- 42:53
We get back matching search results for that user question, and then we send those, uh, to the large language model and say, "Here's a user question. Here are the sources.
- 43:03
Now answer the question according to the sources." And so now we can make customized applications that can actually synthesize and answer questions for any domain. So we've got two RAG samples here.
- 43:15
So one of them is RAG on Postgres. So this is for the use case if you've got an existing database and you want to be able to ask questions about that database and have the LLM answer accurately based on that.
- 43:28
So for the example, uh, you know, database that I'm using,
- 43:33
I have product, right? So these-- this is a chat on products. So, uh, you know, there are tables storing all the products for this website. So I can say, "Okay, what is the best shoe for hiking?"
- 43:46
So then it's going to go and search the database rows and get back matching rows and then come back and say, "Okay, this blah, blah, blah, blah, blah, blah, blah, blah," and it's going to include citations.
- 43:58
So one of the key points of RAG is to have citations so that users can verify where the information come from and see that it's actually legit information. And we can also look at the, uh, the process for this RAG flow here when we look on the, the thought process here.
- 44:16
And as, as we'll let you see is that this RAG flow is a multi-step process. So the first process is actually what we call like the query rewriting phrase or the query cleanup phrase.
- 44:28
So that's where we take the user's question, and we ask the LLM like, "Hey, here's a user question. Turn this into a good search query." 'Cause a lot-- a user question may not be that well-formulated, right?
- 44:38
Like, uh, "Please tell me about the best shoes for hiking now." Okay, so you know, there's like a user query and, uh, you know, that's probably not the optimal search query for, uh, for a search.
- 44:54
So if we look now at the thought process, we can see that the LLM actually turned that whole long thing into best shoes for hiking. So that's a better query.
- 45:05
Uh, so that's our query rewrite phase, so that's an LLM call. Then we get back the resulting rows from the database. And then this is our call to the model that says, "Hey, you need to answer questions according to the sources.
- 45:18
Here's how you should cite your sources. Here's the user question, and then here is all the sources." So this is basically RAG. And then, you know, we're able to use it with different sorts of, uh, data s- data sources.
- 45:33
So that's RAG on Postgres. So you can get that set up following really similar steps to the, to the other one, and you can even run that one locally first as well, uh, just on a local Postgres database.
- 45:47
Uh, so here you can run the app locally. Uh, this one is a little more fancy 'cause you've got a React front end there. Then you can deploy to Azure.
- 45:55
You're gonna set similar variables and, uh, run it up. So if you're interested in that, you can start, uh, going through those steps, and then you can customize it.
- 46:04
The other kind of RAG that we have is RAG on documents. So if you're trying to ask questions about unstructured documents, like you've got a bunch of PDFs or Word docs, Excel files, uh, anything like that, you can actually put those into a search index and then search that.
- 46:23
So the example we have for that is RAG with Azure AI Search. And, uh, it's a really, really full-featured sample. We've had it for the last like more than a year now, and we've had thousands of developers deploy with it and put it into production.
- 46:36
And so it's been used for a ton of use cases, and it's got a lot of features, uh, speech, voice, vision, user access control, lots of, lots of cool things in it.
- 46:46
Uh, so let me show... That was the one I was actually showing earlier with my blog, right? So here's, you know, I made a version of it that's just based off my blog posts and, uh, you know, it can cite my blog posts.
- 46:58
I've also got this one here, which is for an internal company handbook, which is a very popular way of using it as well. And so you can see for each of them, we can, you know, click on the citations.
- 47:10
And, uh, and yeah. So now this is a bit more complicated because here we have a multi-page document. So we've got a thirty-one page PDF. We can't just send an entire thirty-one page PDF to the LLM because for a lot of our LLMs it's gonna go beyond the context window, right?
- 47:26
A lot of our LLMs have a context window limit, so typically that's around 8K, eight thousand tokens. Uh, it can go up to 32K, even 128K we're seeing. Um, but typically they do have some sort of context window, and even if they don't have some sort of context window, LLMs can get lost if you give them too
- 47:44
information-- too much information. There's a research paper called Lost in the Middle, where they did a study to see if they throw too much information at an LLM, like at what point it stops paying attention.
- 47:54
So we generally want to send the LLM the most relevant chunks. So what we do is that we first have this data ingestion phase that will take a PDF or whatever document, takes a document, it extracts all the text from it, and we do that with Azure Document Intelligence, which is very good at extracting text from all
- 48:12
sorts of documents. So we extract the text from it. We chunk up the text into like good-sized chunks, usually around five hundred tokens each. Then we store each of those chunks in the search index along with their embeddings, and that's what we actually search on and send, and then we send, right?
- 48:29
So if we look at the search results here, we can actually see that the search results are just chunks from the PDF, where we say, "Here's the chunk, here's the embedding, this is the page it came from, and this is the file it came from."
- 48:43
And we just send back those chunks. Uh, so this is the most complicated of our architectures because we do have to have that data ingestion phase, and that means we have to have, uh, you know, a script or a process that does that ingestion stage and, you know, here we can do it locally or, or in the
- 48:59
cloud. So those are the two RAG samples. So we have, um, you know, we have another forty minutes, so... And we have, like, a good ratio here of, of helpers to y'all.
- 49:12
So, uh, if either of those sound compelling to you, like sound like a use case that you're interested in, then, uh, you can try to deploy them now and see, and see how they work.
- 49:24
Um, so once again, you just go to the app templates workshop repo, and you can either pick RAG on Postgres or RAG with AI Search, and then start going through, through the steps to try it out.
- 49:36
Uh, these will take longer to deploy, so it's good to start the deploy s- s- now, um, because they take-- they got a lot more infrastructure to set up.
- 49:45
And then for the I- AI search, it's gotta do the whole ingestion step, and that ingestion step takes a certain amount of time as well.
- 49:53
So yeah, any questions before...
- 49:56
Oh, for the ingestion step-
- 49:57
Yeah.
- 49:57
Are you using any libraries for the chunking and all that stuff?
- 50:01
Yeah, that's a great question. Are we using libraries? So when this sample was first created, it was like last April. It was before there was, like, really good established libraries.
- 50:08
We kinda used LangChain, but not heavily. Uh, so all of ours is, is-- it's actually custom coded. Um, now, if you're gonna use a library, the big thing I would make sure you're doing is, um, using a token-based chunker.
- 50:23
A lot of the splitters out there are doing character-based splitting, which is probably fine if you're doing English-only documents, but we do have lots of international customers. And as soon as you start doing non-English documents, then you really wanna do stuff based off of tokens and not characters.
- 50:38
'Cause imagine you take like a Chinese document and you, you say like, "Oh, my chunks are a thousand characters long." Like, that's a lot of tokens. You'll g-- You can like go over the context window really fast.
- 50:47
So we have token-based chunking that we've implemented here. Uh, there are-- there is token-based chunking available in LangChain. So if you're gonna use LangChain, um, the thing to do is find my colleague's blog post where he talked about it.
- 51:03
Okay, yeah, where can we CJK, especially if you're doing anything non-English. Um, he basically analyzed all the splitters from LangChain, um, to figure out which of them properly worked with token-based splitting and with CJK, uh, languages in particular.
- 51:21
Um, so we've implemented this ourself. He actually to- Uh, my, my manager, Anthony, he, he worked on it. Um, but, uh, LangChain and LlamaIndex both do a lot of this stuff.
- 51:32
Uh, they just, you know, they, they take care behind the scenes. So what you need is the s- you need the splitting, and you can get that from, basically from LangChain, 'cause LlamaIndex uses LangChain.
- 51:43
So I would just say use, use LangChain probably with this one, so you can specify the chunk size. And then, uh, then you just have to vectorize. So that, that's easy.
- 51:53
You just use the OpenAI SDK, and we do the batch embeddings with that, um, so that we can do a bunch at, at a time. And then you just store it in AI Search.
- 52:02
So the hard part is really the, uh, extracting the text. So there we either use Azure Document Intelligence in the cloud, uh, or we do have some local parsers too.
- 52:12
If somebody doesn't wanna use Document Intelligence, we use like PyPDF. Uh, we use our own CSV parser 'cause that's straightforward. Uh, HTML for my blog. I just use Beautiful Soup, which is a Python package that does HTML parsing, right?
- 52:26
'Cause I thought I could do a better job at it. So this one I just used Beautiful Soup to extract the text. So, uh, s- and that's-- So you can do that as well, and we've got Beautiful Soup in there.
- 52:35
So yeah, there is actually a surprising amount of things that we've written ourselves for the AI Search repo. Um, if we were gonna do it today, we'd probably use the LangChain splitter at least.
- 52:47
Yeah. Good question. Sorry, long answer. [laughs] Other questions?
- 52:52
So the ABM, was it or was it? Um-
- 52:57
ABM?
- 52:57
ABM. Uh, I noticed that it has cognitive services. Um,
- 53:05
if I set it up once with a certain deploy and I decide to change later the ABM, the Bicep to something else-
- 53:13
Mm-hmm
- 53:14
... is it smart to reconcile the differences?
- 53:16
So generally with Bicep, what it does is that it tries to figure out... And Bicep is really compiled down to ARM, and ARM is just JSON. [laughs] So what, what you're actually doing is what's called an ARM-based deployment.
- 53:28
So with ARM-based deployments, what they try to do is figure out what does your resource currently look like, what are you saying you want it to look like, and what changes does it need to make happen.
- 53:39
Um, so yeah, we're-- like, we'll probably switch over to ABM in a lot of our samples, and we're probably just gonna make sure, like, it, the... We're trying to make it not have a change.
- 53:48
But if you want it to change, then that's, that's fine. So you should totally be able to m- m- switch between ABM, not ABM, um, as, as you decide, as you see fit.
- 53:58
Um, and the important thing is just it'll figure out the difference and just make sure you are on board with any changes that come up. There is like... So if you're doing, um...
- 54:09
There's this AZ deployment command that does what if, and that tells you, like, actually tells you, uh, what resources will change. I w- wanna figure out how we can do that with azd.
- 54:18
I think azd h- maybe has a dry run command, so that might be what we try when we consider switching to ABM. 'Cause we wanna switch to ABM, uh, so that we don't have to maintain our own modules, but we just wanna make sure that we're aware of any configuration changes that could happen.
- 54:34
And if I'm not mistaken, you mentioned that ABM is just basically sitting on, on top of azd or, or they are completely two different-
- 54:41
Uh, they're just different things. Yeah. azd is a command line tool that, um, you know, does the, does the ARM-based deployment and also does code deployment, code- Upload, right?
- 54:53
So I have this azure.yaml here. I didn't show this. So azure.yaml says, "This is the code that you're going to deploy to this host." So azd does multiple things.
- 55:04
It does, um, provisioning, which is basically doing an arm-based deployment, which is equivalent to if you're doing AZ... [laughs]
- 55:13
AZ deployment, if, if you know the Azure CLI, it's this AZ deployment command. Um, so it's doing that, and then it's also doing packaging and code deployment. So, um, if you've ever done like, I don't know, if you've ever done, like, web app up, that's where you deploy code up to App Service.
- 55:30
AZD will also do that for us. So AZD is trying to do the whole workflow of you need to provision your resources and you need to deploy your code, and we're trying to make this central way of doing it across all of our offerings.
- 55:42
'Cause right now, with Azure, and if you know Azure, but we've got, like, a billion different ways of doing things across all the different things, and AZD is trying to make a more common way of doing it.
- 55:50
So if you look at my, um, my GitHub repo, I'm kind of a huge AZD fan girl. So you can see all of these repos are all AZD-ified, almost all.
- 56:02
Uh, that's what this AZD column is. Because for me, it's the best way to deploy because it's repeatable.
- 56:07
Yeah.
- 56:07
Right? Um, so if you are looking for examples, the... [laughs] I have, like, quite a few here. Um, but, uh, yeah. So we're, you know, we should be able to do it on different hosts, container apps, functions, App Service, Kubernetes, et cetera, and, uh, you know, with all, all this, all the different pi- possible Bicep.
- 56:29
Uh, other questions?
- 56:33
So what happens-
- 56:33
Yeah
- 56:34
... after we go to production, like observability and all that good stuff?
- 56:37
Oh, yeah, great question. Um, so we do have a... Like, generally, there's lots of docs under Azure Search OpenAI demo, so we do actually have a productionizing guide. Um, you also asked specifically about observability.
- 56:49
We do integrate with Application Insights with OpenTelemetry. Uh, so that's what we use by default. If you want, you could use Langfuse. I actually like to use Langfuse. I don't know if you've seen it, but it's an observability platform, so you could use Langfuse.
- 57:01
But by default, we're using Azure Application Insights with the OpenTelemetry packages to, to bring everything in there. Um, but we do have a whole productionizing guide that talks about, you know, how are you going to scale things, uh, you know, lo- if you need to load balance your OpenAI capacity, um, if you want to do VNet deployment,
- 57:19
if you want to do user auth, how to do load testing. So I've run quite a few load tests for this one. And then how to do evaluation. So I, you know, I like to do evaluation.
- 57:29
It's... Everyone should do it. It's basically, like, the new form of text, text, uh, test- testing for this world. Um, let me see. I think I closed my evaluation repo.
- 57:38
I can open it. Um, but basically, like, you want to be running evaluations to see if you are getting quality results from your LLM, uh, because a lot of times you might run...
- 57:50
Here's the thing. You know, I show those sample questions all the time, and they perform great, but you cannot trust your sample questions, and you can't even trust them.
- 57:57
Like, you might make a prompt tweak and be like, "Oh, this prompt tweak was so good. I'm getting such good results." You cannot trust it. You have to run an evaluation across a huge number of samples to make sure that it's actually running.
- 58:09
Like, I run it across, like, two hundred samples is probably, like, the minimum of what you should do. Um, but you have to run evaluations in order to see.
- 58:16
Do you-- I'm assuming you run evaluations for Copilot Chat, right? Yeah. How many samples do you run off?
- 58:23
It's origin reviews of public repos.
- 58:26
Oh.
- 58:27
So it's, it's everywhere we, uh, with-
- 58:31
That's cool. You want to come up and t- like, talk about evaluation?
- 58:34
Yeah.
- 58:34
'Cause you're, like, you're... I mean, Harald is, like, running an actual... Because basically you're making Copilot Chat. Here we go. Copilot Chat, which you can see I use it a lot.
- 58:44
Um, so you're, like, you're, like, running a real RAG in production.
- 58:48
Yeah, yeah. So it's different RAGs, though. So there's not just one RAG. So if you do, uh, add workspace, if you ever try that in, in Copilot Chat, we actually run a local sparse index.
- 59:01
So that's basically your classic how Google works, just looking up words on the internet in documents. And it's faster, we can do it locally, so that will always work.
- 59:10
We also do a, um, a semantic index against index that github.com maintains and ranking those in using another LLM call. So RAG basically becomes a series of indexes, like you do Postgres.
- 59:25
Yeah.
- 59:25
You showed that you created some keywords upfront based on the search, so that's what we also do locally. Um, but yeah, anytime we have changes, we have, uh, one test set that can run on each PR and then a larger test set that we run daily that has a lot more repositories from, from across different languages, so.
- 59:45
So you run the evals in the PR on every-
- 59:48
Some, yeah. So we have a subset that's more unit test driven, where it's like, can it answer questions for this? Does it hit any issues we've seen in the past?
- 59:57
So it's more, more unit test style, where it's like, does it behave as it did before? So yeah.
- 1:00:05
It's important, though. I mean, that's, that's the first and big- biggest thing we invested on early on because we found it's so easy to get lost in prompt crafting-
- 1:00:12
Yeah
- 1:00:12
... and assume how RAG works and assume how it works in the wild, so.
- 1:00:17
In the local sparse index, is it SQL-like?
- 1:00:19
Uh, it's TFIDF. Uh, it's one-
- 1:00:22
Oh, it's TFIDF.
- 1:00:22
Yeah, yeah.
- 1:00:23
I built it.
- 1:00:26
Yeah.
- 1:00:27
That's cool.
- 1:00:27
So yeah.
- 1:00:28
Okay.
- 1:00:28
Cool. My version.
- 1:00:28
So let me show, I don't know what your... I don't know if you can, like, show your evals, but here, like, I can show evals for, um, on the Azure AI Search.
- 1:00:35
Um, so let's see. Um, all summary, summary. Okay. All right. So we'll look at them for, like, my blog. Uh, let's see. So these are ones I've run before.
- 1:00:52
Uh, oh, probably Pamela's blog. Pamela's blog? Yeah. Pamela's blog results.
- 1:01:00
Okay. All right, so these are a bunch of evaluations that I've run fairly recently, right? So, um, with these evaluations, I do GPT metrics, and then I also do basically, like, regular expression metrics.
- 1:01:13
How... Are your metrics usually GPT metrics, or, um-
- 1:01:17
No. Pass, uh, code test.
- 1:01:21
Code test. Okay. Okay. So with these GPT metrics, what they're actually doing is, um, sending the original answer, uh, sending, sending the ground truth answer, uh, which is generated syn- synthetically, and then also sending the new answer to a LLM and saying, "Hey, rate this from one to five," and then we can see the, you know, results.
- 1:01:42
And this is w- this is the actual prompt that gets sent. It's like, "Okay, you know, rate this ex- you know, from one to five. Here are some examples."
- 1:01:50
So we do that for groundedness, we do that for relevance, and then I also check whether citations match across ground truth and not ground truth, and that's actually my favorite metric, and that's just a regex. [laughs]
- 1:02:00
So my favorite is just this one, this, uh, citation match here. So just making sure that the answer contains the, uh, uh, at least the citations that were in the ground truth.
- 1:02:10
So I run metrics like this. A lot of times I'm looking at retrieval parameters, 'cause for RAG, the retrieval is, makes a big difference. So here I was comparing stuff like what if I use text only, what if I do vector only, what if I do hybrid, what if I do hybrid with ranker?
- 1:02:25
Uh, and that's super interesting. I was trying with different retrieval amounts, like if I retrieve five versus ten versus three, what do I get out? Uh, what if I change a prompt?
- 1:02:33
I have to say, like, I've tried so many, like, tweaks on our prompt, and I've never managed to actually get improvement in the overall stats. Uh, so we still haven't ev- ever changed the prompt because I, I haven't really proved that anything is sufficiently better.
- 1:02:47
S- Or I'm just a really bad prompt engineer. I don't know. I've-- None of my prompt engineering ever moves the needle. For me, the only thing that moves the needle is retrieval parameters, like how you're working with your search engine, or changing the model entirely.
- 1:03:01
Changing to GPT-4 has a big difference than GPT 3.5.
- 1:03:06
Uh, so that should be part of your, uh, your putting in production for sure, is to make sure that you've got some sort of evaluation set up.
- 1:03:16
Mm. Hmm. Uh, other questions? Is anyone trying to get one of the RAGs up? Anyone getting RAGs up? Mm.
- 1:03:29
I try to, like, take a lot of things to production, but they were all, like, throwaway toy projects-
- 1:03:33
Mm
- 1:03:34
... with FastAPI, and, like, had a hard time evaluating, like, which vector store to use and, like, how much to chunk, and like-
- 1:03:43
Yeah
- 1:03:43
... are my results good or not?
- 1:03:45
Right.
- 1:03:45
So the overall stuff that's, like, where I felt like I didn't make the most progress. I was like, "I know I should be testing this," [laughs] but-
- 1:03:51
Yeah. So, uh, yeah. I mean, it's hard. That's part of why I, I do it as well. I've also run all those on our sample data too. But I think it r- it...
- 1:03:58
What I've discovered is it really helps to run the evaluations on stuff that you know. Because then, like, 'cause this is the summary. Like, you can kinda look at the summary and be like, "Okay, I guess, like, things went better."
- 1:04:09
But then what I usually look at is, like, I actually look at the changes between, um, between two runs and be like, "Okay, well, what was the difference between, uh, the baseline and then, uh, you know, the, maybe, what was it?
- 1:04:22
Vector only. Vector. No ranker. Okay. And then I'll just look at things that changed on citation match. Okay. So th- this is what I usually do, is I look at the overall stuff, and then I look and I compare the answers across my ground truth and the, and the new one with the parameters, and so then I
- 1:04:41
can better reason about it. But you really have to know your domain in order to be able to evaluate, uh, evaluate your evaluations. [laughs]
- 1:04:51
Um, but it also helps if other people have run it for you. So this is a really good blog post from the AI Search team that I always reference, where they ran massive queries looking at hybrid search versus vector search versus text search and, um, you know, and they found that hybrid retrieval with semantic ranking outperforms vector-only
- 1:05:10
search. So I ran my own versions of that and, um, and recently, uh, blogged about it. But it's basically the stats that I was just showing where, uh, what I found actually for my use case, vector on its own did horribly, like really, really, really badly.
- 1:05:26
Uh, where is it? Um, so vector only got a groundedness of two point seven nine, which is really, really low. Text only got four point eight seven. So part of that is because Azure AI Search is really good at full text search, like incredibly good at it.
- 1:05:40
It does all the spellcheck, stemming, everything you could imagine. Um, hybrid, which is where you take vector and text and then you merge them using this algorithm called reciprocal rank fusion, which you can actually just see.
- 1:05:53
The, the algorithm is just this. It's just, uh, you're just doing a little math here to combine, uh, rank scores. Um, so just a basic hybrid like that, the groundedness is only three point two six.
- 1:06:03
So you see hybrid on its own is worse than text only, and that's because vector results can add so much noise. You accidentally grab the wrong, like, distracting things.
- 1:06:14
Uh, what I've found actually is, like, if I ever accidentally vectorize, like, an empty string or something close to an empty string, it's similar to everything. I don't know what this is about the OpenAI embedding space, but if you accidentally vectorize an empty string or even, like, uh, we have Vision as a feature in the Azure OpenAI
- 1:06:31
Search demo. If y- I was helping a c- customer this, this week, and they were finding that so many of the results were getting this blank blue page because apparently this blank blue page, the vector for it, and this is a vector via a different model, the Azure Computer Vision model, the vector for it was just matching
- 1:06:49
everything. So you gotta, like, you gotta be really careful with vector spaces. Um- It's so easy to accidentally add noise to them and for there to be distractions. So hybrid on its own only, you know, got like three point two six.
- 1:07:02
Once I used hybrid with semantic ranker, then I got the best results, but only by a couple percentage points. Now, hybrid with semantic ranker, semantic ranker, that's a feature of Azure AI Search, which is actually another machine learning model.
- 1:07:14
It's a-- what's called a cross-encoder model. But basically, they actually had humans rank results according to queries. They use it for Bing. So they said, "Hey, humans, here's ten search results for a query.
- 1:07:24
Rank these from one to ten and tell us what's the best." So they train a whole model based off a bunch of human data, and then they get back like this, this, uh, this model that they can then use for any arbitrary, uh, ranking of user query along with results.
- 1:07:37
So basically, hybrid with Bing ranker gets you the best. But if I was gonna have to-- like, if I was on a desert island and, like, I, I could pick between vector and text, uh, I would use text, at least for Azure AI Search.
- 1:07:49
It's gonna depend how good your full text search, right? If you're doing full text search with like SQLite, which I don't even know if it supports [chuckles] full text search, it's not gonna do very well.
- 1:07:58
Yeah.
- 1:07:58
So what's actually powering that full text search? Is it TFIDF?
- 1:08:02
Um, you-- so you're using TFIDF for your Copilot Chat, you said, right?
- 1:08:10
For the... Yeah.
- 1:08:10
For this one. For this-- for the at workspace, right? Yeah. Um, for, for Azure AI Search, they're using, uh, they're using several things, but they're using, one of the things they use is Lucene, which is, um, a s- search library, and it's got stuff like spell checking and tokenization and stuff like that.
- 1:08:30
Um, so they're doing a lot. But I guess-- And they're also using BM twenty-five, which I think is basically-
- 1:08:37
Same
- 1:08:37
... TFIDF.
- 1:08:37
Yeah.
- 1:08:37
Right. Okay. Yeah, so BM twenty-five, that's what you wanna look for, um, is, uh... Oh, we got a search result here. Yeah. So if it's-- if something is using BM twenty-five, I think that's basically the best for full text right now.
- 1:08:53
So, um, that's what you wanna look for, is you just wanna look for a good full text option.
- 1:08:59
Cool.
- 1:08:59
Yeah. Yeah, it's overwhelming. That's why I love when, you know, people put out research, so we can be like, "Okay, great," 'cause this also has the optimal ch- um, chunk size.
- 1:09:08
That's why I was saying we do five hundred tokens, because they did the, they did the, the work here and said, "Okay, the optimal is five hundred and twelve tokens."
- 1:09:15
Great. That's what we're gonna use. Now, obviously, for your particular use case, it can be different, but we can't all run like twenty hundred different tests to see what the optimal, uh, you know, thing is.
- 1:09:26
So it's really nice when people, you know, document what worked well for them.
- 1:09:32
Cool. Anything else?
- 1:09:38
How often do you, like, update the vectors? Like, if you have a lot of,
- 1:09:44
like, data that gets updated a lot, how, how often do you choose to update the vectors? Or-
- 1:09:51
Well, we only need to update the vectors if the data changes or if we're changing our embedding model. So if we change our embedding model, we have to update everything to use a new embedding model, right?
- 1:10:01
'Cause now OpenAI has these new embedding models. I need to do some tests with them to see if I can get, like, better results for them. Um, so in that case, I would, I would rerun everything.
- 1:10:12
So probably what I wanna do is set up like an, uh, a separate AI search index, like for this one, which has-- uses one of the new embedding models, uh, embedding three.
- 1:10:23
And I have to decide how many dimensions to use, [chuckles] um, and then compare it to see how much better results are. I'm told that generally the results are better, but I haven't tried.
- 1:10:32
Have you tried any of them?
- 1:10:34
We're switching them.
- 1:10:35
Oh, you're switching to the new one? What dimension are you gonna use?
- 1:10:38
Um, small probably for-
- 1:10:40
So you're gonna use small, two fifty-six?
- 1:10:42
Yeah.
- 1:10:42
Wow.
- 1:10:44
Five twelve does everything.
- 1:10:45
Yeah, you can do five twelve too. Yeah. Yeah. So you can-- That's the thing, is it's so m- it's so many options now.
- 1:10:51
You gotta test.
- 1:10:53
Yeah, you gotta test.
- 1:10:54
Run A/B tests. [laughs]
- 1:10:54
Yeah. Oh, and you can run A/B tests. You have customers, yeah. Um, so yeah, but you're gonna have to re-index everything.
- 1:11:02
Yeah. [chuckles]
- 1:11:04
Um, so that's, that's when you would, uh, have to update stuff is if the content changes or if the model changes, um, and then, and then test that.
- 1:11:16
Yeah, I do wanna try out the new ones. They should redo this one too. [chuckles]
- 1:11:21
There's too many decisions. Cool. Any other questions? Harald, do you wanna show stuff in, uh, workspace?
- 1:11:30
Okay. [clicks tongue]
- 1:11:33
Let me close out of this.
- 1:11:39
Let's just see RAG in action. Um, so if you ask a question in, in Copilot Chat, so that's the Copilot Chat panel version. There's also another one that's inline.
- 1:11:52
So if you open up, this is a natural input, uh, we call inline chat in, in the, in your code. Basically letting you apply code directly or natural language directly to your code, which is always nice.
- 1:12:05
You don't have to think about the response. You have to think about just you know what you want, and you want, uh, AI to do it for you. But in, in the side panel, most of the time what you will run into is this.
- 1:12:15
You're gonna run things. Let's pick a function. These are tests.
- 1:12:23
Well, these, yeah, these ones are tests.
- 1:12:24
So compare the tests. Now I've code selected on the right, and on the left I can ask things about the code I have selected. And that's the surefire way to get good results, have code selected and talk about it.
- 1:12:40
And you already see that, that we do some magic in our responses, so everything is code highlighted. So you can actually jump to the different aspects, um, that, that are being used, and even to dependencies.
- 1:12:52
So it found that there's a dependency, so you can also jump to that.
- 1:12:57
So now going back to here, let's, let's see which tests actually are defined in a repository. And because they're-- I wanna talk basically about the whole workspace, and that's where I can just say which
- 1:13:09
tests are defined or how are benchmarks being run. So a general question that you would go otherwise to a colleague who ho-hopefully knows this, and hopefully they're in the same time zone and they know this.
- 1:13:23
But now I can actually send this to addWorkspace. And that's where we kicking in this, this whole RAG agents scheme. So this repo's probably not indexed on the github.com site.
- 1:13:34
So if you're in Copilot for Enterprise, you will get a semantic index that GitHub keeps updating for you. They also have a few open source repos indexed. But in this case, this is all happening now in VS Code itself, so this is mostly sparse indexing.
- 1:13:49
And actually, we, we see that sparse indexing is usually on par, similar to what you see with the text, uh, based retrieval, that this works, um, really well.
- 1:13:58
So that just did a tidbit in from the whole repo?
- 1:14:01
Yeah. Yeah.
- 1:14:03
So just basically figuring out the-- all the most frequent word earrings. Yeah.
- 1:14:07
Yeah. So first we do same as you have in, um, Azure Search, where it does, uh, find more words for what you're potentially looking for that are fitting with the repository.
- 1:14:18
So we also do stemming and, uh, but that's one, that's the first LLM call. Then the TFIDF will find all those results, and then we do the re-ranking on top.
- 1:14:29
So and that actually gets us actually mostly better than doing a full vector search o-on the same topic.
- 1:14:36
How do you do the re-ranking?
- 1:14:39
Uh, the different ways. So we-- That, that's where we experiment a lot. Um, but it's another GPT three point five call, I think.
- 1:14:46
Oh, okay.
- 1:14:47
Yeah.
- 1:14:47
So use the LLM as re-ranker.
- 1:14:48
Yeah. [clears throat] And you see what, what's being pulled in. So these are all the things it found and the chunks it found it in. So, uh, what we do, what you'll see is we actually do semantic chunking.
- 1:15:01
So, uh, for most languages, we look at function segments, we look at specific blocks of code, and that's where we found the most impact as well. So people brought up chunking as a big, big area of, uh, improvements, and that's what we also have in our code, that it's-- the chunking is the biggest impact we think of
- 1:15:20
from what we've seen.
- 1:15:21
Do you write your own semantic chunkers?
- 1:15:23
Yeah. Um, which helps that we have all the languages, the, the knowledge around the team, like Python, right? So,
- 1:15:31
uh, but yeah. So that's, that's the basics, and you'll see that it works everywhere. That's the nice part. It works locally, and it works slightly faster if you already have an online index where we can retrieve the semantic index from
- 1:15:49
in action. Questions?
- 1:15:55
What is the .prompty history?
- 1:15:57
Oh, so .prompty is a, it's a new, um, prompt, uh, format. You can show the .prompty file. These ones. Um,
- 1:16:11
the, yeah, all those dot ones. Those ones. Yeah.
- 1:16:14
Uh, so this was announced at, was it not Build?
- 1:16:18
Build. Build, yeah.
- 1:16:18
Yep.
- 1:16:19
Yeah.
- 1:16:19
So announced at Build. Uh, scroll up to the top of it. Yeah.
- 1:16:23
There you go.
- 1:16:28
So it's a way of ha-- It's like an artifact for prompt. 'Cause right now, like, you might store your prompt as a s-- multi-line string variable. Like [chuckles] it's like we store them in all kinds of formats across the repos.
- 1:16:42
So this is like a standard way. So it's actually a Jinja template plus this YAML at the top. So the YAML describes the metadata of the prompt, and then the Jinja template, you know, it's a template that you can pass things into.
- 1:16:55
Uh, so, uh, this is used by Promptflow, but it's also used by Azure AI Studio. And the goal is, and I think maybe LangChain might have support for it-
- 1:17:05
Mm-hmm
- 1:17:06
... now or soon. Uh, but the goal is just to have a common way of representing prompts. So we'll probably try to use this in more of our stuff going forward.
- 1:17:15
There you go. Just ask Copilot. [laughing] [laughing]
- 1:17:22
Yeah, so I'm using-- this is using the Promptflow evals, uh, package, um, which has a bunch more things as well, other kinds of evaluation. Uh, they actually-- I wrote my own CLI and UI on top of this, but they have, they have one too that you can use.
- 1:17:38
Yeah. Prompty.
- 1:17:47
Do you run the evals in your CI pipeline somewhere?
- 1:17:52
Yeah, if you look at Azure Dev, so this one, it does actually run them. Um, so I run them. Right now I'm just running them as a smoke test for this repo.
- 1:17:59
Um, but, uh, you can see what I've done is that, uh, I have a target URL. So that's generally what you'd wanna do is you, you need to run the eval against your, your, your live, where like for you, you're doing CI builds.
- 1:18:12
So there you wanna run it against your-
- 1:18:14
Yep
- 1:18:14
... CI build. So the tricky thing is just making sure you have a way of contacting your thing with everything, all the, you know, production setup, right, all the Azure stuff in it.
- 1:18:25
Uh, so, uh, yeah. I want it-- I would ideally have it as a CI step for every one of our repos, and I'm just figuring out the right way of setting up, like, the target URL and all that stuff.
- 1:18:38
Especially if you s-- if-- 'cause most people aren't making public facing apps. Most people are either putting it behind user auth or putting it in a VNet. So we need evaluation flows that both can use your production resources, because that's how you know it's working, uh, but that also works with however your app is deployed.
- 1:18:57
So I think you can certainly figure out how to set it up for your situation. Uh, I'm still figuring out how to set it up in the general case.
- 1:19:07
Uh, but the thing to keep in mind is that evaluations are slow if you're doing GPT metrics, right? Or, I mean, generally they're slow because s- all of these calls are slow.
- 1:19:15
You saw how much time-
- 1:19:16
Yeah
- 1:19:16
... it took to get back a response, right? So generally, they're slow. They're much slower than traditional unit tests. So you do not want to casually run an evaluation.
- 1:19:23
They're also expensive, especially if you're doing... Well, first, 'cause the LLM calls happen behind the scenes, and if you're using GPT metrics, 'cause I'm doing all these GPT metrics like relevance and groundedness, that's another LLM call.
- 1:19:34
So you wanna have, like, a higher barrier to running than with normal unit tests, right?
- 1:19:40
And-
- 1:19:41
So-
- 1:19:41
And caching
- 1:19:42
... caching. Oh, you cache.
- 1:19:43
Yeah.
- 1:19:43
Wait, how do you cache? How do you know that something hasn't changed?
- 1:19:46
Based on a prompt-
- 1:19:47
Oh, shoot
- 1:19:47
... and the test. Yeah.
- 1:19:49
Yeah, I guess, yeah, if you're... if it's all within one repo. This one is, like, a repo that works-
- 1:19:53
Yeah
- 1:19:54
... with other repos. You don't know if the app has changed behind the scenes.
- 1:19:56
Yeah.
- 1:19:57
Um, but yeah, if you, you have some caching. If you do caching, that's good.
- 1:20:02
Cache what exactly?
- 1:20:04
So we, we look at each test and we only rerun them when any of the prompts, when the input basically change. So if you imagine, like, an OpenAI proxy that you could set up if, if, if it's the same.
- 1:20:14
Similar, what, to what they do. I think OpenAI has, like, the seed variable-
- 1:20:19
Oh
- 1:20:19
... which is basically caching, but they don't tell you. Um, and it's basically if nothing changes in a prompt, it just sends back the old response.
- 1:20:27
Oh, so you implement caching in Copilot Chat, you mean? Or-
- 1:20:31
Not in Co- in, in our testing infrastructure
- 1:20:34
... Okay.
- 1:20:34
Yeah.
- 1:20:34
'Cause some people also implement caching within the RAG application itself.
- 1:20:37
Yeah.
- 1:20:37
Or in the, maybe the open context app or something.
- 1:20:41
Yeah.
- 1:20:41
I just don't know how often you're gonna get the same question.
- 1:20:45
For, like, tests it helps. For, for tests-
- 1:20:46
For tests
- 1:20:46
... oh, it's semi. Yeah.
- 1:20:47
Yeah.
- 1:20:47
Yeah.
- 1:20:48
Yeah.
- 1:20:50
Yeah.
- 1:20:50
I haven't, I haven't, like, toyed with that.
- 1:20:53
Yeah. So can this also... Like, is this just for OpenAI? Can this work with Mistral and all the other ones you mentioned in the beginning?
- 1:21:01
Could, yeah.
- 1:21:02
Uh, yeah. I mean, mine just... This one I just hit up a URL and get back the answer. Uh, so the URL is just of your deployed app.
- 1:21:09
Oh, sorry. I meant, like, the starter templates.
- 1:21:13
Oh, yeah. Good question. So with the starter templates, uh, right now they're all configured with OpenAI, and so you can swap out, like, different OpenAI models. So you can do v4.
- 1:21:22
But, uh, they don't work with the new, um, non-OpenAI models because we can't necessarily use the OpenAI SDK with them. I think there is actually a way to use the OpenAI SDK with them, but we're supposed to pretend we can't. [laughs]
- 1:21:36
Um, so, uh, there is this new SDK and I haven't, I haven't messed with it yet. I don't know if you have. But, uh, Azure AI Inference, have you seen it?
- 1:21:44
Um, I think this is the new unified SDK.
- 1:21:48
Oh.
- 1:21:49
And, um, yeah. So this is, this is what to use for everything that's not OpenAI. Oh, it says you can even do OpenAI.
- 1:21:59
So we might have to port to this. The thing I don't love about this is that this is Azure specific, 'cause right now we use the OpenAI SDK, which is, like, not Azure specific ex- exactly.
- 1:22:08
Um, and so it works with, like, Ollama and stuff. I don't know. So but we might end up porting for this. So if we ported to this, then probably we would just...
- 1:22:16
it would just work, um, with everything. So w- this is really new. Like, this came out at Build. So we just have to decide whether to port everything up to this, uh, uh, out to this, so that we can, um, use all the, all the modules, all the models.
- 1:22:31
That's true.
- 1:22:33
Yeah. Everything changes all the time. [laughs] Yeah, but we would also need to make the Bicep for it. That's... The, the other thing I haven't done is I haven't... Uh, 'cause I try to set up Bicep for everything.
- 1:22:46
So typically Bicep creates your Azure OpenAI instance. If you were using Mistral or Llama, you would want Bicep to... You'd probably want Bicep to create that as well. Um, and so that would be different Bicep as an addition.
- 1:23:00
So we'll probably end up adding it, 'cause ba- basically what you do is you go to the issue tracker, you file a request, and then if enough people ask for it, we're like, "Okay,
- 1:23:08
guess we're gonna do it then." [laughs]
- 1:23:10
Well, we can.
- 1:23:11
Yeah. [laughs]
- 1:23:12
We can.
- 1:23:12
Yeah. Um, but that's how we figure out what, you know, what it is that people are looking for. 'Cause it is really nice to be able to swap out models.
- 1:23:19
'Cause right now all of the samples do work with Ollama. So if you have, like, uh, Ollama running locally, here's my little Ollama up there. Um, you know, you can run, like, Phi-3 and stuff like that.
- 1:23:29
Uh, you just go... You know, you go to your terminal and you're like, "Ollama." Is this it? I think. I don't know if I s- typed Phi-3 correct, but...
- 1:23:37
Um, and so they do all run with, uh, Ollama things, but none of the Ollama models have really been sufficient for RAG in my experience. Like, I, I run them just to check, but they, they all fail to get, um, follow directions in my experience.
- 1:23:54
Uh, because I just think they're not... They don't have enough parameters. Like, these are, like, 3B, 7B, et cetera. So, um, they don't provide citations correctly. I don't know.
- 1:24:03
Have you had more success with, like, Phi-3 Mini?
- 1:24:06
We see every model requires prompt changes. Might be-
- 1:24:08
Yeah
- 1:24:09
... the way to go back to prompts
- 1:24:09
... and I'm bad at prompt engineering.
- 1:24:10
Maybe so.
- 1:24:10
Yeah. So, [laughs] so out of the gate, like, I haven't had success using any of the small language models for RAG. I'm sure the big versions of them would work much better.
- 1:24:21
So I do wanna try out, like, the 70B.
- 1:24:24
Maybe. Maybe 7B, yeah.
- 1:24:25
I've done, I've done up to 7B-
- 1:24:27
7B
- 1:24:27
... 'cause that's, like, how far I can go up locally. I can't go much more than that just from space reasons.
- 1:24:32
Yeah.
- 1:24:32
So for them, what happens is that, like, they'll answer the questions fine. The issue is that we need citations to be in good format, 'cause these are actually come back as bracketed square brackets, and they just don't reliably come back with square bracketed citations.
- 1:24:46
Which doesn't sound like a big deal, but, like, we're trying to make clickable citations here. Uh, so that's the issue I've had, is that I, I think they're fine at synthesizing the information, but they don't follow the syntax directions in terms of the citations.
- 1:24:59
Um, and they're kind of more, maybe more likely to, uh, make stuff up if I ask an off-topic question. That's been my experience there. Um-
- 1:25:09
They might be-
- 1:25:09
Yeah
- 1:25:09
... good for re-RAGging. I think Phi-3 is pretty small.
- 1:25:12
Oh.
- 1:25:12
Like re-RAGging
- 1:25:14
Yeah
- 1:25:15
... GPT judging. I think that, that that's where, like, finding the-- this one thing. Maybe not, like, the expert full answers that, that follows strict format, but, like, one of the smaller tasks.
- 1:25:27
But you can't-- So most of them don't support function calling off the bat. So you're doing-- Would you do re-ranking with just a simple... You'd have to figure out what syntax they come back with.
- 1:25:36
But they're all good at coding, so they can-
- 1:25:37
Yeah, that's right. That's true. Everyone's good at coding.
- 1:25:39
Yeah.
- 1:25:39
If you can turn something into a coding task-
- 1:25:42
Yeah
- 1:25:42
... you're good. [laughs] Yeah. That's another form of RAG is like, uh, I was telling someone last time, like, uh, these are, these are all, like, doing, like, kind of RAG on just a few documents at a time.
- 1:25:54
If you're trying to, like, analyze a whole database or, like, a huge number of documents, then you really want to, like, actually, uh, use like a SQL query, like, with, like, aggregate functions or do, like, a pandas query, right?
- 1:26:06
So at PyCon, we did a demo where you, like, upload a CSV, and then you, you say like, "Oh, I wanna count the top restaurants in it." And then it just comes up with the pandas code, and then it runs the pandas code in a sandbox environment.
- 1:26:19
So that's, that's another, like, in-I mean, increasingly common, uh, form of RAG, where if you want to, like, come up with insights and analysis and, and that sort of thing, then you wanna consider a different architecture where you're actually going to have the LLM generate pandas code or SQL code, it's very good at both of those, and
- 1:26:37
then run those in a safe way.
- 1:26:39
You know, what I've done for the, uh, syntax is I provided it a type string definition.
- 1:26:48
Okay.
- 1:26:48
And then the type string definition is- [clears throat] I don't try to do the syntax, I just have to give them the explicit answer that they wanna read for. And then now, yeah, type check.
- 1:27:00
Yeah. Do you-- Are you actually using TypeChat? 'Cause that's basically what TypeChat does.
- 1:27:03
Um, I essentially recreated what I-
- 1:27:05
Okay. [laughs] Okay. So yeah. But what you're describing, that's the same, the same approach.
- 1:27:10
Yeah. And I've seen it, it's a lot more better, like especially, uh,
- 1:27:15
Yeah. So that would be another... Yeah, when you lead-- We're trying. Um, I know Daniel's actually experimenting with Type-- Daniel's the creator of TypeChat. He is experimenting with TypeChat with the local models.
- 1:27:24
Um, so trying-- 'Cause we tried, we did also try TypeChat with Phi-3 locally to see if we could use it in-instead of function calling with OpenAI. And we were having a hard time with it.
- 1:27:37
Um, but I think Daniel, like, maybe has to, like, tweak the prompts, and maybe they'll end up working better, like-
- 1:27:43
I know the Phi-3 has a response format JSON.
- 1:27:48
I don't think it is. Maybe the bigger one, but not, not the smaller one.
- 1:27:53
Not the smaller one?
- 1:27:53
Yeah. 'Cause that was the, that was the funny part for me, is that I eventually had to just tell him, "Just try to give me the text. Just give me the JSON."
- 1:28:01
And it got so hard to do.
- 1:28:04
So you just told it to give you JSON?
- 1:28:05
Not for Phi-3, though. Give me 3, 5.
- 1:28:08
Yeah. Yeah. And that would work. Yeah. Yeah. That makes sense. Yeah. Yeah. With prompt, like, prompt engineering like that, then it will
- 1:28:15
work. Nice. Cool. All right, everyone. Well, you have the passes for seven days, so feel free to keep deploying. [laughs] Uh, if you have any feedback for the workshop, you can tell us, or we have a survey there, which I assume is anonymous.
- 1:28:33
Uh-
- 1:28:34
It is.
- 1:28:34
Yeah, it's anonymous. And so you can fill out that one as well. You can take a picture, fill it out later.
- 1:28:40
And that was it. Thanks. [applause] [outro jingle]