### Complete LangChain .NET Chain Example Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStarted This comprehensive example shows how to set up and run a LangChain.NET chain. It includes downloading a model using HuggingFace, loading it with LLamaSharp, defining a prompt, building a chain with Set and LLM links, and executing the chain asynchronously. ```C# using LangChain.Providers; using LangChain.Providers.HuggingFace.Downloader; using LangChain.Providers.LLamaSharp; using static LangChain.Chains.Chain; // get model path var modelPath = await HuggingFaceModelDownloader.GetModelAsync( repository: "TheBloke/Thespis-13B-v0.5-GGUF", fileName: "thespis-13b-v0.5.Q2_K.gguf", version: "main"); // load model var model = LLamaSharpModelInstruction.FromPath(modelPath).UseConsoleForDebug(); // building a chain var prompt = @" You are an AI assistant that greets the world. World: Hello, Assistant! Assistant:"; var chain = Set(prompt, outputKey: "prompt") | LLM(model, inputKey: "prompt"); await chain.RunAsync(); ``` -------------------------------- ### LangChain CLI Usage Examples Source: https://tryagi.github.io/LangChain/LangChain/cli This snippet demonstrates how to install the LangChain .NET CLI tool globally and provides examples for using the `summarize` and `generate` commands, including setting the OpenAI API key and specifying a model. ```Shell dotnet tool install --global langchain.cli --prerelease langchain auth openai OPENAI_API_KEY # Default model - gpt-3.5-turbo, you can specify another model using --model parameter langchain summarize --input-file README.md --output-file SUMMARY.md langchain generate --input "Give me random word" # It will output a random word to console # Smart task langchain model gpt-4-turbo langchain generate --input "Give me a solution for the next problem: $PROBLEM" ``` -------------------------------- ### Use Claude 3.5 Sonnet with Custom Settings in C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStartedWithAmazonBedrock Illustrates how to initialize a Bedrock provider, instantiate the Claude35SonnetModel, override default settings like MaxTokens, Temperature, and UseStreaming, attach event handlers, define a prompt, and generate a response. ```C# using Amazon; using LangChain.Providers; using LangChain.Providers.Amazon.Bedrock; using LangChain.Providers.Amazon.Bedrock.Predefined.Anthropic; //// var provider = new BedrockProvider(RegionEndpoint.USWest2); var llm = new Claude35SonnetModel(provider) { Settings = new BedrockChatSettings { MaxTokens = 200_000, Temperature = 0, UseStreaming = true } }; llm.RequestSent += (_, request) => Console.WriteLine($"Prompt: {request.Messages.AsHistory()}"); llm.DeltaReceived += (_, delta) => Console.Write(delta.Content); llm.ResponseReceived += (_, response) => Console.WriteLine($"Completed response: {response}"); var prompt = @" you are a comic book writer. you will be given a question and you will answer it. question: who are 10 of the most popular superheros and what are their powers?"; string response = await llm.GenerateAsync(prompt); Console.WriteLine(response); ``` -------------------------------- ### Use AWS CLI Command with Profile (Shell) Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStartedWithAmazonBedrock Example command demonstrating how to use a specific AWS profile () when executing an AWS CLI command, such as listing S3 buckets. ```Shell aws s3 ls --profile ``` -------------------------------- ### Verify AWS CLI Installation (Shell) Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStartedWithAmazonBedrock Command to check the installed version of the AWS Command Line Interface (CLI) to confirm successful installation. ```Shell aws --version ``` -------------------------------- ### Configure Bedrock Provider with Keys and Region in C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStartedWithAmazonBedrock Demonstrates configuring the BedrockProvider using AWS access key ID, secret access key, and a region endpoint, typically retrieved from environment variables. ```C# var accessKeyId = Environment.GetEnvironmentVariable("AWS_ACCESSKEYID"); var secretAccessKey = Environment.GetEnvironmentVariable("AWS_SECRETACCESSKEY"); var provider = new BedrockProvider(accessKeyId, secretAccessKey, RegionEndpoint.USWest2); ``` -------------------------------- ### Building a Simple LangChain .NET Chain Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStarted This snippet demonstrates how to construct a basic chain in LangChain.NET using the Set and LLM links. It sets an initial prompt value and then passes it to an LLM model (assumed to be loaded) for processing, finally executing the chain asynchronously. ```C# // building a chain var prompt = @" You are an AI assistant that greets the world. World: Hello, Assistant! Assistant:"; var chain = Set(prompt, outputKey: "prompt") | LLM(model, inputKey: "prompt"); await chain.RunAsync(); ``` -------------------------------- ### Configure Bedrock Provider with Region in C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStartedWithAmazonBedrock Shows how to instantiate the BedrockProvider class by passing an AWS RegionEndpoint object, specifying the geographic region for the Bedrock service. ```C# var provider = new BedrockProvider(RegionEndpoint.USWest2); ``` -------------------------------- ### Complete Example: OpenAI Provider and Basic Chain Source: https://tryagi.github.io/LangChain/LangChain/wiki/HowToUseOpenAiProvider Provides the full code example combining the initialization of an OpenAI model and provider with custom HTTP settings and the execution of a simple LangChain .NET chain. ```C# using LangChain.Providers.OpenAI; using LangChain.Providers.OpenAI.Predefined; using tryAGI.OpenAI; using static LangChain.Chains.Chain; var model = new OpenAiLatestFastChatModel("your_openAI_key"); var chain = Set("Hello!", outputKey: "request") // set context variable `request` to "Hello" | LLM(model, inputKey: "request", outputKey: "text"); // get text from context variable `request`, pass it to the model and put result into `text` var result = await chain.RunAsync("text"); // execute chain and get `text` context variable Console.WriteLine(result); // Hello! How can I assist you today? var httpClientHandler = new HttpClientHandler(); using var httpClient = new HttpClient(httpClientHandler, disposeHandler: true); using var api = new OpenAiClient( httpClient, baseUri: new Uri("https://api.openai.com/v1/") // default value, can be omitted ); var provider = new OpenAiProvider(api); var tunedModel = new OpenAiLatestFastChatModel(provider); ``` -------------------------------- ### Loading LLamaSharp Model from Path in LangChain .NET C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStarted This code shows how to initialize a `LLamaSharpModelInstruction` instance by providing the local path to a `.gguf` model file. The `.UseConsoleForDebug()` method is chained to enable console debugging output for the model. ```C# // load model var model = LLamaSharpModelInstruction.FromPath(modelPath).UseConsoleForDebug(); ``` -------------------------------- ### Complete Example - Using Chain Output - LangChain .NET - C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/UsingChainOutput Provides the complete code demonstrating how to download a model, build a chain with explicit input/output key management, run the chain, and print the final output extracted from the chain's context. ```C# using LangChain.Providers.HuggingFace.Downloader; using LangChain.Providers.LLamaSharp; using static LangChain.Chains.Chain; // get model path var modelPath = await HuggingFaceModelDownloader.GetModelAsync( repository: "TheBloke/Thespis-13B-v0.5-GGUF", fileName: "thespis-13b-v0.5.Q2_K.gguf", version: "main"); // load model var model = LLamaSharpModelInstruction.FromPath(modelPath); // building a chain var prompt = @" You are an AI assistant that greets the world. World: Hello, Assistant! Assistant:"; var chain = Set(prompt, outputKey: "prompt") | LLM(model, inputKey: "prompt", outputKey: "result"); var result = await chain.RunAsync("result"); Console.WriteLine(result); ``` -------------------------------- ### Downloading Hugging Face Model with LangChain .NET C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStarted This snippet demonstrates how to use `HuggingFaceModelDownloader.GetModelAsync` to download a specified model file from a Hugging Face repository. It returns the local path to the downloaded `.gguf` file, which is required for loading the model. ```C# using LangChain.Providers; using LangChain.Providers.HuggingFace.Downloader; using LangChain.Providers.LLamaSharp; using static LangChain.Chains.Chain; // get model path var modelPath = await HuggingFaceModelDownloader.GetModelAsync( repository: "TheBloke/Thespis-13B-v0.5-GGUF", fileName: "thespis-13b-v0.5.Q2_K.gguf", version: "main"); ``` -------------------------------- ### Configure AWS CLI with Profile (Shell) Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStartedWithAmazonBedrock Command to create or configure a named AWS profile. This allows managing multiple sets of AWS credentials and configurations under different names. ```Shell aws configure --profile ``` -------------------------------- ### Initialize BedrockProvider Default (C#) Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStartedWithAmazonBedrock Initializes the LangChain .NET BedrockProvider using the default constructor. This assumes AWS credentials and region are configured via environment variables, shared credential files, or an AWS profile set as the default. ```C# var provider = new BedrockProvider(); ``` -------------------------------- ### Configure AWS CLI with Access Keys (Shell) Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStartedWithAmazonBedrock Command to configure the AWS CLI using an Access Key ID and Secret Access Key. The user will be prompted to enter credentials, default region, and output format. ```Shell aws configure ``` -------------------------------- ### Verify AWS CLI Configuration (Shell) Source: https://tryagi.github.io/LangChain/LangChain/wiki/GettingStartedWithAmazonBedrock Command to verify that the AWS CLI is configured correctly by retrieving information about the identity (user, role, or federated user) whose credentials are being used. ```Shell aws sts get-caller-identity ``` -------------------------------- ### Initializing ASP.NET Core with LangChain .NET Providers Source: https://tryagi.github.io/LangChain/LangChain/samples/AspNet This snippet demonstrates the standard setup for an ASP.NET Core application's Program.cs file, including adding controllers, Swagger, and specifically registering LangChain .NET services for OpenAI and Anthropic using extension methods for dependency injection. ```csharp using LangChain.Extensions.DependencyInjection; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddOpenAi(); builder.Services.AddAnthropic(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run(); ``` -------------------------------- ### Initializing WordLoader in C# Source: https://tryagi.github.io/LangChain/LangChain/document-loaders/Word This snippet demonstrates how to create an instance of the WordLoader and load a document from a stream. It shows the basic setup for reading content from a Word (.docx) file. ```C# var loader = new WordLoader(); var documents = await loader.LoadAsync(DataSource.FromStream(H.Resources.file_sample_1MB_docx.AsStream())); // check text from paragraph 1 // check text from paragraph 2 ``` -------------------------------- ### Implementing Conversational Memory with LangChain.NET and OpenAI Source: https://tryagi.github.io/LangChain/LangChain/samples/Memory This C# code demonstrates setting up a conversational loop using LangChain.NET. It initializes an OpenAI model, defines a prompt template, selects a memory strategy (Buffer, Window Buffer, Summary, or Summary Buffer) based on user choice, builds a chain to process input and update memory, and runs a loop for user interaction. It requires the OPENAI_API_KEY environment variable. ```csharp using LangChain.Memory; using LangChain.Providers; using LangChain.Providers.OpenAI.Predefined; using static LangChain.Chains.Chain; internal class Program { private static async Task Main(string[] args) { // Pull the API key from the environment, so it's never checked in with source var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY environment variable is not found."); // Use a common, general-purpose LLM var model = new OpenAiLatestFastChatModel(apiKey); // Create a simple prompt template for the conversation to help the AI var template = @" The following is a friendly conversation between a human and an AI. {history} Human: {input} AI: "; // To have a conversation that remembers previous messages we need to use memory. // Here we pick one of a number of different strategies for implementing memory. var memory = PickMemoryStrategy(model); // Build the chain that will be used for each turn in our conversation. // This is just declaring the chain. Actual execution of the chain happens // in the conversation loop below. On every pass through the loop, the user's // input is added to the beginning of this chain to make a new chain. var chain = LoadMemory(memory, outputKey: "history") | Template(template) | LLM(model) | UpdateMemory(memory, requestKey: "input", responseKey: "text"); Console.WriteLine(); Console.WriteLine("Start a conversation with the friendly AI!"); Console.WriteLine("(Enter 'exit' or hit Ctrl-C to end the conversation)"); // Run an endless loop of conversation while (true) { Console.WriteLine(); Console.Write("Human: "); var input = Console.ReadLine() ?? string.Empty; if (input == "exit") { break; } // Build a new chain by prepending the user's input to the original chain var currentChain = Set(input, "input") | chain; // Get a response from the AI var response = await currentChain.RunAsync("text"); Console.Write("AI: "); Console.WriteLine(response); } } private static BaseChatMemory PickMemoryStrategy(IChatModel model) { // The memory will add prefixes to messages to indicate where they came from // The prefixes specified here should match those used in our prompt template MessageFormatter messageFormatter = new MessageFormatter { AiPrefix = "AI", HumanPrefix = "Human" }; BaseChatMessageHistory chatHistory = GetChatMessageHistory(); string memoryClassName = PromptForChoice(new[] { nameof(ConversationBufferMemory), nameof(ConversationWindowBufferMemory), nameof(ConversationSummaryMemory), nameof(ConversationSummaryBufferMemory) }); switch (memoryClassName) { case nameof(ConversationBufferMemory): return GetConversationBufferMemory(chatHistory, messageFormatter); case nameof(ConversationWindowBufferMemory): return GetConversationWindowBufferMemory(chatHistory, messageFormatter); case nameof(ConversationSummaryMemory): return GetConversationSummaryMemory(chatHistory, messageFormatter, model); case nameof(ConversationSummaryBufferMemory): return GetConversationSummaryBufferMemory(chatHistory, messageFormatter, (IChatModelWithTokenCounting)model); default: throw new InvalidOperationException($"Unexpected memory class name: '{memoryClassName}'"); } } private static string PromptForChoice(string[] choiceTexts) { while (true) { Console.Clear(); Console.WriteLine("Select from the following options:"); int choiceNumber = 1; foreach (string choiceText in choiceTexts) { ``` -------------------------------- ### Handling Console Input in C# Source: https://tryagi.github.io/LangChain/LangChain/samples/Memory This snippet shows a loop for displaying choices to the user on the console, reading their input, parsing it as an integer, and returning the selected text. It handles invalid input by looping. ```C# Console.WriteLine($" {choiceNumber}: {choiceText}"); choiceNumber++; } Console.WriteLine(); Console.Write("Enter choice: "); string choiceEntry = Console.ReadLine() ?? string.Empty; if (int.TryParse(choiceEntry, out int choiceIndex)) { string choiceText = choiceTexts[choiceIndex]; Console.WriteLine(); Console.WriteLine($"You selected '{choiceText}'"); return choiceText; } } } ``` -------------------------------- ### Complete Crew Agent Example in C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/CheckingInternetSpeedWithCrewAndOllama This comprehensive C# snippet demonstrates setting up and running a LangChain.NET Crew agent system. It includes initializing an Ollama provider and model, defining a custom 'ping' tool using `CrewAgentToolLambda`, creating 'manager' and 'pinger' agents, adding the tool to the pinger agent, building the agent chain, running it, and printing the final output. ```C# using System.Diagnostics; using System.Net; using LangChain.Chains.StackableChains.Agents.Crew; using LangChain.Chains.StackableChains.Agents.Crew.Tools; using LangChain.Providers; using LangChain.Providers.Ollama; using Ollama; using static LangChain.Chains.Chain; var provider = new OllamaProvider( // url: "http://172.16.50.107:11434", // if you have ollama running on different computer/port. Default is "http://localhost:11434/api" ); var model = new OllamaChatModel(provider, id: "llama3.1").UseConsoleForDebug(); var pingTool = new CrewAgentToolLambda("ping", "executes ping on specified ip address", address => { var addressParsed = IPAddress.Parse(address); var process = new Process { StartInfo = new ProcessStartInfo { FileName = "ping", Arguments = "-n 5 " + addressParsed, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true } }; process.Start(); string result = process.StandardOutput.ReadToEnd(); process.WaitForExit(); return Task.FromResult(result); }); // controls agents var manager = new CrewAgent(model, "manager", "assign task to one of your co-workers and return the result"); // the actual agent who does the job var pinger = new CrewAgent(model, "pinger", "checks the speed of internet connection", "you using ping command and analyzing it's result. After this you print a single number as your final answer(the connection speed in milliseconds)."); pinger.AddTools(new[] { pingTool }); var chain = Set("What is my ping to google's main dns server?") | Crew(new[] { manager, pinger }, manager); var res = await chain.RunAsync("text"); Console.WriteLine(res); ``` -------------------------------- ### Initializing and Using HuggingFace Models with LangChain.NET (C#) Source: https://tryagi.github.io/LangChain/LangChain/samples/HuggingFace This snippet demonstrates how to initialize the HuggingFace provider in LangChain.NET and use two different models: GPT-2 for text generation and a BLIP model for image-to-text conversion. It shows how to set up the provider with an API key (though empty in this example) and an HttpClient, then instantiate specific models and call their respective generation methods. It requires the LangChain.Providers.HuggingFace NuGet package. ```C# using LangChain.Providers; using LangChain.Providers.HuggingFace; using LangChain.Providers.HuggingFace.Predefined; using var client = new HttpClient(); var provider = new HuggingFaceProvider(apiKey: string.Empty, client); var gpt2Model = new Gpt2Model(provider); var gp2ModelResponse = await gpt2Model.GenerateAsync("What would be a good company name be for name a company that makes colorful socks?"); Console.WriteLine("### GP2 Response"); Console.WriteLine(gp2ModelResponse); const string imageToTextModel = "Salesforce/blip-image-captioning-base"; var model = new HuggingFaceImageToTextModel(provider, imageToTextModel); var path = Path.Combine(Path.GetTempPath(), "solar_system.png"); var imageData = await File.ReadAllBytesAsync(path); var binaryData = new BinaryData(imageData, "image/jpg"); var imageToTextResponse = await model.GenerateTextFromImageAsync(new ImageToTextRequest { Image = binaryData }); Console.WriteLine("\n\n### ImageToText Response"); Console.WriteLine(imageToTextResponse.Text); Console.ReadLine(); ``` -------------------------------- ### Initializing Conversation Summary Memory in C# Source: https://tryagi.github.io/LangChain/LangChain/samples/Memory This method creates a `ConversationSummaryMemory` instance, which summarizes the conversation history using a language model. It requires a `BaseChatMessageHistory`, a `MessageFormatter`, and an `IChatModel`. ```C# private static BaseChatMemory GetConversationSummaryMemory(BaseChatMessageHistory chatHistory, MessageFormatter messageFormatter, IChatModel model) { return new ConversationSummaryMemory(model, chatHistory) { Formatter = messageFormatter }; } ``` -------------------------------- ### Initializing Conversation Window Buffer Memory in C# Source: https://tryagi.github.io/LangChain/LangChain/samples/Memory This method creates a `ConversationWindowBufferMemory` instance, which stores only the last N messages in a buffer, specified by the `WindowSize`. It requires a `BaseChatMessageHistory` and a `MessageFormatter`. ```C# private static BaseChatMemory GetConversationWindowBufferMemory(BaseChatMessageHistory chatHistory, MessageFormatter messageFormatter) { return new ConversationWindowBufferMemory(chatHistory) { WindowSize = 3, Formatter = messageFormatter }; } ``` -------------------------------- ### Initializing Conversation Buffer Memory in C# Source: https://tryagi.github.io/LangChain/LangChain/samples/Memory This method creates a `ConversationBufferMemory` instance, which stores the full conversation history in a buffer. It requires a `BaseChatMessageHistory` and a `MessageFormatter`. ```C# private static BaseChatMemory GetConversationBufferMemory(BaseChatMessageHistory chatHistory, MessageFormatter messageFormatter) { return new ConversationBufferMemory(chatHistory) { Formatter = messageFormatter }; } ``` -------------------------------- ### Building a Crew Agent Chain in C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/CheckingInternetSpeedWithCrewAndOllama This snippet demonstrates how to construct a LangChain.NET Crew agent chain. It initializes the chain with a starting prompt using `Set`, pipes it into the `Crew` function which takes an array of agents (including the manager) and the designated manager agent, runs the chain asynchronously with `RunAsync`, and prints the result to the console. ```C# var chain = Set("What is my ping to google's main dns server?") | Crew(new[] { manager, pinger }, manager); var res = await chain.RunAsync("text"); Console.WriteLine(res); ``` -------------------------------- ### Initializing Chat Message History in C# Source: https://tryagi.github.io/LangChain/LangChain/samples/Memory This method initializes and returns a basic `ChatMessageHistory` object, which is used to store the conversation history. The comment indicates that other history types are also compatible. ```C# private static BaseChatMessageHistory GetChatMessageHistory() { // Other types of chat history work, too! return new ChatMessageHistory(); } ``` -------------------------------- ### Initializing Crew Agents (C#) Source: https://tryagi.github.io/LangChain/LangChain/wiki/CheckingInternetSpeedWithCrewAndOllama Creates two CrewAgent instances: a "manager" agent responsible for delegating tasks and a "pinger" agent specialized in checking internet speed using the ping command, providing a detailed backstory for the pinger to guide its behavior. ```C# // controls agents var manager = new CrewAgent(model, "manager", "assign task to one of your co-workers and return the result"); // the actual agent who does the job var pinger = new CrewAgent(model, "pinger", "checks the speed of internet connection", "you using ping command and analyzing it's result. After this you print a single number as your final answer(the connection speed in milliseconds)."); ``` -------------------------------- ### Retrieval Augmented Generation (RAG) with OpenAI and SQLite in C# Source: https://tryagi.github.io/LangChain/LangChain This snippet demonstrates how to perform RAG using LangChain.NET. It covers initializing OpenAI models for embeddings and language generation, creating a SQLite vector database from a PDF document, and querying the database to answer questions using both direct async methods and LangChain chains. ```C# // Price to run from zero(create embeddings and request to LLM): 0,015$ // Price to re-run if database is exists: 0,0004$ // Dependencies: LangChain, LangChain.Databases.Sqlite, LangChain.DocumentLoaders.Pdf // Initialize models var provider = new OpenAiProvider( Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InconclusiveException("OPENAI_API_KEY is not set")); var llm = new OpenAiLatestFastChatModel(provider); var embeddingModel = new TextEmbeddingV3SmallModel(provider); // Create vector database from Harry Potter book pdf using var vectorDatabase = new SqLiteVectorDatabase(dataSource: "vectors.db"); var vectorCollection = await vectorDatabase.AddDocumentsFromAsync( embeddingModel, // Used to convert text to embeddings dimensions: 1536, // Should be 1536 for TextEmbeddingV3SmallModel dataSource: DataSource.FromUrl("https://canonburyprimaryschool.co.uk/wp-content/uploads/2016/01/Joanne-K.-Rowling-Harry-Potter-Book-1-Harry-Potter-and-the-Philosophers-Stone-EnglishOnlineClub.com_.pdf"), collectionName: "harrypotter", // Can be omitted, use if you want to have multiple collections textSplitter: null); // Default is CharacterTextSplitter(ChunkSize = 4000, ChunkOverlap = 200) // Now we have two ways: use the async methods or use the chains // 1. Async methods // Find similar documents for the question const string question = "Who was drinking a unicorn blood?"; var similarDocuments = await vectorCollection.GetSimilarDocuments(embeddingModel, question, amount: 5); // Use similar documents and LLM to answer the question var answer = await llm.GenerateAsync( $""" Use the following pieces of context to answer the question at the end. If the answer is not in context then just say that you don't know, don't try to make up an answer. Keep the answer as short as possible. {similarDocuments.AsString()} Question: {question} Helpful Answer: """); Console.WriteLine($"LLM answer: {answer}"); // The cloaked figure. // 2. Chains var promptTemplate = @"Use the following pieces of context to answer the question at the end. If the answer is not in context then just say that you don't know, don't try to make up an answer. Keep the answer as short as possible. Always quote the context in your answer. {context} Question: {text} Helpful Answer:"; var chain = Set("Who was drinking a unicorn blood?") // set the question (default key is "text") | RetrieveSimilarDocuments(vectorCollection, embeddingModel, amount: 5) // take 5 most similar documents | CombineDocuments(outputKey: "context") // combine documents together and put them into context | Template(promptTemplate) // replace context and question in the prompt with their values | LLM(llm.UseConsoleForDebug()); // send the result to the language model var chainAnswer = await chain.RunAsync("text"); // get chain result Console.WriteLine("Chain Answer:"+ chainAnswer); Console.WriteLine($"LLM usage: {llm.Usage}"); // Print usage and price Console.WriteLine($"Embedding model usage: {embeddingModel.Usage}"); // Print usage and price ``` -------------------------------- ### Initializing Conversation Summary Buffer Memory in C# Source: https://tryagi.github.io/LangChain/LangChain/samples/Memory This method creates a `ConversationSummaryBufferMemory` instance, which summarizes older messages and keeps recent messages in a buffer, controlled by `MaxTokenCount`. It requires a `BaseChatMessageHistory`, a `MessageFormatter`, and an `IChatModelWithTokenCounting`. ```C# private static BaseChatMemory GetConversationSummaryBufferMemory(BaseChatMessageHistory chatHistory, MessageFormatter messageFormatter, IChatModelWithTokenCounting model) { return new ConversationSummaryBufferMemory(model, chatHistory) { MaxTokenCount = 25, Formatter = messageFormatter }; } ``` -------------------------------- ### Initializing and Running Basic OpenAI Chain in C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/HowToUseOpenAiProviderSmaller This snippet demonstrates how to initialize an OpenAI model using OpenAiLatestFastChatModel and create a simple chain using the Set and LLM operators from LangChain.Chains.Chain. It then runs the chain asynchronously with a placeholder input 'text' and prints the output to the console. Requires the LangChain.Providers.OpenAI package. ```C# using LangChain.Providers.OpenAI.Predefined; using static LangChain.Chains.Chain; var model = new OpenAiLatestFastChatModel("your_openAI_key"); var chain = Set("Hello!") | LLM(model); Console.WriteLine(await chain.RunAsync("text")); ``` -------------------------------- ### Creating Basic LangChain .NET Chain with OpenAI Source: https://tryagi.github.io/LangChain/LangChain/wiki/HowToUseOpenAiProvider Demonstrates initializing an OpenAI model and creating a simple chain using `Set` and `LLM` to process a fixed input and print the output. Requires an OpenAI API key. ```C# using LangChain.Providers.OpenAI; using LangChain.Providers.OpenAI.Predefined; using tryAGI.OpenAI; using static LangChain.Chains.Chain; var model = new OpenAiLatestFastChatModel("your_openAI_key"); var chain = Set("Hello!", outputKey: "request") // set context variable `request` to "Hello" | LLM(model, inputKey: "request", outputKey: "text"); // get text from context variable `request`, pass it to the model and put result into `text` var result = await chain.RunAsync("text"); // execute chain and get `text` context variable Console.WriteLine(result); // Hello! How can I assist you today? ``` -------------------------------- ### Creating and Running SequentialChain in C# Source: https://tryagi.github.io/LangChain/LangChain/samples/SequentialChain This snippet demonstrates how to build a SequentialChain in LangChain .NET. It initializes two LlmChain instances with specific prompts and an OpenAI model, then combines them into a SequentialChain. The first chain takes a product as input and outputs a company name, which is then used as input for the second chain to generate a description. Finally, it executes the chain with a sample input and prints the result. ```C# using LangChain.Abstractions.Chains.Base; using LangChain.Chains.LLM; using LangChain.Chains.Sequentials; using LangChain.Prompts; using LangChain.Providers.OpenAI.Predefined; using LangChain.Schema; using var httpClient = new HttpClient(); var llm = new OpenAiLatestFastChatModel("api-key"); var firstTemplate = "What is a good name for a company that makes {product}?"; var firstPrompt = new PromptTemplate(new PromptTemplateInput(firstTemplate, new List(1) { "product" })); var chainOne = new LlmChain(new LlmChainInput(llm, firstPrompt) { Verbose = true, OutputKey = "company_name" }); var secondTemplate = "Write a 20 words description for the following company:{company_name}"; var secondPrompt = new PromptTemplate(new PromptTemplateInput(secondTemplate, new List(1) { "company_name" })); var chainTwo = new LlmChain(new LlmChainInput(llm, secondPrompt)); var overallChain = new SequentialChain(new SequentialChainInput( new IChain[] { chainOne, chainTwo }, new[] { "product" }, new[] { "company_name", "text" } )); var result = await overallChain.CallAsync(new ChainValues(new Dictionary(1) { { "product", "colourful socks" } })); Console.WriteLine(result.Value["text"]); Console.WriteLine("SequentialChain sample finished."); ``` -------------------------------- ### Setting up LangChain.Serve.OpenAI in C# Source: https://tryagi.github.io/LangChain/LangChain/samples/Serve.OpenAI This snippet demonstrates how to configure a .NET web application to serve LangChain models using the LangChain.Serve.OpenAI package. It includes adding the necessary services, creating an OpenAI chat model instance, and registering the model with the serving middleware. Optional steps for adding Swagger for API testing are also included. ```C# using LangChain.Providers.OpenAI; using LangChain.Providers.OpenAI.Predefined; using LangChain.Serve.OpenAI; var builder = WebApplication.CreateBuilder(); // 1. Add LangChainServe builder.Services.AddLangChainServeOpenAi(); // 2. Create a model var provider = new OpenAiProvider(Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? ""); var model = new OpenAiLatestSmartChatModel(provider); // 4. Optional. Add swagger to be able to test the API builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // 5. Configure LangChainServe app.UseLangChainServeOpenAi(options => { options.RegisterModel(model); }); // 6. Optional. Add swagger middleware app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My OpenAI API V1"); }); app.Run(); ``` -------------------------------- ### Implement RAG Pipeline with LangChain.Net, SQLite, and PDF Source: https://tryagi.github.io/LangChain/LangChain/wiki/RagWithOpenAiOllama This snippet sets up OpenAI and Ollama providers, initializes a SQLite vector database, loads and indexes a PDF file using a PDF loader and text splitter, defines a RAG prompt template, builds a chain to retrieve relevant document chunks and pass them to an LLM, and finally runs the chain with a sample question. ```C# using LangChain.Databases.Sqlite; using LangChain.Extensions; using LangChain.Providers; using LangChain.Providers.OpenAI.Predefined; using LangChain.DocumentLoaders; using LangChain.Providers.Ollama; using LangChain.Providers.OpenAI; using LangChain.Splitters.Text; using Ollama; using static LangChain.Chains.Chain; // prepare OpenAI embedding model var provider = new OpenAiProvider(apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY key is not set")); var embeddingModel = new TextEmbeddingV3SmallModel(provider); var llm = new OpenAiLatestFastChatModel(provider); // prepare Ollama with mistral model var providerOllama = new OllamaProvider(); var embeddingModelOllama = new OllamaEmbeddingModel(providerOllama, id: "nomic-embed-text"); var llmOllama = new OllamaChatModel(providerOllama, id: "llama3.1").UseConsoleForDebug(); using var vectorDatabase = new SqLiteVectorDatabase("vectors.db"); var vectorCollection = await vectorDatabase.AddDocumentsFromAsync( embeddingModel, dimensions: 1536, // Should be 1536 for TextEmbeddingV3SmallModel // First, specify the source to index. dataSource: DataSource.FromPath("E:\\AI\\Datasets\\Books\\Harry-Potter-Book-1.pdf"), collectionName: "harrypotter", // Second, configure how to extract chunks from the bigger document. textSplitter: new RecursiveCharacterTextSplitter( chunkSize: 500, // To pick the chunk size, estimate how much information would be required to capture most passages you'd like to ask questions about. Too many characters makes it difficult to capture semantic meaning, and too few characters means you are more likely to split up important points that are related. In general, 200-500 characters is good for stories without complex sequences of actions. chunkOverlap: 200)); // To pick the chunk overlap you need to estimate the size of the smallest piece of information. It may happen that one chunk ends with `Ron's hair` and the other one starts with `is red`.In this case, an embedding would miss important context, and not be generated propperly. With overlap the end of the first chunk will appear in the begining of the other, eliminating the problem. string promptText = @"Use the following pieces of context to answer the question at the end. If the answer is not in context then just say that you don't know, don't try to make up an answer. Keep the answer as short as possible. {context} Question: {question} Helpful Answer:"; var chain = Set("Who was drinking a unicorn blood?", outputKey: "question") // set the question | RetrieveDocuments( vectorCollection, embeddingModel, inputKey: "question", outputKey: "documents", amount: 5) // take 5 most similar documents | StuffDocuments(inputKey: "documents", outputKey: "context") // combine documents together and put them into context | Template(promptText) // replace context and question in the prompt with their values | LLM(llm); // send the result to the language model // get chain result var result = await chain.RunAsync("text"); Console.WriteLine(result); ``` -------------------------------- ### Using PromptTemplate with LlmChain in C# Source: https://tryagi.github.io/LangChain/LangChain/samples/Prompts Demonstrates how to create a basic text prompt using PromptTemplate, initialize an LlmChain with an LLM (OpenAI), and execute the chain using both CallAsync and RunAsync methods. Requires the OPENAI_API_KEY environment variable. ```C# using LangChain.Chains.LLM; using LangChain.Prompts; using LangChain.Providers.OpenAI.Predefined; using LangChain.Schema; var llm = new OpenAiLatestFastChatModel(Environment.GetEnvironmentVariable("OPENAI_API_KEY")!); var prompt = new PromptTemplate(new PromptTemplateInput( template: "What is a good name for a company that makes {product}?", inputVariables: ["product"])); var chain = new LlmChain(new LlmChainInput(llm, prompt)); var result = await chain.CallAsync(new ChainValues(new Dictionary { { "product", "colourful socks" } })); // The result is an object with a `text` property. Console.WriteLine(result.Value["text"]); // Since the LLMChain is a single-input, single-output chain, we can also call it with `run`. // This takes in a string and returns the `text` property. var result2 = await chain.RunAsync("colourful socks"); Console.WriteLine(result2); ``` -------------------------------- ### Initializing LLM Model - LangChain .NET - C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/UsingChainOutput Downloads a specific HuggingFace model file using the HuggingFaceModelDownloader and loads it into a LLamaSharp instruction model instance. This model instance is a prerequisite for building chains that utilize this particular language model. ```C# using LangChain.Providers.HuggingFace.Downloader; using LangChain.Providers.LLamaSharp; using static LangChain.Chains.Chain; // get model path var modelPath = await HuggingFaceModelDownloader.GetModelAsync( repository: "TheBloke/Thespis-13B-v0.5-GGUF", fileName: "thespis-13b-v0.5.Q2_K.gguf", version: "main"); // load model var model = LLamaSharpModelInstruction.FromPath(modelPath); // building a chain var prompt = @" You are an AI assistant that greets the world. World: Hello, Assistant! Assistant:"; ``` -------------------------------- ### Initializing and Using OpenAI Model - C# Source: https://tryagi.github.io/LangChain/LangChain/samples/OpenAI This snippet demonstrates how to initialize an OpenAI chat model using an API key retrieved from an environment variable and then use the model to generate text based on a prompt. The generated result is printed to the console. Requires the LangChain.Providers.OpenAI package. ```C# using LangChain.Providers; using LangChain.Providers.OpenAI.Predefined; var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY environment variable is not found."); var model = new OpenAiLatestFastChatModel(apiKey); var result = await model.GenerateAsync("What is a good name for a company that sells colourful socks?"); Console.WriteLine(result); ``` -------------------------------- ### Setting up ReAct Agent with Google Search Tool in C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/AgentWithOllamaReact This snippet demonstrates how to initialize an LLM (OpenAI or Ollama) and the Google Custom Search tool, then combine them into a LangChain.NET chain using the ReActAgentExecutor to enable the agent to perform searches. ```C# using LangChain.Chains.StackableChains.Agents.Tools.BuiltIn; using LangChain.Providers; using LangChain.Providers.OpenAI.Predefined; using static LangChain.Chains.Chain; // var provider = new OllamaProvider( // options: new RequestOptions // { // Stop = new[] { "Observation", "[END]" }, // add injection word `Observation` and `[END]` to stop the model(just as additional safety feature) // Temperature = 0 // }); // var llm = new OllamaChatModel(provider, id: "llama3.1").UseConsoleForDebug(); var apiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? throw new InvalidOperationException("OPENAI_API_KEY key is not set"); var llm = new OpenAiLatestFastChatModel(apiKey).UseConsoleForDebug(); // create a google search var searchApiKey = Environment.GetEnvironmentVariable("GOOGLE_SEARCH_API_KEY") ?? throw new InvalidOperationException("GOOGLE_SEARCH_API_KEY is not set"); var cx = Environment.GetEnvironmentVariable("GOOGLE_SEARCH_CX") ?? throw new InvalidOperationException("GOOGLE_SEARCH_CX is not set"); var searchTool = new GoogleCustomSearchTool(key: searchApiKey, cx: cx, resultsLimit: 1); var chain = Set("What is tryAGI/LangChain?") | ReActAgentExecutor(llm) // does the magic .UseTool(searchTool); // add the google search tool await chain.RunAsync(); ``` -------------------------------- ### Using ChatPromptTemplate with LlmChain in C# Source: https://tryagi.github.io/LangChain/LangChain/samples/Prompts Illustrates how to construct a chat-based prompt using ChatPromptTemplate with system and human messages. Shows how to initialize an LlmChain with the chat prompt and an LLM, enabling verbose output, and calling the chain with multiple input variables. ```C# var chatPrompt = ChatPromptTemplate.FromPromptMessages([ SystemMessagePromptTemplate.FromTemplate( "You are a helpful assistant that translates {input_language} to {output_language}."), HumanMessagePromptTemplate.FromTemplate("{text}") ]); var chainB = new LlmChain(new LlmChainInput(llm, chatPrompt) { Verbose = true }); var resultB = await chainB.CallAsync(new ChainValues(new Dictionary(3) { {"input_language", "English"}, {"output_language", "French"}, {"text", "I love programming"}, })); Console.WriteLine(resultB.Value["text"]); ``` -------------------------------- ### Define RAG Prompt Template (C#) Source: https://tryagi.github.io/LangChain/LangChain/wiki/RagWithOpenAiOllama Defines a multi-line string template for the Retrieval Augmented Generation prompt. It instructs the language model to use the provided context to answer the question, avoid making up answers, and keep the response concise. It includes `{context}` and `{question}` placeholders. ```C# string promptText = @"Use the following pieces of context to answer the question at the end. If the answer is not in context then just say that you don't know, don't try to make up an answer. Keep the answer as short as possible. {context} Question: {question} Helpful Answer:"; ``` -------------------------------- ### Configuring OpenAI Provider with Custom HttpClient Source: https://tryagi.github.io/LangChain/LangChain/wiki/HowToUseOpenAiProvider Shows how to initialize the `OpenAiProvider` and `OpenAiClient` with a custom `HttpClient` and `HttpClientHandler`, allowing for advanced network configuration like setting a custom base URI. ```C# var httpClientHandler = new HttpClientHandler(); using var httpClient = new HttpClient(httpClientHandler, disposeHandler: true); using var api = new OpenAiClient( httpClient, baseUri: new Uri("https://api.openai.com/v1/") // default value, can be omitted ); var provider = new OpenAiProvider(api); var tunedModel = new OpenAiLatestFastChatModel(provider); ``` -------------------------------- ### Initializing HTML Loader and Loading Document (C#) Source: https://tryagi.github.io/LangChain/LangChain/document-loaders/Html This snippet demonstrates how to create an instance of the HtmlLoader and use it to asynchronously load a document from a specified URL using the DataSource.FromUrl method. It then retrieves the first loaded document. ```C# var loader = new HtmlLoader(); var documents = await loader.LoadAsync(DataSource.FromUrl("https://en.wikipedia.org/wiki/Web_scraping")); var first = documents.First(); ``` -------------------------------- ### Defining Chain with Input/Output Keys - LangChain .NET - C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/UsingChainOutput Constructs a LangChain .NET chain by piping a Set link into an LLM link. The Set link stores the initial prompt string in the chain's context under the key "prompt", and the LLM link uses the value associated with the "prompt" key as input, storing its generated output under the key "result". ```C# var chain = Set(prompt, outputKey: "prompt") | LLM(model, inputKey: "prompt", outputKey: "result"); ``` -------------------------------- ### Initializing Ollama Provider and Model in C# Source: https://tryagi.github.io/LangChain/LangChain/wiki/AgentWithOllama This snippet shows how to set up the Ollama provider and a specific chat model (llama3.1) using LangChain .NET. It demonstrates creating a simple chain to send a prompt to the model and execute it asynchronously. ```C# using LangChain.Providers; using LangChain.Providers.Ollama; using Ollama; using static LangChain.Chains.Chain; var provider = new OllamaProvider( // url: "http://172.16.50.107:11434", // if you have ollama running on different computer/port. Default is "http://localhost:11434/api" ); var model = new OllamaChatModel(provider, id: "llama3.1").UseConsoleForDebug(); var chain = Set("What is tryAGI/LangChain? In 5 words") | LLM(model); await chain.RunAsync(); ```