LangChain.Chains.DataExtractionChain (LangChain v0.9.4)

Copy Markdown View Source

Defines an LLMChain for performing data extraction from a body of text.

Provide the schema for desired information to be parsed into. It is treated as though there are 0 to many instances of the data structure being described so information is returned as an array.

The result is always a list. If the LLM returns a single map instead of an array, it is automatically wrapped in a list so callers can rely on a consistent return type.

Originally based on:

Example

# JSONSchema definition of data we want to capture or extract.
schema_parameters = %{
  type: "object",
  properties: %{
    person_name: %{type: "string"},
    person_age: %{type: "number"},
    person_hair_color: %{type: "string"},
    dog_name: %{type: "string"},
    dog_breed: %{type: "string"}
  },
  required: []
}

# Model setup
{:ok, chat} = ChatOpenAI.new(%{temperature: 0})

# run the chain on the text information
data_prompt =
  "Alex is 5 feet tall. Claudia is 4 feet taller than Alex and jumps higher than him.
  Claudia is a brunette and Alex is blonde. Alex's dog Frosty is a labrador and likes to play hide and seek."

{:ok, result} = LangChain.Chains.DataExtractionChain.run(chat, schema_parameters, data_prompt)

# Example result
[
  %{
    "dog_breed" => "labrador",
    "dog_name" => "Frosty",
    "person_age" => nil,
    "person_hair_color" => "blonde",
    "person_name" => "Alex"
  },
  %{
    "dog_breed" => nil,
    "dog_name" => nil,
    "person_age" => nil,
    "person_hair_color" => "brunette",
    "person_name" => "Claudia"
  }
]

If the LLM returns a single map (e.g. when only one entity is found), it is wrapped in a list automatically:

# Single-entity result normalised to a list
[
  %{
    "person_name" => "Alex",
    "person_age" => nil,
    ...
  }
]

Accessing the LLMChain

run/4 returns only the extracted data. When more than the data is needed, for instance to log or report the token usage of the extraction, use run_chain/4 to get the executed LangChain.Chains.LLMChain and extract_result/1 to pull the data out of it:

{:ok, chain} = LangChain.Chains.DataExtractionChain.run_chain(chat, schema_parameters, data_prompt)

usage = LangChain.TokenUsage.get(chain.last_message)
{:ok, result} = LangChain.Chains.DataExtractionChain.extract_result(chain)

Callbacks

The LLMChain used for the extraction is built internally, so handlers registered on the llm itself are not used. Pass :callbacks to observe the run as it happens, which is the only way to see streamed deltas:

LangChain.Chains.DataExtractionChain.run(chat, schema_parameters, data_prompt,
  callbacks: [%{on_llm_token_usage: fn _chain, usage -> log_usage(usage) end}]
)

Handlers are registered on the internally run LLMChain, so the full set of LangChain.Chains.ChainCallbacks events is available.

The schema_parameters in the previous example can also be expressed using a list of LangChain.FunctionParam structs. An equivalent version looks like this:

alias LangChain.FunctionParam

schema_parameters = [
  FunctionParam.new!(%{name: "person_name", type: :string}),
  FunctionParam.new!(%{name: "person_age", type: :number}),
  FunctionParam.new!(%{name: "person_hair_color", type: :string}),
  FunctionParam.new!(%{name: "dog_name", type: :string}),
  FunctionParam.new!(%{name: "dog_breed", type: :string})
]
|> FunctionParam.to_parameters_schema()

Summary

Functions

Build the function to expose to the LLM that can be called for data extraction.

Return the extracted data from an executed LangChain.Chains.LLMChain that was run by run_chain/4.

Coerces the extraction tool's info argument to a list of rows.

Run the data extraction chain and return the extracted data.

Run the data extraction chain and return the executed LangChain.Chains.LLMChain.

Functions

build_extract_function(json_schema)

@spec build_extract_function(json_schema :: map()) ::
  LangChain.Function.t() | no_return()

Build the function to expose to the LLM that can be called for data extraction.

extract_result(chain)

@spec extract_result(LangChain.Chains.LLMChain.t()) ::
  {:ok, result :: [any()]} | {:error, LangChain.LangChainError.t()}

Return the extracted data from an executed LangChain.Chains.LLMChain that was run by run_chain/4.

Returns an error when the LLM did not respond with the expected extraction tool call.

normalize_extraction_info(info)

@spec normalize_extraction_info(term()) ::
  {:ok, [any()]} | {:error, LangChain.LangChainError.t()}

Coerces the extraction tool's info argument to a list of rows.

Models sometimes return one JSON object instead of a one-element array; run/4 uses this so callers always get {:ok, list}.

run(llm, json_schema, prompt, opts \\ [])

@spec run(
  LangChain.ChatModels.ChatOpenAI.t(),
  json_schema :: map(),
  prompt :: [any()],
  opts :: Keyword.t()
) :: {:ok, result :: [any()]} | {:error, LangChain.LangChainError.t()}

Run the data extraction chain and return the extracted data.

When the executed chain is needed as well, for instance to report token usage, use run_chain/4 with extract_result/1.

Accepts the same options as run_chain/4.

run_chain(llm, json_schema, prompt, opts \\ [])

@spec run_chain(
  LangChain.ChatModels.ChatOpenAI.t(),
  json_schema :: map(),
  prompt :: [any()],
  opts :: Keyword.t()
) ::
  {:ok, LangChain.Chains.LLMChain.t()}
  | {:error, LangChain.Chains.LLMChain.t(), LangChain.LangChainError.t()}

Run the data extraction chain and return the executed LangChain.Chains.LLMChain.

Use this instead of run/4 when the chain itself is needed and not just the extracted data. The chain gives access to the returned messages, token usage, and everything else recorded during execution.

{:ok, chain} = DataExtractionChain.run_chain(chat, schema_parameters, data_prompt)

# inspect the token usage of the extraction
usage = LangChain.TokenUsage.get(chain.last_message)

# get the extracted data from the chain
{:ok, result} = DataExtractionChain.extract_result(chain)

Follows the same return pattern as LangChain.Chains.LLMChain.run/2.

Options

  • :verbose - when true, enables verbose logging on the internally run LLMChain. Defaults to false.
  • :callbacks - a list of callback handler maps to register on the internally run LLMChain. See LangChain.Chains.ChainCallbacks for the available events. Defaults to [].