Content Developer II at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
121348 stories
·
30 followers

Announcing Fluid Framework 2.0 Preview

1 Share

We are excited to announce the release of Fluid Framework 2.0 Preview. This release includes several improvements over our Beta release back in January and gets us closer to general availability this summer.

A diagram of a diagram Description automatically generated with medium confidence

SharedTree updates

The new SharedTree Distributed Data Structure (DDS) provides an intuitive programming interface for working with data and supports a broad range of data types including primitives, objects, arrays, and maps. Since the Beta release, we have continued to make improvements to SharedTree.

Undo/Redo – Added the ability to listen for changes and track revertible objects on your undo/redo stacks. Revertibles allow you to undo and redo changes even if other changes have been made in remote clients.

Transactions – You can group multiple changes such that they are applied atomically, and if they fail, they fail atomically. As a result of grouping changes in a transaction, you also get a single revertible object making it easier to undo and redo.

Events – We have updated the Events to make it easier to create granular event listeners for single nodes and better support the undo/redo feature.

Schema improvements – Schemas are even more powerful now with the added support for recursive types, which allows you to define types that reference nodes of the same type in their subtree.

Other improvements

We have also continued to make improvements to other parts of the release including:

Fluid Developer Tools (DevTools) – Fluid DevTools is a browser extension that improves the developer experience when writing and debugging Fluid applications. We have made improvements to the usability of the DevTools including visualization of data stored in SharedTree and Ops latency telemetry visualization. Learn more about Fluid DevTools here.

Typed telemetry support – Before deploying your application at scale, it is critical to have the holistic telemetry in place to monitor its usage and look for issues and optimizations. To make this easier, we are providing a fluid-telemetry package that comes with Typed telemetry events that you can funnel to your any analytics tool of your choice. If you decide to use Azure App Insights to view this data, we also provide helper packages and dashboard queries to get you started quickly. Learn more about the telemetry packages here.

We have also added more samples and documentation to help you start building with SharePoint Embedded.

You can find the full list of updates in the release notes.

Start building today

Fluid Framework 2.0 is now available in Preview, with general availability (GA) planned for this summer. The preview release is close to a GA release so you can start developing new apps and test updating the existing 1.x Fluid apps with it. We recommend starting deployments once the stable GA version is released later this summer. You can learn more about release types and API guarantees here.

Visit the following resources to learn more:

Follow us on X (Twitter) / @Microsoft365Dev, LinkedIn, and subscribe to our YouTube channel to stay up to date on the latest developer news and announcements.

The post Announcing Fluid Framework 2.0 Preview appeared first on Microsoft 365 Developer Blog.

Read the whole story
alvinashcraft
10 minutes ago
reply
West Grove, PA
Share this story
Delete

Python Tutorial: Use TensorFlow to Generate Predictive Text

1 Share
Stylized woman reading a book.

Predictive text is something we use every day. We use it when we send text messages, emails and anywhere else you might write. It has become so commonplace that it’s an expected feature across most platforms. Given its ubiquity, I was curious to see how hard it was to create my own predictive text model. I wasn’t expecting it to be perfect, as not even the top predictive text models are, but I thought it would be a fun project to learn more about machine learning and natural language processing.

The tutorial will show you how to make a simple text-based prediction model based off of Jane Austen’s “Pride and Prejudice.” Due to the training data being based on a romantic novel, I was expecting that the resulting predictive text would be very skewed towards the themes of love and marriage. We’ll test this theory at the end.

The interface for this will be an API. It will take prediction queries and return the three most likely words to come afterward. We’ll deploy the API to the cloud so that it can be used as a third-party API in other applications, like a chat app or anywhere else you might want to embed predictive text. If you want to skip to the end and deploy it yourself, you can find the full source code in our examples repo.

Python will be the base language because the machine learning (ML) ecosystem around Python is fantastic, enabling us to use tools like TensorFlow, Keras and NumPy. TensorFlow acts as a kind of ML toolbox. There are plenty of options, but we should use the right tool for the job.

Using a bidirectional long short-term memory recurrent neural network (Bi-LSTM) is ideal for our predictive text problem. This type of neural network, apart from having a very long name, also has the unique capability to store both long- and short-term context. We’ll need short-term memory to store the previous words in the sentence and long-term memory to store the context of how these words have been used in previous sentences.

Step 1 – Set up the Project

We’ll use the following tools:

  • Pipenv for simplified dependency management
  • The Nitric CLI for simple cloud backend infrastructure
  • (optional) Your choice of an AWS, Google Cloud Platform (GCP) or Microsoft Azure account.

Start by creating a new project for our API.

nitricnewprediction-apipython-starter

Then open the project in your editor of choice and resolve dependencies using Pipenv.

pipenvinstall--dev

Step 2 – Prepare the Data Set

Project Gutenberg provides the “Pride and Prejudice” text, so you can download the file from there, or you can use the precleaned data from our example repo, which is the recommended approach. This text file will form the basis of our training data and will give our predictions a Jane Austen spin.

Before we begin training our model, we want to make sure we explore and preprocess the training data to clean it up for quality training. Looking through the “Pride and Prejudice” text, we find that Project Gutenberg adds a header and a footer to the data. There are also volume headers, chapter headings, punctuation and contractions that we’ll remove. We’ll also convert all the numbers to words — “8” to “eight.” This cleanup allows our training data to be as versatile as possible, so predictions will be more cohesive.

Now that we have our cleaned data, we’ll tokenize the data so it can be processed by the model. To tokenize the data, we’ll use Keras’ preprocessing module, so we’ll need to install the Keras module.

pipenvinstallkeras==2.15.0

We can then create and fit the tokenizer to the text. We’ll initialize the Out of Vocabulary (OOV) token as <oov>. After it’s fit to the text, we’ll save it so we can use it later.

Now we’re ready to start training our model.

Step 3 – Train the Model

To train the model, we’ll use a Bi-LSTM. This type of recurrent neural network is ideal for this problem since it enables the neural network to store the context of the previous words in the sentence.

Start by loading the tokenizer we created in the preprocessing stage.

We’ll then create the input sequences to train our model. This works by getting every six-word combination in the text. First, add NumPy as a dependency.

pipenvinstallnumpy

Then we’ll write the function to create the input sequences from the data.

We’ll then split the input sequences into labels, training and testing data.

The next part is fitting, compiling and training the model. We’ll pass in the training data, which we have split into training and testing data. We can use the model checkpoint callback, which will save the best iteration of our model at each epoch. To optimize our training speed, we’ll also add an adaptive moment estimation (ADAM) optimizer and a reduce learning rate on plateau callback.

Then we’ll add layers to the sequential model.

Finally, we can put it all together and then compile the model using the training data.

With all the services defined, we can train our model with the cleaned data.

The model checkpoint save callback will save the model as model.keras. We’ll then be able to load the model when we create our API.

Step 4 – Write the Text Prediction Function

We’re ready to start predicting text. Starting with the hello.py file, we’ll first write functions to load the model and tokenizer.

We will then write a function to predict the next three most likely words. This uses the tokenizer to create the same token list that was used to train the model. We can then get a prediction of all the most likely words, which we’ll reduce down to three. We’ll then get the actual word from the map of tokens by finding the word in the dictionary. The tokenizer word index is in the form { "word": token_num }, such as { "the": 1, "and": 2 }. The predictions we receive will be an array of the token numbers.

Step 5 – Create the API

Using the predictive text function, we can create our API. I will be using the Nitric framework for this, as it makes deploying our API very straightforward and gives us the choice of which cloud we want to use at the end.

First, we will import the necessary modules for the Nitric SDK.

We’ll then define the API and our first route.

Within this function block, we want to define the code that will be run on a request. We’ll accept the prompt to predict from via the query parameters. This will mean that requests are in the form: /predictions?prompt=.

Now that we have extracted the prompt from the user, we can pass this into the model for prediction. This will produce the three most likely next words and return them to the user.

That’s all there is to it. To test the function locally, we’ll start the Nitric server.

nitricstart

You can then make a request to the API using any HTTP client. Given the prompt “What should I”, it returns the most likely responses: “have”, “think” and “say”.

You will find that the predictions have a lot of focus on family and weddings. This shows that the training data, courtesy of Jane Austen, has a big effect on the type of predictions that are produced. You can see these themes in the below examples where we start with a two-word sentence and see what the predictive text produces.

Step 6 – Deploy to the Cloud

You can deploy to your cloud to enable use of the API by other projects. First, set up your credentials and any other cloud-specific configuration:

Create your stack. This is an environment configuration file for the cloud provider where your project will be deployed. For this project, I used Google Cloud; however, it will work perfectly well if you prefer AWS or Azure.

nitricstacknew

This project will run as expected with a default memory configuration of 512MB. However, to get instant predictions, we’ll amend the memory to be 1GB. This just means adding some config to the newly created stack file.

You can then deploy using the following command:

nitricup

When deployment is finished, you’ll get an endpoint so you can test your API in the cloud.

If you’re just testing for now, you can tear down the stack with the following command:

nitricdown

If you want to learn more about using Nitric to quickly deploy Python and other language applications to your cloud, check out the session that Anmol Krishan Sachdeva and Kingsley Madikaegbu of Google are leading at Open Source Summit North America: “Thinking Beyond IaC: an OSS Approach to Cloud Agnostic Infra. Management Using Infra. from Code (IfC).”

The post Python Tutorial: Use TensorFlow to Generate Predictive Text appeared first on The New Stack.

Read the whole story
alvinashcraft
10 minutes ago
reply
West Grove, PA
Share this story
Delete

Top 5 Underutilized JavaScript Features

1 Share
Developer

JavaScript is an essential programming language, but often its capabilities are left under-explored. JS possesses a range of features that can be applied to a countless number of use cases, helping developers create efficient, reusable, and adaptable code.

In this article, we will explore the top five under-utilized JavaScript features and their use cases. We will also provide code examples to show how JS can be used for nearly everything, from solving date management issues to chaining functions, and even detecting malicious websites.

1. JavaScript Hooking to Detect Malicious Websites

One nifty JS feature is the use of hooks as an effective method of telling if a website is fake or not, all without any particular OpSec or cybersecurity knowledge in general.

Hooks are JS functions that allow a developer to “hook into” state and lifecycle features from the highly popular UI development library, React. This means developers can use React without having to write individual classes.

In the following example, we will focus on web pages that are built using static and dynamic components. Static components are always declared as part of the HTML source code and rendered by the browser or its installed plugins. Meanwhile, dynamic components include scripts like JS which modify HTML documents by adding, changing, or removing certain elements, as well as utilizing XMLHttpRequest and similar objects for server interaction.

How It Works

An exploit kit (a toolkit used by cybercriminals) and malicious websites or web applications typically rely on obfuscation to bypass signature-based protection methods. JS can be used to deobfuscate websites, modifying the code and its elements so it can be read and processed by the browser.

Exploit kits often contain very large chunks of code to hide the exploit and confuse web browsers. Once decoded by JS, new page elements are added — such as new DIV elements, new JS elements, and new Java applet elements that load the exploit.

This means JS hooks can be applied to script functions during the deobfuscation process, issuing alerts if anything unusual is detected, such as the addition of potentially malicious Java applet elements.

To do this, we must first focus on hooking the primary methods of adding elements: appendChild, replaceChild, and document.write. The fourth method is slightly more challenging; so instead, the focus should be to hook specific functions such as document.getElementById(), or document.createElement(). Objects can then be added to the MutationObserver object, or we can use Mutation Events and monitor for any changes.

Below is an example of a function that registers hooks:

function jsh_hook_function(object, property, pre_h_func, post_h_func) {
    const original = object[property];
    object[property] = function(...args) {
        if (pre_h_func) {
            pre_h_func.apply(this, args);
        }

        const result = original.apply(this, args);

        if (post_h_func) {
            post_h_func.apply(this, [args, result]);
        }

        return result;
    };
}

2. Generate Reports in Node.js

Reporting and documentation are key elements of a robust cybersecurity strategy, but it can be a tedious and time-consuming process — especially when it comes to more sensitive information, such as pentesting reports, vulnerability assessments and anything else security-related. Jsreport is a specialized reporting platform that has been developed in the open source JavaScript runtime environment, Node.js. The platform has a range of use cases, including HTML to PDF conversion.

Using just the Chrome browser, you simply need to install the jsreport npm package and call a single function. As well as HTML, the platform can convert all kinds of mediums, making it possible to generate DOCX files as PDFs with JS alone or even entire spreadsheets, formulas included. This means data can be kept on a single platform and converted into reports without third-party tools — ideal for cybersecurity documentation and exporting pentesting reports so that testing, analysis, and data storage are all centralized.

Jsreport is not Google Chrome specific and is compatible with a range of services and technologies to print output. This includes Apache FOP to render XML files.

How It Works

Install jsreport npm and call one function:

const http = require('http');
const jsreport = require('jsreport');

http.createServer(async (req, res) => {
  try {
    const result = await jsreport.render({
      template: {
        content: '<h1>Hello world</h1>',
        engine: 'handlebars',
        recipe: 'chrome-pdf'
      }
    });

    res.setHeader('Content-Type', 'application/pdf');
    result.stream.pipe(res);
  } catch (e) {
    res.writeHead(500, { 'Content-Type': 'text/plain' });
    res.end(`Error generating PDF: ${e.message}`);
  }
}).listen(1337, '127.0.0.1');

3. Control Execution Flow with Generators

Generators are a type of function that can be paused and resumed, helping developers maintain more control over the flow of execution. Generators can be used for backtracking algorithms, infinite sequences, and asynchronous operations; plus they also allow customer iteration patterns to be created.

It’s a powerful and versatile JavaScript feature that is often under-utilized, with many software developers missing out on the ability to have maximum control over code execution.

How It Works

Here is a simple code example:

function* generatorFunction() {
  yield 'Hello';
  yield 'World';
}

const generator = generatorFunction();
console.log(generator.next().value); // Output: Hello
console.log(generator.next().value); // Output: World


To specify a generator function, first the generatorFunction should be defined using the function* syntax, Then the yield keyword is used to pause the execution of the function and to return a value. Next, the generator object is created by calling the generatorFunction, followed by calling the next method on the generator to resume the execution. The value property of the returned object also contains the yielded value.

4. Improved Date Management with Temporal

Over the years, many developers have complained about poor date management features in JavaScript. Fortunately, Temporal has provided a native solution, offering a standard global object to replace the date object to solve a range of issues. For example, one perplexing problem was poor indexing with months starting at zero, while days started at 1.

Supporting multiple time zones and non-Gregorian calendars, Temporal is an out-of-the-box solution that has an easy-to-use API that simplifies parsing dates from strings. The immutable nature (i.e. cannot be changed) of Temporal objects also means that dates will be immune from bugs that cause unexpected modifications.

How It Works

Here are several Temporal methods that devs can utilize:

a) PlainDate() – Create a date with no time.

new Temporal.PlainDate(2024, 7, 26);
Temporal.PlainDate.from('2024-07-26');
// both return a PlainDate object that represents 26th July 2024


b) PlainTime () – Create a time with no date.

new Temporal.PlainTime(20, 24, 0);
Temporal.PlainTime.from('20:24:00');
// both return a PlainTime object of 20:24


c) PlainMonthDay () – Creates a month and day but does not assign a year. A useful function for days that recur on the same date every year, such as Valentine’s Day.

const valentinesDay = Temporal.PlainMonthDay.from({ month: 2, day: 14 });

5. Create Reusable Code with High-Order Functions

In JavaScript, functions are the priority, which allows high-order functions to be created to establish a code hierarchy. High-order functions turn one or multiple functions into arguments or they can be used to return another function. This provides a range of capabilities such as composition, currying, and function chainings — ultimately helping developers create streamlined, modular code that can be easily reused on other projects.

How It Works

Let’s consider function chaining as an example. In this instance, the object is a calculator, and using function chaining there are many ways to alter its internal state and return each modified state seamlessly.

const calculator = {
  value: 0,
  add(num) {
    this.value += num;
    return this;
  },
  subtract(num) {
    this.value -= num;
    return this;
  },
  multiply(num) {
    this.value *= num;
    return this;
  },
  getValue() {
    return this.value;
  },
};

const result = calculator.add(5).subtract(2).multiply(3).getValue();
console.log(result); // Output: 9

The post Top 5 Underutilized JavaScript Features appeared first on The New Stack.

Read the whole story
alvinashcraft
11 minutes ago
reply
West Grove, PA
Share this story
Delete

.NET 9 Preview 3: 'I've Been Waiting 9 Years for This API!'

1 Share
Microsoft's third preview of .NET 9 sees a lot of minor tweaks and fixes with no earth-shaking new functionality, but little things can be important to individual developers.
Read the whole story
alvinashcraft
11 minutes ago
reply
West Grove, PA
Share this story
Delete

Advanced RAG with Azure AI Search and LlamaIndex

1 Share

BuildAppswithAdvancedRAG.png

 

We’re excited to share a new collaboration between Azure AI Search and LlamaIndex, enabling developers to build better applications with advanced retrieval-augmented generation (RAG) using a comprehensive RAG framework and state-of-the-art retrieval system.

 

RAG is a popular way to incorporate company information into Large Language Model (LLM)-based applications. With RAG, AI applications access the latest information in near-real time, and teams can maintain control over their data. 

 

In RAG, there are various stages that you can evaluate and modify to improve your results, they fall into three categories: pre-retrieval, retrieval, and post-retrieval.

  • Pre-retrieval enhances the quality of data retrieved using techniques such as query rewriting.
  • Retrieval improves results using advanced techniques such as hybrid search and semantic ranking.
  • Post-retrieval focuses on optimizing retrieved information and enhancing prompts.

 

LlamaIndex provides a comprehensive framework and ecosystem for both beginner and experienced developers to build LLM applications over their data sources.

 

Azure AI Search is an information retrieval platform with cutting-edge search technology and seamless platform integrations, built for high performance Generative AI applications at any scale.

 

In this post, we will focus on the pre-retrieval and retrieval stages. We will show you how to use LlamaIndex in pre-retrieval for query transformations and use Azure AI Search for advanced retrieval techniques.

 

AdvancedRAG.png

Figure 1: Pre-retrieval, retrieval, and post-retrieval in advanced RAG

 

Pre-retrieval Techniques and Optimizing Query Orchestration

To optimize pre-retrieval, LlamaIndex offers query transformations, a powerful feature that refines user input. Some query transformation techniques include:

  • Routing: keep the query unchanged, but identify the relevant subset of tools that the query applies to. Output those tools as the relevant choices.
  • Query rewriting: keep the tools unchanged, but rewrite the query in a variety of different ways to execute against the same tools.
  • Sub-questions: decompose the query into multiple sub-questions over different tools, identified by their metadata.
  • ReAct agent tool picking: given the initial query, identify (1) the tool to pick, and (2) the query to execute on the tool.

 

Take query rewriting as an example: query rewriting uses the LLM to reformulate your initial query into many forms. This allows developers to explore diverse aspects of the data, resulting in more nuanced and accurate responses. By doing query rewriting, developers can generate multiple queries for ensemble retrieval and fusion retrieval, leading to higher quality retrieved results. Leveraging Azure OpenAI, an initial query can be decomposed into multiple sub-queries.

 

Consider this initial query:

“What happened to the author?”

 

If the question is overly broad or it seems unlikely to find a direct comparison within our corpus text, it is advisable to break down the question into multiple sub-queries.

 

Sub-queries:

  1. “What is the latest book written by the author?”
  2. “Has the author won any literary awards?”
  3. “Are there any upcoming events or interviews with the author?”
  4. “What is the author’s background and writing style?”
  5. “Are there any controversies or scandals surrounding the authors?”

 

Sub Question Query Engine

One of the great things about LlamaIndex is that advanced retrieval strategies like this are built-in to the framework. For example, the sub-queries above can be handled in a single step using the Sub Question Query Engine, which does the work of decomposing the question into simpler questions and then combining the answers into a single response for you.

 

 

response = query_engine.query("What happened to the author?")

 

 

 

Retrieval with Azure AI Search

To enhance retrieval, Azure AI Search offers hybrid search and semantic ranking. Hybrid search  performs both keyword and vector retrieval and applies a fusion step (Reciprocal Rank Fusion (RRF)) to select the best results from each technique.

 

Semantic ranker adds a secondary ranking over an initial BM25-ranked or RRF-ranked result. This secondary ranking uses multi-lingual, deep learning models to promote the most semantically relevant results.

 

Semantic ranker can easily be enabled by updating the “query_type” parameter to “semantic.” Since semantic ranking is done within Azure AI Search stack, our data shows that semantic ranker coupled with hybrid search is the most effective approach for improved relevance out of the box.

In addition, Azure AI Search supports filters in vector queries. You can set a filter mode to apply filters before or after vector query execution:

  • Pre-filter mode: apply filters before query execution, reducing the search surface area over which the vector search algorithm looks for similar content. Pre-filtering is generally slower than post-filtering but favors recall and precision.
  • Post-filter mode: apply filters after query execution, narrowing the search results. Post-filtering favors speed over selection.

 

We are excited to be collaborating with LlamaIndex to offer easier ways to optimize pre-retrieval and retrieval to implement advanced RAG. Running advanced RAG doesn’t stop at pre-retrieval and retrieval optimization, we are just getting started! Stay tuned for future approaches we are exploring together.

 

Get Started and Next Steps

 

Examples

Setup Azure OpenAI

 

 

aoai_api_key = "YourAzureOpenAIAPIKey" aoai_endpoint = "YourAzureOpenAIEndpoint" aoai_api_version = "2023-05-15" llm = AzureOpenAI( model="YourAzureOpenAICompletionModelName", deployment_name="YourAzureOpenAICompletionDeploymentName", api_key=aoai_api_key, azure_endpoint=aoai_endpoint, api_version=aoai_api_version, ) # You need to deploy your own embedding model as well as your own chat completion model embed_model = AzureOpenAIEmbedding( model="YourAzureOpenAIEmbeddingModelName", deployment_name="YourAzureOpenAIEmbeddingDeploymentName", api_key=aoai_api_key, azure_endpoint=aoai_endpoint, api_version=aoai_api_version, )

 

 

 

Setup Azure AI Search

 

 

search_service_api_key = "YourAzureSearchServiceAdminKey" search_service_endpoint = "YourAzureSearchServiceEndpoint" search_service_api_version = "2023-11-01" credential = AzureKeyCredential(search_service_api_key) # Index name to use index_name = "llamaindex-vector-demo" # Use index client to demonstrate creating an index index_client = SearchIndexClient( endpoint=search_service_endpoint, credential=credential, ) # Use search client to demonstration using existing index search_client = SearchClient( endpoint=search_service_endpoint, index_name=index_name, credential=credential, )

 

 

 

Create a new index

 

 

metadata_fields = { "author": "author", "theme": ("topic", MetadataIndexFieldType.STRING), "director": "director", } vector_store = AzureAISearchVectorStore( search_or_index_client=index_client, filterable_metadata_field_keys=metadata_fields, index_name=index_name, index_management=IndexManagement.CREATE_IF_NOT_EXISTS, id_field_key="id", chunk_field_key="chunk", embedding_field_key="embedding", embedding_dimensionality=1536, metadata_string_field_key="metadata", doc_id_field_key="doc_id", language_analyzer="en.lucene", vector_algorithm_type="exhaustiveKnn",

 

 

 

Load documents

 

 

documents = SimpleDirectoryReader("../data/paul_graham/").load_data() storage_context = StorageContext.from_defaults(vector_store=vector_store) Settings.llm = llm Settings.embed_model = embed_model index = VectorStoreIndex.from_documents( documents, storage_context=storage_context )

 

 

 

Vector search

 

 

from llama_index.core.vector_stores.types import VectorStoreQueryMode default_retriever = index.as_retriever( vector_store_query_mode=VectorStoreQueryMode.DEFAULT ) response = default_retriever.retrieve("What is inception about?") # Loop through each NodeWithScore in the response for node_with_score in response: node = node_with_score.node # The TextNode object score = node_with_score.score # The similarity score chunk_id = node.id_ # The chunk ID # Extract the relevant metadata from the node file_name = node.metadata.get("file_name", "Unknown") file_path = node.metadata.get("file_path", "Unknown") # Extract the text content from the node text_content = node.text if node.text else "No content available" # Print the results in a user-friendly format print(f"Score: {score}") print(f"File Name: {file_name}") print(f"Id: {chunk_id}") print("\nExtracted Content:") print(text_content) print("\n" + "=" * 40 + " End of Result " + "=" * 40 + "\n")

 

 

 

Hybrid search

 

 

from llama_index.core.vector_stores.types import VectorStoreQueryMode hybrid_retriever = index.as_retriever( vector_store_query_mode=VectorStoreQueryMode.HYBRID ) hybrid_retriever.retrieve("What is inception about?")

 

 

 

Hybrid search and semantic ranking

 

 

hybrid_retriever = index.as_retriever( vector_store_query_mode=VectorStoreQueryMode.SEMANTIC_HYBRID ) hybrid_retriever.retrieve("What is inception about?")

 

 

 

Query rewriting

 

 

from llama_index.core import PromptTemplate query_gen_str = """\ You are a helpful assistant that generates multiple search queries based on a \ single input query. Generate {num_queries} search queries, one on each line, \ related to the following input query: Query: {query} Queries: """ query_gen_prompt = PromptTemplate(query_gen_str) def generate_queries(query: str, llm, num_queries: int = 5): response = llm.predict( query_gen_prompt, num_queries=num_queries, query=query ) # assume LLM proper put each query on a newline queries = response.split("\n") queries_str = "\n".join(queries) print(f"Generated queries:\n{queries_str}") return queries queries = generate_queries("What happened to the author?", llm)

 

 

Generated queries:

  1. What is the latest book written by the author?
  2. Has the author won any literary awards?
  3. Are there any upcoming events or interviews with the author?
  4. What is the author's background and writing style?
  5. Are there any controversies or scandals surrounding the author?

 

Sub question query engine

 

 

from llama_index.core.query_engine import SubQuestionQueryEngine from llama_index.core.tools import QueryEngineTool, ToolMetadata # setup base query engine as tool query_engine_tools = [ QueryEngineTool( query_engine=index.as_query_engine(), metadata=ToolMetadata( name=”pg_essay”, description="Paul Graham essay on What I Worked On", ), ), ] # build a sub-question query engine over this tool # this allows decomposing the question down into sub-questions which then execute against the tool query_engine = SubQuestionQueryEngine.from_defaults( query_engine_tools=query_engine_tools, use_async=True, ) response = query_engine.query("What happened to the author?")

 

 

Generated 1 sub questions.

[pg_essay] Q: What did the author work on?

[pg_essay] A: The author worked on writing and programming before college. They wrote short stories and also tried programming on an IBM 1401 computer using an early version of Fortran. Later, they worked with microcomputers, building one themselves and eventually getting a TRS-80. They wrote simple games, a program to predict rocket heights, and a word processor. In college, the author initially planned to study philosophy but switched to AI because of their interest in intelligent computers.

Read the whole story
alvinashcraft
11 minutes ago
reply
West Grove, PA
Share this story
Delete

Powerful React Form Builders to Consider in 2024

1 Share
Powerful React Form Builders to Consider We survey four React form builders, noting their core features and important aspects to consider when picking a form builder.

Continue reading Powerful React Form Builders to Consider in 2024 on SitePoint.

Read the whole story
alvinashcraft
11 minutes ago
reply
West Grove, PA
Share this story
Delete
Next Page of Stories