### Install Dependencies and Set Up Environment Variables Source: https://github.com/brainlid/langchain/blob/main/CLAUDE.md Installs project dependencies using Mix and copies the example environment file. Remember to edit the .env file with your API keys. ```bash mix deps.get cp .env.example .env # Edit .env with your API keys ``` -------------------------------- ### ChatDeepSeek Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Example of initializing ChatDeepSeek with a specific model and temperature. ```elixir alias LangChain.ChatModels.ChatDeepSeek {:ok, deepseek} = ChatDeepSeek.new(%{ model: "deepseek-chat", temperature: 0.8 }) ``` -------------------------------- ### ChatGoogleAI Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Example of initializing ChatGoogleAI with a specific model and temperature. ```elixir alias LangChain.ChatModels.ChatGoogleAI {:ok, gemini} = ChatGoogleAI.new(%{ model: "gemini-1.5-pro", temperature: 0.8 }) ``` -------------------------------- ### ChatVertexAI Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Example of initializing ChatVertexAI with model, project ID, and region. ```elixir alias LangChain.ChatModels.ChatVertexAI {:ok, vertex} = ChatVertexAI.new(%{ model: "gemini-1.5-pro", project_id: "my-project", region: "us-central1" }) ``` -------------------------------- ### ChatMistralAI Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Example of initializing ChatMistralAI with a specific model and temperature. ```elixir alias LangChain.ChatModels.ChatMistralAI {:ok, mistral} = ChatMistralAI.new(%{ model: "mistral-large", temperature: 0.8 }) ``` -------------------------------- ### ContentPart Examples Source: https://github.com/brainlid/langchain/blob/main/_autodocs/types.md Examples demonstrating how to create different types of ContentPart, such as text, image from URL, and thinking blocks. ```elixir alias LangChain.Message.ContentPart # Text content text_part = ContentPart.text!("What is this?") # Image from URL image_part = ContentPart.image_url!("https://example.com/image.png") # Thinking block thinking_part = ContentPart.thinking!("Let me reason about this...") ``` -------------------------------- ### ChatAwsMantle Example with IAM Credentials Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Example of initializing ChatAwsMantle with a function that provides IAM credentials. ```elixir # With IAM credentials {:ok, gpt_oss} = ChatAwsMantle.new(%{ model: "openai.gpt-oss-120b", credentials: fn -> ExAws.Config.new() end }) ``` -------------------------------- ### Copy Example Environment File Source: https://github.com/brainlid/langchain/blob/main/_autodocs/configuration.md Copy the example .env file to .env for local development. This file is automatically loaded by the test suite. ```bash cp .env.example .env # Edit .env with your API keys ``` -------------------------------- ### ChatAwsMantle Example with Bearer Token Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Example of initializing ChatAwsMantle with a bearer token from environment variables. ```elixir alias LangChain.ChatModels.ChatAwsMantle # With bearer token {:ok, kimi} = ChatAwsMantle.new(%{ model: "moonshotai.kimi-k2.5", region: "us-east-1", api_key: System.fetch_env!("AWS_BEARER_TOKEN_BEDROCK") }) ``` -------------------------------- ### TokenUsage Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/types.md Example of calculating total tokens and estimated cost from a TokenUsage struct after running a chain. ```elixir alias LangChain.TokenUsage # After running a chain usage = chain.token_usage total_tokens = usage.input + usage.output cost = (usage.input * 0.003 + usage.output * 0.004) / 1000 ``` -------------------------------- ### FunctionParam Simple Parameters Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/content-parts-and-tools.md Example of creating a simple string parameter for a function. ```APIDOC ## FunctionParam Simple Parameters Example ### Description Creating a simple string parameter. ### Code ```elixir alias LangChain.FunctionParam param = FunctionParam.new!(%{name: "query", type: :string, required: true, description: "Search query"}) ``` ``` -------------------------------- ### ToolResult Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/types.md Example of creating a ToolResult struct with details about a completed tool execution. ```elixir alias LangChain.Message.ToolResult result = ToolResult.new!(%{ tool_call_id: "call_123", name: "search", content: "Found 10 results for 'Elixir programming'" }) ``` -------------------------------- ### Web Search Tool Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/tools.md An example of how to create a custom web search tool using LangChain's Function tool. This tool takes a search query and an optional maximum number of results. ```APIDOC ## Web Search Tool Example ### Description Example of a custom web search tool. ### Tool Definition ```elixir alias LangChain.Function search_tool = Function.new!(%{ name: "web_search", description: "Search the web for information", parameters_schema: %{ type: "object", properties: %{ query: %{ type: "string", description: "Search query" }, max_results: %{ type: "integer", description: "Maximum results to return" } }, required: ["query"] }, function: fn %{"query" => query, "max_results" => limit}, _context -> # Implement your search logic results = perform_web_search(query, limit) {:ok, Jason.encode!(results)} end }) ``` ``` -------------------------------- ### ChatOpenAI Constructor and Examples Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Initializes a ChatOpenAI model instance with specified attributes and demonstrates creating instances for different models and configurations. ```elixir ChatOpenAI.new(attrs \\ %{}) ``` ```elixir alias LangChain.ChatModels.ChatOpenAI {:ok, gpt4} = ChatOpenAI.new(%{ model: "gpt-4-turbo", temperature: 0.7, stream: true }) {:ok, gpt35} = ChatOpenAI.new(%{ model: "gpt-3.5-turbo", temperature: 0.5 }) ``` -------------------------------- ### Creating and Matching Trajectories Source: https://github.com/brainlid/langchain/blob/main/_autodocs/types.md Example of how to create a Trajectory from a chain and check if it matches a specific pattern of tool calls. ```elixir alias LangChain.Trajectory trajectory = Trajectory.from_chain(chain) # trajectory.tool_calls contains the sequence of function calls made # Check if trajectory matches expected pattern Trajectory.matches?(trajectory, [ %{name: "search", arguments: nil}, %{name: "summarize", arguments: nil} ]) ``` -------------------------------- ### ChatGrok Constructor and Examples Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Initializes a ChatGrok model instance with specified attributes and demonstrates creating instances for different Grok models. ```elixir ChatGrok.new(attrs \\ %{}) ``` ```elixir alias LangChain.ChatModels.ChatGrok {:ok, grok4} = ChatGrok.new(%{ model: "grok-4", temperature: 0.7 }) {:ok, grok_mini} = ChatGrok.new(%{ model: "grok-3-mini", temperature: 0.5 }) ``` -------------------------------- ### Copy and Edit Environment File Source: https://github.com/brainlid/langchain/blob/main/README.md Copy the example environment file to .env and edit it with your private API keys. The .env file is automatically loaded by the test suite. ```shell cp .env.example .env # Edit .env with your private API keys ``` -------------------------------- ### Elixir Starting DynamicSupervisor Child Source: https://github.com/brainlid/langchain/blob/main/CLAUDE.md Use `DynamicSupervisor.start_child/2` to start a child process managed by a `DynamicSupervisor`, referencing the supervisor by its registered name. ```elixir DynamicSupervisor.start_child(MyApp.MyDynamicSup, child_spec) ``` -------------------------------- ### ToolResult Examples Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/content-parts-and-tools.md Demonstrates creating ToolResult objects for simple text, multi-modal content with images, and error results. ```APIDOC ## ToolResult Examples ### Description Examples of creating `ToolResult` objects with different content types. ### Code ```elixir # Simple text result result = ToolResult.new!(%{tool_call_id: "call_123", name: "search", content: "Found 42 matching results"}) # Multi-modal result with image result_with_image = ToolResult.new!(%{tool_call_id: "call_456", name: "analyze_image", content: [ContentPart.text!("Analysis: Contains a cat"), ContentPart.image_url!("https://example.com/image.png")]}) # Error result error_result = ToolResult.new!(%{tool_call_id: "call_789", name: "fetch_data", content: "Connection timeout", is_error: true}) ``` ``` -------------------------------- ### Initialize ChatPerplexity Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Constructs a new ChatPerplexity client. Set the model ID and temperature. An API key is required but not shown in this example. ```elixir alias LangChain.ChatModels.ChatPerplexity {:ok, perplexity} = ChatPerplexity.new(%{ model: "pplx-7b-chat", temperature: 0.8 }) ``` -------------------------------- ### FunctionParam Enum Parameter Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/content-parts-and-tools.md Example of creating a string parameter with a predefined list of enum values. ```APIDOC ## FunctionParam Enum Parameter Example ### Description Creating an enum parameter. ### Code ```elixir param = FunctionParam.new!(%{name: "sort_by", type: :string, enum_values: ["relevance", "price", "date"], description: "Sort order"}) ``` ``` -------------------------------- ### ChatAnthropic Constructor and Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Initializes a ChatAnthropic model instance with specified attributes and demonstrates creating a streaming-enabled instance. ```elixir ChatAnthropic.new(attrs \\ %{}) ``` ```elixir alias LangChain.ChatModels.ChatAnthropic {:ok, claude} = ChatAnthropic.new(%{ model: "claude-3-7-sonnet-20250219", temperature: 0.8, stream: true }) ``` -------------------------------- ### FunctionParam Array Parameter Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/content-parts-and-tools.md Example of creating an array parameter with a specified item type. ```APIDOC ## FunctionParam Array Parameter Example ### Description Creating an array parameter. ### Code ```elixir param = FunctionParam.new!(%{name: "tags", type: :array, item_type: "string", description: "List of tags"}) ``` ``` -------------------------------- ### Elixir Tool Context-Based Authorization Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/tools.md Demonstrates how to use context information, such as `user_id`, within a tool's function to enforce authorization and control access to resources. ```elixir function: fn %{"resource_id" => res_id}, %{"user_id" => user_id} -> if MyApp.Resources.owns?(user_id, res_id) do {:ok, "Resource data..."} else {:error, "You don't have permission to access this resource"} end end ``` -------------------------------- ### Database Query Tool Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/tools.md An example of a custom database query tool. This tool allows querying a specific table with a WHERE clause, and can be scoped by user ID. ```APIDOC ## Database Query Tool Example ### Description Example of a custom database query tool. ### Tool Definition ```elixir alias LangChain.Function alias LangChain.Message.ToolResult alias LangChain.Message.ContentPart db_tool = Function.new!(%{ name: "query_database", description: "Query application database", parameters_schema: %{ type: "object", properties: %{ table: %{type: "string", description: "Table name"}, query: %{type: "string", description: "Where clause"} }, required: ["table"] }, function: fn %{"table" => table, "query" => where_clause}, %{"user_id" => user_id} -> # Query with user scoping case MyApp.Database.query(table, where_clause, user_id: user_id) do {:ok, results} -> # Return structured result with data {:ok, Jason.encode!(results), results} {:error, reason} -> {:error, "Database error: #{reason}"} end end }) ``` ``` -------------------------------- ### Adding Callbacks to LLMChain Source: https://github.com/brainlid/langchain/blob/main/_autodocs/types.md An example demonstrating how to define and add custom callback handlers to an LLMChain. This allows for logging or custom actions during chain execution. ```elixir handler = %{ on_message_processed: fn chain, message -> IO.puts("Message: #{message.content}") end, on_tool_call: fn chain, tool_call -> IO.puts("Executing: #{tool_call.name}") end, on_error: fn chain, error -> IO.puts("Error: #{error.message}") end } chain = LLMChain.new!(%{llm: ChatOpenAI.new!()}) |> LLMChain.add_callback(handler) ``` -------------------------------- ### Configure Kubernetes Environment Variables Source: https://github.com/brainlid/langchain/blob/main/_autodocs/configuration.md Define environment variables for a Kubernetes deployment. This example shows how to reference secrets stored in Kubernetes. ```yaml env: - name: OPENAI_API_KEY valueFrom: secretKeyRef: name: langchain-secrets key: openai-api-key ``` -------------------------------- ### ChatAnthropic Constructor and Extended Thinking Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Initializes a ChatAnthropic model instance and demonstrates configuring extended thinking capabilities for complex reasoning. ```elixir ChatAnthropic.new(attrs \\ %{}) ``` ```elixir {:ok, claude} = ChatAnthropic.new(%{ model: "claude-3-7-sonnet-20250219", thinking: %{ type: "enabled", budget_tokens: 5000 } }) ``` -------------------------------- ### Combining Trajectory Matching Modes Source: https://github.com/brainlid/langchain/blob/main/guides/evaluation.md Compose mode and argument options freely to define specific matching criteria for tool call sequences. This example checks for a specific call with partial argument matching, ignoring order and extra calls. ```elixir # At least called get_forecast with city=Paris, ignore order and extra args Trajectory.matches?(trajectory, [ %{name: "get_forecast", arguments: %{"city" => "Paris"}} ], mode: :superset, args: :subset) ``` -------------------------------- ### Start LLMChain in Async Task for LiveView Source: https://github.com/brainlid/langchain/blob/main/usage-rules.md Initiates an LLMChain run within an asynchronous Task to prevent blocking the LiveView process. Store the task reference for potential cancellation. ```elixir task = Task.async(fn -> LLMChain.run(chain, mode: :while_needs_response) end) # Store task reference to allow cancellation if needed socket = assign(socket, :llm_task, task) ``` -------------------------------- ### FunctionParam Object Parameter Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/content-parts-and-tools.md Example of creating a nested object parameter with its own properties. ```APIDOC ## FunctionParam Object Parameter Example ### Description Creating a nested object parameter. ### Code ```elixir param = FunctionParam.new!(%{name: "filters", type: :object, description: "Search filters", object_properties: [FunctionParam.new!(%{name: "min_price", type: :number, description: "Minimum price"}), FunctionParam.new!(%{name: "max_price", type: :number, description: "Maximum price"})}}) ``` ``` -------------------------------- ### Create and Format a PromptTemplate Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/utilities.md Use PromptTemplate.new! to create a template with placeholders and input variables. Then, use PromptTemplate.format_prompt to render the template with specific values. Ensure the template and input_variables are correctly defined. ```elixir alias LangChain.PromptTemplate template = PromptTemplate.new!(%{ template: "Answer this question: {question}", input_variables: ["question"] }) rendered = PromptTemplate.format_prompt(template, %{"question" => "What is Elixir?"}) IO.puts(rendered) # => "Answer this question: What is Elixir?" ``` -------------------------------- ### Create a system message Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/message.md Use `new_system!` to create a system message, which primes the LLM with instructions. System messages must have content and typically appear first. ```elixir Message.new_system!("You are a helpful assistant that specializes in mathematics") ``` -------------------------------- ### Initialize OpenAI Chat Models Source: https://github.com/brainlid/langchain/blob/main/_autodocs/configuration.md Instantiate OpenAI chat models. Choose between fast and cheap 'gpt-3.5-turbo', powerful 'gpt-4-turbo', or the latest 'gpt-4o'. ```elixir # Fast and cheap ChatOpenAI.new(%{model: "gpt-3.5-turbo"}) # Powerful and flexible ChatOpenAI.new(%{model: "gpt-4-turbo"}) # Latest and best ChatOpenAI.new(%{model: "gpt-4o"}) ``` -------------------------------- ### Email Tool Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/tools.md An example of a custom email tool for sending email messages. It requires recipient, subject, and body parameters. ```APIDOC ## Email Tool Example ### Description Example of a custom email tool. ### Tool Definition ```elixir alias LangChain.Function email_tool = Function.new!(%{ name: "send_email", description: "Send an email message", parameters_schema: %{ type: "object", properties: %{ to: %{type: "string", description: "Recipient email"}, subject: %{type: "string", description: "Email subject"}, body: %{type: "string", description: "Email body"} }, required: ["to", "subject", "body"] }, function: fn %{"to" => to, "subject" => subject, "body" => body}, context -> case MyApp.Email.send(to, subject, body) do :ok -> {:ok, "Email sent successfully to #{to}"} {:error, reason} -> {:error, "Failed to send email: #{reason}"} end end }) ``` ``` -------------------------------- ### LLMChain Fallback Execution Source: https://github.com/brainlid/langchain/blob/main/_autodocs/INDEX.md Demonstrates running an LLMChain with a list of fallback LLMs. ```elixir LLMChain.run(chain, with_fallbacks: [fallback_llm]) ``` -------------------------------- ### LLMChain with Tools and Streaming Mode Source: https://github.com/brainlid/langchain/blob/main/_autodocs/INDEX.md Sets up an LLMChain with a ChatOpenAI model, adds tools, a user message, and runs in a specific streaming mode. ```elixir LLMChain.new!(%{llm: ChatOpenAI.new!()}) |> LLMChain.add_tools([tool1, tool2]) |> LLMChain.add_message(Message.new_user!("...")) |> LLMChain.run(mode: :while_needs_response) ``` -------------------------------- ### Elixir LLMChain with Multiple Tools Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/tools.md Demonstrates how to compose multiple tools (Calculator, search, weather, database, email) within an LLMChain, allowing the LLM to automatically select and use them for complex tasks. ```elixir alias LangChain.Chains.LLMChain alias LangChain.Message {:ok, chain} = LLMChain.new!(%{llm: ChatOpenAI.new!()}) |> LLMChain.add_tools([ Calculator.new!(), search_tool, weather_tool, database_tool, email_tool ]) |> LLMChain.add_message(Message.new_system!("You have access to various tools...")) |> LLMChain.add_message(Message.new_user!("Complex task requiring multiple tools")) |> LLMChain.run(mode: :while_needs_response) # LLM will automatically choose which tools to call ``` -------------------------------- ### Initialize ChatBumblebee Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Constructs a new ChatBumblebee client for self-hosted models. Requires specifying the Nx.Serving module and chat template format. ```elixir alias LangChain.ChatModels.ChatBumblebee {:ok, local_model} = ChatBumblebee.new(%{ serving: MyApp.ModelServing, template_format: :mistral }) ``` -------------------------------- ### Initialize ChatOpenAI with Top-P Source: https://github.com/brainlid/langchain/blob/main/_autodocs/configuration.md Create a new ChatOpenAI instance with Top-P (nucleus sampling) to control response diversity. This is an alternative to temperature sampling. ```elixir ChatOpenAI.new(%{top_p: 0.9}) ``` -------------------------------- ### Get Most Recent Assistant Message from LLMChain Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/llm-chain.md Retrieves the most recent message sent by the assistant from the chain's history. ```elixir assistant_message(chain) ``` -------------------------------- ### Initialize xAI Grok Chat Models Source: https://github.com/brainlid/langchain/blob/main/_autodocs/configuration.md Instantiate xAI Grok chat models. Options include 'grok-4' for reasoning and humor, and 'grok-3-mini' for faster, cheaper requests. ```elixir ChatGrok.new(%{model: "grok-4"}) ChatGrok.new(%{model: "grok-3-mini"}) # Faster, cheaper ``` -------------------------------- ### FunctionParam Constructor Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/content-parts-and-tools.md Demonstrates the usage of the `FunctionParam.new/1` and `FunctionParam.new!/1` constructors. ```APIDOC ## FunctionParam Constructor ### Description Constructing `FunctionParam` objects using `new/1` and `new!/1`. ### Constructor ```elixir FunctionParam.new(attrs) FunctionParam.new!(attrs) {:ok, t()} | {:error, Ecto.Changeset.t()} t() | no_return() ``` ``` -------------------------------- ### Get Last Message from LLMChain Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/llm-chain.md Retrieves the last message in the chain's message history. Useful for accessing the most recent interaction. ```elixir last = LLMChain.last_message(chain) IO.puts(last.content) ``` -------------------------------- ### Initialize ChatOpenAI with Streaming Enabled Source: https://github.com/brainlid/langchain/blob/main/_autodocs/configuration.md Create a new ChatOpenAI instance with streaming enabled. This allows for receiving responses as they are generated, improving perceived latency. ```elixir ChatOpenAI.new(%{stream: true}) ``` -------------------------------- ### Elixir DynamicSupervisor Child Specification Source: https://github.com/brainlid/langchain/blob/main/CLAUDE.md When using Elixir's `DynamicSupervisor`, provide a name in the child spec. This name is then used to start children. ```elixir {DynamicSupervisor, name: MyApp.MyDynamicSup} ``` -------------------------------- ### Initialize LLMChain with Custom Context Source: https://github.com/brainlid/langchain/blob/main/_autodocs/configuration.md Create an LLMChain instance and pass custom context data, such as user ID and permissions, to be available to tools. ```elixir LLMChain.new!(%{ llm: ChatOpenAI.new!(), custom_context: %{ user_id: 123, account_id: 456, permissions: ["read", "write"] } }) ``` -------------------------------- ### Handling LangChain Errors Source: https://github.com/brainlid/langchain/blob/main/_autodocs/types.md Example of how to handle different types of errors returned by LLMChain.run, specifically focusing on rate limiting and general error messages. ```elixir alias LangChain.LangChainError case LLMChain.run(chain) do {:error, %LangChainError{type: "rate_limit"}} -> # Handle rate limiting {:error, %LangChainError{message: msg}} -> # Handle with message end ``` -------------------------------- ### ChatGoogleAI Constructor Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Initializes a ChatGoogleAI client. Defaults to 'gemini-1.5-pro' model. ```elixir ChatGoogleAI.new(attrs \\ %{}) {:ok, t()} | {:error, Ecto.Changeset.t()} ``` -------------------------------- ### Get Custom Context from LLMChain Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/llm-chain.md Retrieves the custom context map associated with the chain. This can store arbitrary data relevant to the chain's state. ```elixir get_custom_context(chain) ``` -------------------------------- ### Pass LLM-Specific Options Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/function.md Provide provider-specific options to influence LLM behavior, such as caching configurations. This example shows setting ephemeral cache control for Anthropic. ```elixir fn = Function.new!(%{ name: "expensive_computation", description: "Runs expensive calculation", parameters_schema: %{type: "object"}, function: fn _args, _context -> {:ok, "Result: 42"} end, options: [ # Anthropic prompt caching configuration cache_control: [type: "ephemeral"] ] }) ``` -------------------------------- ### Message Roles Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/message.md Defines the different roles a message can have within a conversation, including System, User, Assistant, and Tool, along with their specific rules and usage examples. ```APIDOC ## Message Roles ### System (`:system`) Primes the LLM with system instructions and behavior guidelines. **Rules** - Must have content - Typically appears first in a conversation - Usually only one system message per conversation **Example** ```elixir Message.new_system!("You are a helpful assistant that specializes in mathematics") ``` ### User (`:user`) Represents input from the user or application. **Rules** - Must have content (text or ContentParts) - Can include images, files via ContentParts - Can appear multiple times in a conversation **Example** ```elixir Message.new_user!("What is the capital of France?") # Multi-modal user message Message.new_user!([ ContentPart.text!("Analyze this image:"), ContentPart.image_url!("https://example.com/chart.png") ]) ``` ### Assistant (`:assistant`) Represents a response from the LLM. **Rules** - Content is optional (can be streamed in deltas) - Can contain tool_calls requesting function execution - May contain ContentParts with text, images, or thinking blocks **Example** ```elixir Message.new_assistant!([ ContentPart.text!("Here's my analysis:"), ContentPart.thinking!("Let me think about this...") ]) ``` ### Tool (`:tool`) Returns results from executed functions/tools. **Rules** - Must have tool_results - One tool message per batch of tool executions - Contains results of multiple tool calls if they were in parallel **Example** ```elixir Message.new_tool!([ ToolResult.new!(%{ tool_call_id: "search_1", name: "search", content: "Found 42 results for 'Python'" }) ]) ``` ``` -------------------------------- ### Initialize ChatOpenAI with Temperature Source: https://github.com/brainlid/langchain/blob/main/_autodocs/configuration.md Create a new ChatOpenAI instance with a specified temperature to control response randomness. Lower values are more deterministic, higher values are more creative. ```elixir ChatOpenAI.new(%{temperature: 0.7}) ``` -------------------------------- ### Function Execution with Context Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/function.md Demonstrates a function that uses context to access user-specific data. The function queries user data scoped by `user_id` from the context. ```elixir fn = Function.new!(%{ name: "get_user_profile", description: "Get current user profile", parameters_schema: %{ type: "object", properties: %{field: %{type: "string"}}, required: ["field"] }, function: fn %{"field" => field}, %{"user_id" => user_id} = _context -> # Query user data scoped by user_id case MyApp.Users.get_field(user_id, field) do {:ok, value} -> {:ok, Jason.encode!(%{field => value})} {:error, reason} -> {:error, reason} end end }) ``` -------------------------------- ### Initialize ChatBumblebee Model Source: https://github.com/brainlid/langchain/blob/main/README.md Initialize a ChatBumblebee model with specified serving configuration, template format, and receive timeout. Streaming is enabled. ```elixir ChatBumblebee.new!(%{ serving: @serving_name, template_format: @template_format, receive_timeout: @receive_timeout, stream: true }) ``` -------------------------------- ### LLMChain Run Modes Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chains.md Demonstrates the different modes for running an LLMChain: :single, :while_needs_response, :step, :until_success, and :until_tool_used. ```APIDOC ## LLMChain Run Modes ### `:single` (default) Execute once - pass messages to LLM, get response. ```elixir {:ok, chain} = LLMChain.new!(%{llm: ChatOpenAI.new!()}) |> LLMChain.add_message(Message.new_user!("Hello")) |> LLMChain.run() # mode: :single is default ``` ### `:while_needs_response` Loop until LLM stops requesting tools. ```elixir {:ok, chain} = LLMChain.new!(%{llm: ChatOpenAI.new!()}) |> LLMChain.add_tools([search_tool]) |> LLMChain.add_message(Message.new_user!("Research topic X")) |> LLMChain.run(mode: :while_needs_response) ``` ### `:step` Execute a single step and return control. ```elixir {:ok, chain} = LLMChain.new!(%{llm: ChatOpenAI.new!()}) |> LLMChain.run(mode: :step) ``` ### `:until_success` Loop until receiving a response without errors. ```elixir {:ok, chain} = LLMChain.new!(%{llm: ChatOpenAI.new!()}) |> LLMChain.run(mode: :until_success, max_runs: 5) ``` ### `:until_tool_used` Loop until a specific tool is called (see LLMChain documentation for details). ``` -------------------------------- ### Create LLMChain (Raise on Error) Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/llm-chain.md Constructs a new LLMChain instance, raising an error if the configuration is invalid. Use this for simpler setups where errors should halt execution. ```elixir alias LangChain.Chains.LLMChain chain = LLMChain.new!(%{ llm: ChatOpenAI.new!(%{model: "gpt-4"}) }) ``` -------------------------------- ### Streaming Chat with ChatOpenAI Source: https://github.com/brainlid/langchain/blob/main/_autodocs/INDEX.md Initializes a ChatOpenAI model with streaming enabled and then runs an LLMChain. ```elixir {:ok, model} = ChatOpenAI.new(%{stream: true}) LLMChain.new!(%{llm: model}) |> LLMChain.run() ``` -------------------------------- ### Initialize ChatOpenAI with Seed for Deterministic Output Source: https://github.com/brainlid/langchain/blob/main/_autodocs/configuration.md Create a new ChatOpenAI instance with a seed for deterministic output. This ensures that the same prompt will produce the same response, useful for testing and reproducibility. ```elixir ChatOpenAI.new(%{seed: 42}) ``` -------------------------------- ### ChatVertexAI Constructor Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Initializes a ChatVertexAI client for enterprise Google AI. ```elixir ChatVertexAI.new(attrs \\ %{}) {:ok, t()} | {:error, Ecto.Changeset.t()} ``` -------------------------------- ### Elixir Tool Parameter Validation Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/tools.md Shows how to implement a `parse_args` function within a tool definition to validate input parameters, such as checking for a valid email format. ```elixir parse_args: fn args -> email = args["email"] if String.match?(email, ~r/@/) do {:ok, args} else {:error, "Invalid email format"} end end ``` -------------------------------- ### Initialize Calculator Tool Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/tools.md Initializes the Calculator tool. This tool is used for performing mathematical calculations. ```elixir alias LangChain.Tools.Calculator calc_tool = Calculator.new!() ``` -------------------------------- ### Argument Pre-processing with parse_args Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/function.md Utilize `parse_args` to validate and transform raw arguments from the LLM before function execution. This example validates a 'limit' parameter, ensuring it does not exceed 100. ```elixir fn = Function.new!(%{ name: "search_users", description: "Search for users", parameters_schema: %{ type: "object", properties: %{ query: %{type: "string"}, limit: %{type: "integer"} }, required: ["query"] }, parse_args: fn args -> # Validate and normalize arguments limit = Map.get(args, "limit", 10) if limit > 100 do {:error, "limit cannot exceed 100"} else {:ok, %{"query" => args["query"], "limit" => limit}} end end, function: fn %{"query" => q, "limit" => l}, _context -> {:ok, "Found #{l} users matching #{q}"} end }) ``` -------------------------------- ### Add LangChain Dependency to Mix Project Source: https://github.com/brainlid/langchain/blob/main/README.md Install the LangChain Elixir library by adding it to your project's dependencies in `mix.exs`. Ensure you are using Elixir 1.17 or higher. ```elixir def deps do [ {:langchain, "~> 0.8.0"} ] end ``` -------------------------------- ### ChatOllamaAI Constructor Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Initializes a ChatOllamaAI client for locally hosted models. ```elixir ChatOllamaAI.new(attrs \\ %{}) {:ok, t()} | {:error, Ecto.Changeset.t()} ``` -------------------------------- ### Basic xAI Grok-4 Usage with LLMChain Source: https://github.com/brainlid/langchain/blob/main/README.md Instantiate a ChatGrok model with specified parameters and create an LLMChain. Then, add a user message and run the chain to get a response. ```elixir alias LangChain.ChatModels.ChatGrok alias LangChain.Chains.LLMChain alias LangChain.Message # Basic Grok-4 usage {:ok, grok} = ChatGrok.new(%{model: "grok-4", temperature: 0.7}) {:ok, chain} = LLMChain.new!(%{llm: grok}) |> LLMChain.add_message(Message.new_user!("Explain quantum computing")) |> LLMChain.run() # Fast and efficient Grok-3-mini {:ok, mini_grok} = ChatGrok.new(%{model: "grok-3-mini", temperature: 0.8}) ``` -------------------------------- ### Initialize ChatOllamaAI Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Constructs a new ChatOllamaAI client. Specify the model name and Ollama server endpoint. ```elixir alias LangChain.ChatModels.ChatOllamaAI {:ok, llama} = ChatOllamaAI.new(%{ model: "llama2:7b", endpoint: "http://localhost:11434" }) ``` -------------------------------- ### Initialize LLMChain with Verbose Logging Source: https://github.com/brainlid/langchain/blob/main/_autodocs/configuration.md Create an LLMChain instance with verbose logging enabled. This provides detailed output during chain execution, useful for debugging. ```elixir LLMChain.new!(%{ llm: ChatOpenAI.new!(), verbose: true }) ``` -------------------------------- ### Get Trajectory Calls by Tool Name Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/utilities.md Retrieves all tool calls made to a specific tool within a trajectory. Useful for counting or analyzing calls to a particular tool. ```elixir search_calls = Trajectory.calls_by_name(trajectory, "search") IO.puts("Search was called #{length(search_calls)} times") ``` -------------------------------- ### Parameter Definition using FunctionParam List Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/function.md Defines function parameters using a list of `FunctionParam` structs for simple cases. This example sets a reminder with text and optional days. ```elixir alias LangChain.FunctionParam fn = Function.new!(%{ name: "set_reminder", description: "Set a reminder", parameters: [ FunctionParam.new!(%{ name: "text", type: :string, required: true, description: "Reminder text" }), FunctionParam.new!(%{ name: "days", type: :integer, description: "Days until reminder" }) ], function: fn %{"text" => text, "days" => days}, _context -> {:ok, "Reminder set for #{days} days"} end }) ``` -------------------------------- ### Run Live API Tests for OpenAI Source: https://github.com/brainlid/langchain/blob/main/_autodocs/README.md Execute tests that involve live API calls to OpenAI. This requires API keys to be configured and incurs costs. ```bash mix test --include live_openai ``` -------------------------------- ### New RoutingChain and Execution Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chains.md Initializes a RoutingChain with a language model and defined routes, then executes it with an input to determine the appropriate route and result. ```elixir alias LangChain.Chains.RoutingChain alias LangChain.Routing.PromptRoute routes = [ PromptRoute.new!(%{name: "math", description: "Mathematical problems", prompt: "Solve: {input}"}), PromptRoute.new!(%{name: "language", description: "Grammar and writing", prompt: "Check grammar: {input}"}) ] {:ok, {route_name, result}} = RoutingChain.new!(%{llm: ChatOpenAI.new!(), routes: routes}) |> RoutingChain.run("What is 2+2?") IO.puts("Route: #{route_name}") # => "Route: math" ``` -------------------------------- ### LangChain.Ex: Custom Callback Handler Example Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chains.md Defines and applies a custom callback handler to an LLMChain. The handler processes messages, tool calls, and errors, printing relevant information. ```elixir alias LangChain.Chains.LLMChain handler = %{ on_message_processed: fn _chain, message -> IO.puts("[Message] #{message.role}: #{message.content}") end, on_tool_call: fn _chain, tool_call -> IO.puts("[Tool Call] #{tool_call.name}") end, on_error: fn _chain, error -> IO.puts("[Error] #{error.message}") end } LLMChain.new!(%{llm: ChatOpenAI.new!()}) |> LLMChain.add_callback(handler) |> LLMChain.run() ``` -------------------------------- ### Create LLMChain with Configuration Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/llm-chain.md Constructs a new LLMChain instance with specified attributes. Use this when you need to handle potential configuration errors gracefully. ```elixir alias LangChain.Chains.LLMChain alias LangChain.ChatModels.ChatOpenAI {:ok, chain} = LLMChain.new(%{ llm: ChatOpenAI.new!(%{model: "gpt-4"}), verbose: true }) ``` -------------------------------- ### Trajectory Mismatch Failure Example Source: https://github.com/brainlid/langchain/blob/main/guides/evaluation.md Illustrates the informative failure message produced by `assert_trajectory` on mismatch, showing expected vs. actual tool calls with mode and argument details. ```elixir Trajectory mismatch (mode: strict, args: exact) Expected: [%{name: "search", arguments: %{"query" => "weather"}}] Actual: [%{name: "search", arguments: %{"query" => "news"}}] ``` -------------------------------- ### ChatBumblebee Constructor Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/chat-models.md Initializes a ChatBumblebee client for self-hosted models using Bumblebee/Nx. Requires serving module and template format. ```APIDOC ## ChatBumblebee Constructor ### Description Initializes a ChatBumblebee client for self-hosted models via Elixir's Bumblebee/Nx. This allows running models locally. ### Method `ChatBumblebee.new(attrs \ %{})` ### Parameters #### Common Parameters - **serving** (module()) - Required - Nx.Serving module hosting the model. - **template_format** (atom()) - Required - Chat template (e.g., :mistral, :zephyr). - **stream** (boolean()) - Optional - Enable streaming. Defaults to false. ### Example ```elixir alias LangChain.ChatModels.ChatBumblebee {:ok, local_model} = ChatBumblebee.new(%{ serving: MyApp.ModelServing, template_format: :mistral }) ``` ``` -------------------------------- ### Expose Custom Elixir Function to LLM Source: https://github.com/brainlid/langchain/blob/main/README.md Integrate custom Elixir functions into LangChain, allowing LLMs to call them with provided context. This example demonstrates a function that returns the location of an item. ```elixir alias LangChain.Function alias LangChain.Message alias LangChain.Chains.LLMChain alias LangChain.ChatModels.ChatOpenAI alias LangChain.Utils.ChainResult # map of data we want to be passed as `context` to the function when # executed. custom_context = %{ "user_id" => 123, "hairbrush" => "drawer", "dog" => "backyard", "sandwich" => "kitchen" } # a custom Elixir function made available to the LLM custom_fn = Function.new!(%{ name: "custom", description: "Returns the location of the requested element or item.", parameters_schema: %{ type: "object", properties: %{ thing: %{ type: "string", description: "The thing whose location is being requested." } }, required: ["thing"] }, function: fn %{"thing" => thing} = _arguments, context -> # our context is a pretend item/location location map {:ok, context[thing]} end }) # create and run the chain {:ok, updated_chain} = LLMChain.new!(%{ llm: ChatOpenAI.new!(), custom_context: custom_context, verbose: true }) |> LLMChain.add_tools(custom_fn) |> LLMChain.add_message(Message.new_user!("Where is the hairbrush located?")) |> LLMChain.run(mode: :while_needs_response) # print the LLM's answer IO.puts(ChainResult.to_string!(updated_chain)) # => "The hairbrush is located in the drawer." ``` -------------------------------- ### Define a Custom Tool with Schema and Business Logic Source: https://github.com/brainlid/langchain/blob/main/_autodocs/README.md Create a custom tool named 'my_tool' with a description, parameter schema, and a function that executes business logic and returns a JSON-encoded result. ```elixir Function.new!(%{ name: "my_tool", description: "Does something useful", parameters_schema: %{type: "object", properties: %{}}, function: fn args, context -> result = my_business_logic(args, context) {:ok, Jason.encode!(result)} end }) ``` -------------------------------- ### Handle Errors with String Messages Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/function.md Functions should return errors as clear string messages to enhance LLM understanding. This example demonstrates returning a specific error message for division by zero. ```elixir fn = Function.new!(%{ name: "divide", description: "Divide two numbers", parameters_schema: %{ type: "object", properties: %{ numerator: %{type: "number"}, denominator: %{type: "number"} }, required: ["numerator", "denominator"] }, function: fn %{"numerator" => n, "denominator" => 0}, _context -> {:error, "Division by zero is not allowed"} end, function: fn %{"numerator" => n, "denominator" => d}, _context -> {:ok, n / d} end }) ``` -------------------------------- ### Perform Deep Research Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/tools.md Example of performing a deep research query using the DeepResearch tool. It initializes the tool, creates a research request, and then executes the research, printing the content of the result. ```elixir alias LangChain.Tools.DeepResearch alias LangChain.Tools.DeepResearch.ResearchRequest research_tool = DeepResearch.new!(%{ model: "claude-3-5-sonnet-20241022" }) request = ResearchRequest.new!(%{ query: "Latest developments in quantum computing", max_depth: 5 }) {:ok, result} = DeepResearch.research(research_tool, request) IO.puts(result.content) ``` -------------------------------- ### Ecto Query Preloading Associations Source: https://github.com/brainlid/langchain/blob/main/CLAUDE.md Always preload Ecto associations in queries when they will be accessed in templates to avoid N+1 query problems. Example shows accessing user email from a message. ```elixir message.user.email ``` -------------------------------- ### Elixir DynamicSupervisor Child Specification Source: https://github.com/brainlid/langchain/blob/main/AGENTS.md When using OTP primitives like DynamicSupervisor, provide a name in the child spec. This allows starting children using the supervisor's module name. ```elixir {DynamicSupervisor, name: MyApp.MyDynamicSup} ``` ```elixir DynamicSupervisor.start_child(MyApp.MyDynamicSup, child_spec) ``` -------------------------------- ### Create Text ContentPart Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/content-parts-and-tools.md Constructs a ContentPart for text. Use the '!' version for immediate error raising. ```elixir alias LangChain.Message.ContentPart text_part = ContentPart.text!("Explain quantum computing") ``` -------------------------------- ### Track Token Usage Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/utilities.md Access the token_usage field from a chain object to get a TokenUsage struct. Sum the input and output tokens for the total, and account for cached tokens which may be nil. ```elixir usage = chain.token_usage total = usage.input + usage.output cached = (usage.cache_read_input_tokens || 0) IO.puts("Tokens: #{total} (#{cached} cached)") ``` -------------------------------- ### Create File ContentPart Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/content-parts-and-tools.md Constructs a ContentPart for a file, specifying the file path and its MIME type. ```elixir file_part = ContentPart.file!("document.pdf", "application/pdf") ``` -------------------------------- ### ChatOpenAI with Cloudflare Workers AI Source: https://github.com/brainlid/langchain/blob/main/README.md Configure and use ChatOpenAI with Cloudflare Workers AI by setting the custom endpoint and API token. This example demonstrates a basic chat completion without streaming. ```elixir alias LangChain.ChatModels.ChatOpenAI alias LangChain.Chains.LLMChain alias LangChain.Message account_id = System.fetch_env!("CLOUDFLARE_ACCOUNT_ID") api_key = System.fetch_env!("CLOUDFLARE_API_TOKEN") endpoint = "https://api.cloudflare.com/client/v4/accounts/#{account_id}/ai/v1/chat/completions" {:ok, chat} = ChatOpenAI.new(%{ endpoint: endpoint, api_key: api_key, model: "@cf/moonshotai/kimi-k2.6", temperature: 0, seed: 0, stream: false }) {:ok, updated_chain} = %{llm: chat} |> LLMChain.new!() |> LLMChain.add_messages([ Message.new_system!("You answer with a single word."), Message.new_user!("Reply with the single word: PONG") ]) |> LLMChain.run() ``` -------------------------------- ### run(chain, opts \ []) Source: https://github.com/brainlid/langchain/blob/main/_autodocs/api-reference/llm-chain.md Executes the LLMChain once, passing messages to the LLM and receiving a response. Supports various execution modes and fallback LLMs. ```APIDOC ## `run(chain, opts \ [])` ### Description Executes the chain once - passes messages to LLM and receives response. Supports different execution modes and fallback LLMs. ### Method `run/2` or `run/3` depending on options ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **chain** (t()) - Required - The LLMChain to execute - **mode** (atom()) - Optional - Execution mode: `:single`, `:while_needs_response`, `:until_success`, `:until_tool_used`, `:step`. Defaults to `:single`. - **with_fallbacks** ([ChatModel.t()]) - Optional - List of fallback LLMs to try on failure. Defaults to `[]`. - **before_fallback** (function()) - Optional - Callback to modify chain before using fallback. Defaults to `nil`. - **stream** (boolean()) - Optional - Override chat model streaming setting. ### Returns - `{:ok, updated_chain :: t()}` - Execution completed successfully - `{:error, error :: LangChainError.t()}` - Execution failed ### Example ```elixir {:ok, updated_chain} = chain |> LLMChain.add_message(Message.new_user!("What is 2+2?")) |> LLMChain.run() # Access the assistant's response last_message = List.last(updated_chain.messages) IO.puts(last_message.content) ``` ```