Coder Social home page Coder Social logo

langchain-rust's Introduction

🦜️🔗LangChain Rust

Latest Version

⚡ Building applications with LLMs through composability, with Rust! ⚡

Discord Docs: Tutorial

🤔 What is this?

This is the Rust language implementation of LangChain.

Current Features

  • LLMs

  • Embeddings

  • VectorStores

  • Chain

  • Agents

  • Tools

  • Semantic Routing

  • Document Loaders

    • PDF

      use futures_util::StreamExt;
      
      async fn main() {
          let path = "./src/document_loaders/test_data/sample.pdf";
      
          let loader = LoPdfLoader::from_path(path).expect("Failed to create PdfLoader");
      
          let docs = loader
              .load()
              .await
              .unwrap()
              .map(|d| d.unwrap())
              .collect::<Vec<_>>()
              .await;
      
      }
    • Pandoc

      use futures_util::StreamExt;
      
      async fn main() {
      
          let path = "./src/document_loaders/test_data/sample.docx";
      
          let loader = PandocLoader::from_path(InputFormat::Docx.to_string(), path)
              .await
              .expect("Failed to create PandocLoader");
      
          let docs = loader
              .load()
              .await
              .unwrap()
              .map(|d| d.unwrap())
              .collect::<Vec<_>>()
              .await;
      }
    • HTML

      use futures_util::StreamExt;
      use url::Url;
      
      async fn main() {
          let path = "./src/document_loaders/test_data/example.html";
          let html_loader = HtmlLoader::from_path(path, Url::parse("https://example.com/").unwrap())
              .expect("Failed to create html loader");
      
          let documents = html_loader
              .load()
              .await
              .unwrap()
              .map(|x| x.unwrap())
              .collect::<Vec<_>>()
              .await;
      }
    • CSV

      use futures_util::StreamExt;
      
      async fn main() {
          let path = "./src/document_loaders/test_data/test.csv";
          let columns = vec![
              "name".to_string(),
              "age".to_string(),
              "city".to_string(),
              "country".to_string(),
          ];
          let csv_loader = CsvLoader::from_path(path, columns).expect("Failed to create csv loader");
      
          let documents = csv_loader
              .load()
              .await
              .unwrap()
              .map(|x| x.unwrap())
              .collect::<Vec<_>>()
              .await;
      }
    • Git commits

      use futures_util::StreamExt;
      
      async fn main() {
          let path = "/path/to/git/repo";
          let git_commit_loader = GitCommitLoader::from_path(path).expect("Failed to create git commit loader");
      
          let documents = csv_loader
              .load()
              .await
              .unwrap()
              .map(|x| x.unwrap())
              .collect::<Vec<_>>()
              .await;
      }
    • Source code

      let loader_with_dir =
      SourceCodeLoader::from_path("./src/document_loaders/test_data".to_string())
      .with_dir_loader_options(DirLoaderOptions {
      glob: None,
      suffixes: Some(vec!["rs".to_string()]),
      exclude: None,
      });
      
      let stream = loader_with_dir.load().await.unwrap();
      let documents = stream.map(|x| x.unwrap()).collect::<Vec<_>>().await;

Installation

This library heavily relies on serde_json for its operation.

Step 1: Add serde_json

First, ensure serde_json is added to your Rust project.

cargo add serde_json

Step 2: Add langchain-rust

Then, you can add langchain-rust to your Rust project.

Simple install

cargo add langchain-rust

With Sqlite

cargo add langchain-rust --features sqlite

Download additional sqlite_vss libraries from https://github.com/asg017/sqlite-vss

With Postgres

cargo add langchain-rust --features postgres

With SurrialDB

cargo add langchain-rust --features surrealdb

With Qdrant

cargo add langchain-rust --features qdrant

Please remember to replace the feature flags sqlite, postgres or surrealdb based on your specific use case.

This will add both serde_json and langchain-rust as dependencies in your Cargo.toml file. Now, when you build your project, both dependencies will be fetched and compiled, and will be available for use in your project.

Remember, serde_json is a necessary dependencies, and sqlite, postgres and surrealdb are optional features that may be added according to project needs.

Quick Start Conversational Chain

use langchain_rust::{
    chain::{Chain, LLMChainBuilder},
    fmt_message, fmt_placeholder, fmt_template,
    language_models::llm::LLM,
    llm::openai::{OpenAI, OpenAIModel},
    message_formatter,
    prompt::HumanMessagePromptTemplate,
    prompt_args,
    schemas::messages::Message,
    template_fstring,
};

#[tokio::main]
async fn main() {
    //We can then initialize the model:
    // If you'd prefer not to set an environment variable you can pass the key in directly via the `openai_api_key` named parameter when initiating the OpenAI LLM class:
    // let open_ai = OpenAI::default()
    //     .with_config(
    //         OpenAIConfig::default()
    //             .with_api_key("<your_key>"),
    //     ).with_model(OpenAIModel::Gpt35.to_string());
    let open_ai = OpenAI::default().with_model(OpenAIModel::Gpt35.to_string());


    //Once you've installed and initialized the LLM of your choice, we can try using it! Let's ask it what LangSmith is - this is something that wasn't present in the training data so it shouldn't have a very good response.
    let resp = open_ai.invoke("What is rust").await.unwrap();
    println!("{}", resp);

    // We can also guide it's response with a prompt template. Prompt templates are used to convert raw user input to a better input to the LLM.
    let prompt = message_formatter![
        fmt_message!(Message::new_system_message(
            "You are world class technical documentation writer."
        )),
        fmt_template!(HumanMessagePromptTemplate::new(template_fstring!(
            "{input}", "input"
        )))
    ];

    //We can now combine these into a simple LLM chain:

    let chain = LLMChainBuilder::new()
        .prompt(prompt)
        .llm(open_ai.clone())
        .build()
        .unwrap();

    //We can now invoke it and ask the same question. It still won't know the answer, but it should respond in a more proper tone for a technical writer!

    match chain
        .invoke(prompt_args! {
        "input" => "Quien es el escritor de 20000 millas de viaje submarino",
           })
        .await
    {
        Ok(result) => {
            println!("Result: {:?}", result);
        }
        Err(e) => panic!("Error invoking LLMChain: {:?}", e),
    }

    //If you want to prompt to have a list of messages you could use the `fmt_placeholder` macro

    let prompt = message_formatter![
        fmt_message!(Message::new_system_message(
            "You are world class technical documentation writer."
        )),
        fmt_placeholder!("history"),
        fmt_template!(HumanMessagePromptTemplate::new(template_fstring!(
            "{input}", "input"
        ))),
    ];

    let chain = LLMChainBuilder::new()
        .prompt(prompt)
        .llm(open_ai)
        .build()
        .unwrap();
    match chain
        .invoke(prompt_args! {
        "input" => "Who is the writer of 20,000 Leagues Under the Sea, and what is my name?",
        "history" => vec![
                Message::new_human_message("My name is: luis"),
                Message::new_ai_message("Hi luis"),
                ],

        })
        .await
    {
        Ok(result) => {
            println!("Result: {:?}", result);
        }
        Err(e) => panic!("Error invoking LLMChain: {:?}", e),
    }
}

langchain-rust's People

Contributors

abraxas-365 avatar prabirshrestha avatar renovate[bot] avatar fgsch avatar anush008 avatar bwstearns avatar erhant avatar flaviodelgrosso avatar eng-cc avatar edartruwu avatar jorgefiestas avatar rzmk avatar timvw avatar aadi-pcln avatar

Stargazers

Ahmed Hani Ibrahim avatar Axmin Shrestha avatar  avatar  avatar Sven avatar Aahnik Daw avatar Cyclotomic Fields avatar 知半解 avatar vincent avatar Brad Pillow avatar Lubomir Anastasov avatar Mriganka Basu Roy Chowdhury avatar Andy Wei avatar Jan Ehrhardt avatar Jeancarlo Barrios avatar franklin selva avatar  avatar  avatar Vadym Parakonnyi avatar mars-peng-lb avatar ḕℏỈẍȓ avatar Sagaya Abdulhafeez avatar Johannus Vogel avatar  avatar Yanzhong Lin avatar Inkfinite avatar Ramon Iglesias avatar Walter Ye avatar Srimanth Agastyaraju avatar Arbal avatar  avatar Luke Milby avatar 千古兴亡知衡权 avatar Xiyu Zhai avatar FoundGod avatar Neurokid avatar Eric Buehler avatar xiongjianjunjun avatar  avatar  avatar Dhruvajyoti Sarma avatar Asutos avatar  avatar Dan Clark avatar Ryuici avatar  avatar Leo Dutra avatar Samir Djelal avatar Brucel Qwe avatar  avatar Sajjad Anwar avatar ZenYang avatar Jinho Sung avatar Null avatar  avatar archme avatar Devin Gould avatar Brandon Burciaga avatar 张伯雨 avatar  avatar Peter Xu avatar shuo avatar Chris Raethke avatar Hamze GHALEBI avatar Pierre Lafievre avatar Aaron Yee avatar Douglas Post avatar vidy avatar Neil Joseph Skaria avatar Varun Gupta avatar vadxq avatar kuno avatar Michal Piotrowski avatar Hanifan Rizki Nurahman avatar  avatar Mathia Haure-Touzé avatar Jun avatar  avatar Alejandro Osornio avatar Paul Karcher avatar Anthony Cervantes avatar Philip Fung avatar Ryan Lindskog avatar zshuaibin avatar Jason Ivey avatar Gynshu avatar  avatar hansel avatar Aleksey Shakhmatov avatar  avatar tiutiutiu avatar Mateusz Kurdziel avatar Matthieu Drouian avatar Ho Kim avatar Josh avatar  avatar Guillaume Dorchies avatar Mahmoud avatar ab avatar Jordi Carrillo avatar

Watchers

 avatar Juan José Miranda avatar Luis Ibarra Consiglieri avatar Ben Brandt avatar yanshoutong avatar Sandeep avatar Peet Stander avatar  avatar

langchain-rust's Issues

Add the ability to add a prompt to ConversationalRetrieverChainBuilder

Hello,
First of all I would like to thank you for the enormous effort you make for the Rust community.

Concerning my request, I wanted to create a ConversationalRetrieverChainBuilder, but before starting the discussion with LLM, I wanted to add an initialization prompt.

But apparently this function only exists on LLMChainBuilder. [ .prompt() ]

I tried adding the prompt during chain.invoke(), with :

let input_variables = prompt_args! {  ... };

but it doesn't work, LLM doesn't take it into account, as if I hadn't passed it any parameters.

Thank you in advance for your help

Pull missing model for Ollama LLM generation

Is your feature request related to a problem? Please describe.

While using Ollama for LLM generation, if the model does not exist locally it will give an error saying that the model does not exist.

For example, the llm_ollama.rs example used llama2 (https://github.com/Abraxas-365/langchain-rust/blob/main/examples/llm_ollama.rs#L15) and if run the example you will get:

OpenAIError(ApiError(ApiError { message: "model 'llama2' not found, try pulling it first", type: Some("api_error"), param: None, code: None }))

Describe the solution you'd like
I would perhaps suggest that we provide a simple wrapper for Ollama in particular? We already have an OllamaEmbedder struct that kind of handles the client setup. We could have a more fine-grained setup where the embedder and LLM models are passed in by themselves.

  • For embedders, we dont need to pull explicitly as Ollama does it on their own (https://github.com/ollama/ollama/blob/main/docs/api.md#generate-embeddings)
  • For generation, we can always pull the model before generation is invoked. If the model does not exist, it will take some time to download it of course; if it exists it will take a few seconds to load it into memory. Then, generation will not give an error due to non-existing model.

Describe alternatives you've considered
We are using LangChain and Ollama-rs together right now as a workaround in our project https://github.com/andthattoo/dkn-search-node/, using the latter to pull the model.

normalize vector store methods

Currently some vector store such as PgVector initializes the collection when using the StoreBuilder. This can be very expensive if we initialize the StoreBuilder in every http request. Consider adding methods such as initialize_collection(), remove_collection(), clear_collection() in VectorStore trait.

Token counter to Agentes

Description:

We propose implementing a token counter functionality within Agentes. This feature aims to collect all the prompt and output tokens of the large language model (LLM) and include them in the Agent executor chain result upon calling the Call function.

This enhancement would provide valuable insights into the token usage patterns of the LLM during execution, which can be beneficial for various purposes such as analyzing model behavior, optimizing resource utilization, and debugging.

chain.stream should return None instead of Error when stream ends

Currently I need to write a lot of boilerplate code when the streaming has ended. this also means I need to add async_openai as dependeny.

let mut stream = chain.stream(input_variables).await?;

while let Some(result) = stream.next().await {
    match &result {
        Ok(data) => data.to_stdout()?,
        Err(ChainError::LLMError(LLMError::OpenAIError(
            OpenAIError::StreamError(e),
        ))) => {
            if e == "Stream ended" {
                break;
            } else {
                error!("OpenAI Error: {:?}", e);
                break;
            }
        }
        Err(e) => panic!("Errorx: {:?}", e),
    }
}

This could be simplified to use Result<Option<StreamData>>.

let mut stream = chain.stream(input_variables).await?;

while let Some(result) = stream.next().await {
    match &result {
        Ok(Some(data)) => data.to_stdout()?,
        None => break,
        Err(e) => panic!("Errorx: {:?}", e),
    }
}

Enhancement Request: Adding Customization Options to WebScrapper Tool

Currently, the WebScrapper tool offers a solid foundation for web scraping tasks. However, to better suit diverse use cases and enhance its flexibility, I propose the addition of more customization options.

Proposed Customization Options:

User-defined Selectors: Allow users to define their own CSS or XPath selectors for targeting specific elements on web pages. This would enable more granular control over the scraping process and accommodate websites with complex structures.

Get memory form chain

Should implement a function to get the memory from the chain. It's useful when trying to see the complete chat history.

Expand Vector Store Trait to Support Additional Vector Databases

Summary:

The current implementation of the vector store trait primarily supports pgvector. To enhance versatility and usability within diverse environments, it would be beneficial to extend support to other popular vector databases such as Pinecone, Chroma, MongoDB, and others.

Motivation:

Expanding the vector store trait to include a wider range of vector databases will significantly increase the adaptability of Langchain rust in various use cases and environments. This enhancement can lead to broader adoption and greater flexibility in handling different types of vector data.

Proposed Changes:

Pinecone Integration: Leverage Pinecone's efficient vector search capabilities to enhance performance in similarity search tasks.
Chroma Support: Utilize Chroma for improved color search functionalities, making it ideal for applications requiring color-based vector search.
MongoDB Extension: Incorporate MongoDB's flexible document-based storage, allowing for efficient storage and querying of vector data alongside traditional data types.

Call to Action:

I invite the community to discuss the proposed changes, share insights, and contribute to the implementation of this enhancement. Your feedback and contributions are highly valued as we work together to make langchain rust more adaptable and powerful.

spell error

I found a spell error in conversational_chain.rs
spell_error

Add support for local embedding models

When you have large number of documents you want to create embedding, you may easily hit rate limits. To over come this we should have support for local embedding. While we can currently do this with ollama, we need to have an ollama server running.

Having local embeddings such as fastembed-rs would allow us to easily create desktop/cli apps.

Support Request for Official Endorsement by Langchain

As one of the maintainer of this project, I've been thrilled to see the growth and enthusiasm around our Rust port of Langchain. To further our project's reach and capabilities, I believe it's time we seek official endorsement and support from the Langchain team. This would not only bring more visibility to our project but could also lead to closer collaboration, ensuring better compatibility and feature parity with the official Langchain releases.

How You Can Help

I am reaching out to our community to gather support for this initiative. Here's how you can help:

  1. Express Interest: Share your thoughts on this GitHub issue about how an official endorsement could benefit your work and the broader Rust and Langchain communities.
  2. Reach Out to Langchain: Consider reaching out to the Langchain team through their official channels, forums, or social media to express your support for the Rust port. A collective voice from our community can make a significant impact.
  3. Share Examples: If you have used our Rust port in your projects, please share your experiences and examples. Demonstrating real-world use cases and benefits can strengthen our case for official endorsement.

Potential Benefits of Official Endorsement

  • Enhanced Visibility: Official recognition can attract more developers and contributors to our project.
  • Direct Support: Potential direct support or collaboration from the Langchain team could help in aligning our project closely with Langchain's roadmap and features.
  • Community Growth: An official endorsement could significantly boost our community, bringing in new users and contributors.

use tracing crate for logs

tracing is a popular library used by lot of popular libraries. We should look into use it.

When I was running a embeddings on git commits with 99k+ commits it was very hard for me to debug what was going on. I had to modify the code to add custom logs.

SurrealDB : ASSERT Error ( vector_dimensions )

Hello,

when I use surrealdb as a store, I always get this error:
field: Idiom([Field(Ident("embedding"))]), check: "(array::len($value) = 1536) OR (array::len($value) = 0)" })
when I add a document to the store :

    let store = StoreBuilder::new()
        .embedder(embedder)
        .db(db)
        .vector_dimensions(1536)
        .build()
        .await
        .unwrap();

    // Intialize the tables in the database. This is required to be done only once.
    store.initialize().await.unwrap();

    match store
        .add_documents(&docs, &VecStoreOptions::default().with_score_threshold(0.8))
        .await
    {
        Ok(_) => {}
        Err(e) => {
            println!("{:?}", e) // <---------------- here
        }
    };

the problem is here in "surrealdb.rs".

async fn create_collection_table_if_not_exists(&self) -> Result<(), Box<dyn Error>> {
        if !self.schemafull {
            return Ok(());
        }

        let vector_dimensions = self.vector_dimensions;

        match &self.collection_table_name {
            Some(collection_table_name) => {
                self.db
                    .query(format!(
                        r#"
                            DEFINE TABLE {collection_table_name} SCHEMAFULL;
                            DEFINE FIELD text                      ON {collection_table_name} TYPE string;
                            DEFINE FIELD embedding                 ON {collection_table_name} TYPE array ASSERT (array::len($value) = {vector_dimensions}) || (array::len($value) = 0);
                            DEFINE FIELD embedding.*               ON {collection_table_name} TYPE float;
                            DEFINE FIELD metadata                  ON {collection_table_name} FLEXIBLE TYPE option<object>;"#
                    ))
                    .await?
                    .check()?;
            }
            None => {
                let collection_table_name = &self.collection_name;
                dbg!(&collection_table_name);
                self.db
                    .query(format!(
                        r#"
                            DEFINE TABLE {collection_table_name} SCHEMAFULL;
                            DEFINE FIELD text              ON {collection_table_name} TYPE string;
                            DEFINE FIELD embedding         ON {collection_table_name} TYPE array ASSERT (array::len($value) = {vector_dimensions}) || (array::len($value) = 0);
                            DEFINE FIELD embedding.*       ON {collection_table_name} TYPE float;
                            DEFINE FIELD metadata          ON {collection_table_name} FLEXIBLE TYPE option<object>;"#
                    ))
                    .await?
                    .check()?;
            }
        }

        Ok(())
    }

simply remove all (temporary solution) :

ASSERT (array::len($value) = {vector_dimensions}) || (array::len($value) = 0)

and everything works properly.

or you need to find the right vector_dimensions ? ( 1536 )

I tried this, but it doesn't work :

    let docs = html_loader
        .load()
        .await
        .unwrap()
        .map(|x| x.unwrap())
        .collect::<Vec<_>>()
        .await;

    let size = docs[0].page_content.len(); //<---- not de right size

(minor remark : vector_dimensions must take usize as parameter, not i32 I think )

thank you in advance for your help.

Add OpenAI tools & function calling

Ref:

There are bunch of models that now support tools and function calling. This would allow us to have a json schema defined and force the model to return a json response allowing us to easily use this to add new capabilities.

assistant = client.beta.assistants.create(
  instructions="You are a weather bot. Use the provided functions to answer questions.",
  model="gpt-4-turbo-preview",
  tools=[{
      "type": "function",
    "function": {
      "name": "getCurrentWeather",
      "description": "Get the weather in location",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {"type": "string", "description": "The city and state e.g. San Francisco, CA"},
          "unit": {"type": "string", "enum": ["c", "f"]}
        },
        "required": ["location"]
      }
    }
  }, {
    "type": "function",
    "function": {
      "name": "getNickname",
      "description": "Get the nickname of a city",
      "parameters": {
        "type": "object",
        "properties": {
          "location": {"type": "string", "description": "The city and state e.g. San Francisco, CA"},
        },
        "required": ["location"]
      }
    } 
  }]
)

async operations are not really async

Hi, I've been working on a langchain variant in Rust myself, and I am reading this project to compare notes.
I can offer a tip, something I've bumped into in the past: when running CPU bound operations (loading text from PDF, splitting text, embedding, and more), you need to offload to one of the two:

  1. Tokio's builtin async pool with an async task
  2. Create your own dedicated pool for specific resources (a pool for embedders, a pool for splitters, etc), and offload to that dedicated pool (still using Tokio, of course)

For one-time loading during boot process of the app or similar workflow I recommend (1),
For multi-request processing, such as initializing a full-blown chain and then putting it on a webservice for serving multiple inference requests (with the same chain), I recommend (2).

It is a non-trivial refactor as you might discover some pieces of code are not Sync or Send and you'll have to drill down to make them such.
However, there's no getting around this kind of refactor, as currently CPU bound operations will completely block Tokio's async operations and make using Tokio pointless.

Output Parser for chains

Add an output parser for the chain, so I can have a chain which returns a markdown like:

What I want to get

So when the LLM returns an answer, we can parse it and just return the desired content.

Support ConversationalRetrievalChain

Is your feature request related to a problem? Please describe.
Add ConversationalRetrievalChain

Describe the solution you'd like
A chain that implements the ConversationalRetrievalChain

Describe alternatives you've considered
We could not implement it.

Additional context
In order to implement a chatbot this chain is the most suitable.

use thiserror

We probably want to start using thiserror crate sooner so can avoid this sort of errors and ? just works.

.await?;
   |               ^ doesn't have a size known at compile-time
   |
   = help: the trait `Sized` is not implemented for `dyn std::error::Error`

Add support for pandoc loader

pandoc supports lot of file formats. We should create a PandocLoader. Because files can be large we want to use AsyncRead. We probably want to convert all Reader to AsyncReader in the code that is already in the main branch.

For the python library, the seem to instead have EpubLoader which internally uses pandoc. We might still want to create PandocLoader so we don't have to reimplement tons of loader.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

cargo
Cargo.toml
  • scraper 0.19
  • serde 1.0
  • async-trait 0.1.80
  • tokio 1
  • reqwest 0.12
  • serde_json 1.0
  • futures 0.3
  • regex 1.10.4
  • log 0.4.21
  • html-escape 0.2.13
  • reqwest-eventsource 0.6.0
  • async-openai 0.23.0
  • mockito 1.4.0
  • tiktoken-rs 0.5.8
  • sqlx 0.7.4
  • uuid 1.8.0
  • pgvector 0.3.2
  • text-splitter 0.13
  • surrealdb 1.4.2
  • csv 1.3.0
  • urlencoding 2.1.3
  • lopdf 0.32.0
  • thiserror 1.0.59
  • futures-util 0.3.30
  • async-stream 0.3.5
  • tokio-stream 0.1.15
  • secrecy 0.8.0
  • readability 0.3.0
  • url 2.5.0
  • fastembed 3
  • flume 0.11.0
  • gix 0.63.0
  • opensearch 2
  • aws-config 1.2
  • glob 0.3.1
  • strum_macros 0.26.2
  • async-recursion 1.1.0
  • tree-sitter 0.22
  • tree-sitter-rust 0.21
  • tree-sitter-cpp 0.22
  • tree-sitter-javascript 0.21
  • tree-sitter-c 0.21
  • tree-sitter-go 0.21
  • tree-sitter-python 0.21
  • tree-sitter-typescript 0.21
  • qdrant-client 1.8.0
  • ollama-rs 0.2.0
  • tokio-test 0.4.4
  • testcontainers 0.18
  • cc 1
github-actions
.github/workflows/ci.yml
  • actions/checkout v4
  • actions-rs/toolchain v1
  • actions-rs/cargo v1
  • actions-rs/cargo v1
  • actions-rs/cargo v1
  • actions/checkout v4
  • actions-rs/toolchain v1
  • actions-rs/cargo v1
  • actions-rs/cargo v1

  • Check this box to trigger a request for Renovate to run again on this repository

Add support for cancellation

Using LLMs can be expensive or slow. Add support for cancellation - https://docs.rs/tokio-util/latest/tokio_util/sync/struct.CancellationToken.html

Seems like in JS, they use the 2nd args for options - https://js.langchain.com/docs/modules/model_io/chat/cancelling_requests

could also support none as option.

let open_ai = OpenAI::default();
let response = open_ai.invoke("What is the capital of France?", None).await.unwrap();
let token = CancellationToken::new();

let open_ai = OpenAI::default();
let response = open_ai.invoke("What is the capital of France?", InvokeOptions::default().with_cancellation(token.clone())).await.unwrap();

Add document loader

Add document loaders to make it easy to implement RAG.

Add stream handler to Agent executor

As I delve into the development of the Rust port for the Lagchain library, I've identified a crucial feature that appears to be absent in the original Python implementation—native support for streaming the final responses of agents. This functionality is particularly important for applications requiring real-time data processing and analysis. Inspired by a tutorial on streaming Lagchain agent outputs (video link below), I believe incorporating this feature into the Rust port could significantly enhance its utility and performance.

Video Reference: How to Stream Lagchain Agent Output

Feature Description:
I propose we integrate a feature allowing for the asynchronous streaming of an agent's final response. This could potentially be implemented using Rust's robust asynchronous and concurrency features, such as futures and streams, to provide a high-performance, real-time data streaming capability.

OPEN_AI_KEY

Thank you for the exciting project!

I wanted to test the agent and got error:

thread 'main' panicked at src/examples/agent.rs:45:19:
Error invoking LLMChain: ApiError(ApiError { message: "You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY), or as the password field (with blank username) if you're accessing the API from your browser and are prompted for a username and password. You can obtain an API key from https://platform.openai.com/account/api-keys.", type: Some("invalid_request_error"), param: None, code: None })

I have my key in a .env file as OPENAI_API_KEY

Is there another way I should've loaded?

Thank you in advance

Add HuggingFace inference API

Is your feature request related to a problem? Please describe.
The HuggingFace inference API is gaining popularity, and I wanted to use the HuggingFace inference API on this https://huggingface.co/docs/api-inference/en/quicktour reference, which is not OpenAI compatible.

Describe the solution you'd like
We should define a new feature for this project and overwrite the HuggingFace Inference API.

Describe alternatives you've considered
There is no alternative way.

Additional context
Add any other context or screenshots about the feature request here.

Implement a MockOpenAI or MockLLM Server for Improved Testing

Summary

To ensure the robustness and reliability of our langchain project as we introduce new features, it’s imperative to consider implementing a MockOpenAI/LLM server. This would enable us to run comprehensive tests without affecting our actual OpenAI/LLM interactions

Motivation

As we continue to expand the project's capabilities, there is a growing concern that new additions might inadvertently affect existing functionalities. The introduction of a MockOpenAI server would facilitate a more controlled testing environment, allowing for:

  • Isolated testing of new features without dependency on live OpenAI services.
  • Cost-effective way to perform extensive testing.
  • Early detection of potential issues and conflicts with new code integrations.

Implementing Support for Streaming Intermediate Agent Steps

Hello Rust Port Team,

I am currently enhancing the Rust port of the Lagchain library and I'd like to propose the implementation of a feature that is already present in the original Lagchain library: the ability to stream intermediate steps of agents. This feature is invaluable for, Impruving the UX, debugging, monitoring, and scenarios where intermediate data is crucial for understanding the agent's progression through its tasks.

In the original Lagchain library, this functionality facilitates a deeper insight into the agent's operation by providing real-time data at various checkpoints. Integrating this into the Rust port could not only align our feature set more closely with the original library.

Proposed Feature:
Integrate a mechanism to stream intermediate steps of agents in the Rust port, similar to the functionality available in the original Lagchain library.

Add more LLMs integrations

Description

At the current date, the only available integration for OpenAI's Large Language Model (LLM) is with ChatGPT. However, it would be highly beneficial to expand this integration to other platforms such as Azure or OLLAMA. This expansion would allow users to leverage the capabilities of LLM in a wider range of applications and environments, enhancing flexibility and accessibility.

Proposed Solution

Integrate OpenAI's LLM with Azure and/or OLLAMA to enable users to utilize the model within these platforms seamlessly. This integration could involve developing APIs, SDKs, or plugins that facilitate easy integration and interaction with LLM.

Expected Benefits

  • Enhanced Accessibility: Users will have the flexibility to access LLM through multiple platforms, catering to diverse needs and preferences.
  • Improved Workflow Integration: Integration with Azure and OLLAMA will streamline workflows for developers and researchers, allowing them to leverage LLM within their existing environments.
  • Expanded User Base: By integrating with popular platforms like Azure and OLLAMA, OpenAI can reach a broader audience, fostering greater adoption and utilization of LLM.

Community Feedback

Please share your thoughts and feedback on this proposed integration. Your input will help us prioritize and shape the development of this feature.

Evaluate the use of derive_builder for implementing builders in our project

Background:

In our current project, we have several instances where we're implementing builder patterns manually for constructing complex objects. This process has become error-prone and cumbersome as our project scales. To improve developer efficiency and maintain code quality, we're considering the use of the derive_builder crate.

Proposal:

The derive_builder crate offers a macro to automatically implement the builder pattern for any given struct. This could potentially reduce boilerplate code and make our codebase more maintainable. Before proceeding, we need to assess the feasibility and implications of integrating this crate into our project.

  • Points for Discussion:
    Ease of Integration: How easily can derive_builder be integrated into our existing codebase? What changes would be required, and how disruptive might they be?

  • Flexibility: Does derive_builder offer enough flexibility to cover our use cases? Are there any limitations we should be aware of?

  • Performance: How does the use of derive_builder impact compile-time and runtime performance? Is there a significant overhead compared to our manual implementations?

  • Learning Curve: What is the learning curve associated with derive_builder? Considering our team's current Rust expertise, how much effort would be required to get everyone up to speed?

  • Maintenance and Support: How actively is derive_builder maintained? Are there any known issues or bugs that could affect our usage?

  • Community and Ecosystem: How widely is derive_builder used in the Rust ecosystem? Can we find examples of other projects similar to ours that are using it successfully?

  • Alternatives: Are there other crates or patterns we should consider as alternatives to derive_builder? How do they compare in terms of the criteria above?

Next Steps:

Based on the discussion, we should decide whether to proceed with integrating derive_builder, explore alternatives, or continue with our current approach. If we decide to move forward with derive_builder, we'll need to outline an implementation plan and assign responsibilities.

Call to Action:

Please share your thoughts, experiences, and any relevant insights on the use of derive_builder in the comments below. Your feedback is crucial for making an informed decision.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.