Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Langchain

lang_chain.livemd

Langchain

Mix.install([
  {:langchain, path: "~/Projects/elixir/langchain"}
])

Section

defmodule MyApp do
  @pretend_db %{
    1 => %{user_id: 1, name: "Michael Johnson", account_type: :trial, favorite_animal: "Horse"},
    2 => %{user_id: 2, name: "Joan Jett", account_type: :member, favorite_animal: "Aardvark"}
  }

  def get_user_info(user_id) do
    @pretend_db[user_id]
  end
end
alias LangChain.Function

function =
  Function.new!(%{
    name: "get_user_info",
    description: "Return JSON object of the current users's relevant information.",
    parameters_schema: %{
      type: "object",
      properties: %{
        user_id: %{
          type: "string",
          description: "The thing whose location is being requested."
        }
      },
      required: ["user_id"]
    },
    function: fn _args, %{user_id: user_id} = _context ->
      # Use the provided user_id context to call our Elixir function.
      # ChatGPT responses must be text. Convert the returned Map into JSON.
      Jason.encode!(MyApp.get_user_info(user_id))
    end
  })
alias LangChain.Message

messages = [
  Message.new_system!(~s(You are a helpful haiku poem generating assistant.
    ONLY generate a haiku for users with an `account_type` of "member".
    If the user has an `account_type` of "trial", say you can't do it,
    but you would love to help them if they upgrade and become a member.)),
  Message.new_user!("The current user is requesting a Haiku poem about their favorite animal.")
]
Application.put_env(:langchain, :google_ai_key, System.fetch_env!("LB_GOOGLEAI_API_KEY"))
alias LangChain.ChatModels.ChatGoogleAI

chat_model =
  ChatGoogleAI.new!(%{stream: true})
context = %{user_id: 2}
alias LangChain.Chains.LLMChain
alias LangChain.MessageDelta

callback = fn
  %MessageDelta{} = data ->
    # we received a piece of data
    IO.write(data.content)

  %Message{} = data ->
    # we received the finshed message once fully complete
    IO.puts("")
    IO.puts("")
    IO.inspect(data.content, label: "COMPLETED MESSAGE")
end

{:ok, updated_chain} =
  %{llm: chat_model, context: context, verbose: true}
  |> LLMChain.new!()
  # add the prompt message
  |> LLMChain.add_messages(messages)
  # add the functions that are available to the LLM
  |> LLMChain.add_callback(%{log: callback})
  |> LLMChain.add_tools([function])
  # keep running the LLM chain against the LLM if needed to evaluate
  # function calls and provide a response.
  |> LLMChain.run(while_needs_response: true)

updated_chain.last_message.content
alias LangChain.Chains.LLMChain

{:ok, updated_chain} =
  updated_chain
  |> LLMChain.add_messages([Message.new_user!("Give me two more please!")])
  # keep running the LLM chain against the LLM if needed to evaluate
  # function calls and provide a response.
  |> LLMChain.run(while_needs_response: true)

IO.puts(updated_chain.last_message.content)