Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for examples to title chain #191

Merged
merged 1 commit into from
Nov 10, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
add support for examples to title chain
- added module doc with examples
- support providing examples for consistency

closes #163
brainlid committed Nov 10, 2024
commit 93556fd9c6ffadd968b55d632b49ebb8b9ff8836
63 changes: 56 additions & 7 deletions lib/chains/text_to_title_chain.ex
Original file line number Diff line number Diff line change
@@ -2,6 +2,48 @@ defmodule LangChain.Chains.TextToTitleChain do
@moduledoc """
A convenience chain for turning a user's prompt text into a summarized title
for the anticipated conversation.

## Examples
A basic example that generates a title

llm = ChatOpenAI.new!(%{model: "gpt-3.5-turbo", stream: false, seed: 0})
user_text = "Let's start a new blog post about the magical properties of pineapple cookies."

%{
llm: llm,
input_text: user_text
}
|> TextToTitleChain.new!()
|> TextToTitleChain.evaluate()

#=> "Magical Properties of Pineapple Cookies Blog Post"

Want to get more consistent titles?

LLMs are pretty bad at following instructions for text length. However, we can
provide examples titles for the LLM to follow in format style and length. We
get the added benefit of getting more consistently formatted titles.

This is the same example, however now we provide other title examples to the
LLM to follow for consistency.

llm = ChatOpenAI.new!(%{model: "gpt-3.5-turbo", stream: false, seed: 0})
user_text = "Let's start a new blog post about the magical properties of
pineapple cookies."

%{
llm: llm,
input_text: user_text,
examples: [
"Blog Post: Making Delicious and Healthy Smoothies",
"System Email: Notifying Users of Planned Downtime"
]
}
|> TextToTitleChain.new!()
|> TextToTitleChain.evaluate()

#=> "Blog Post: Exploring the Magic of Pineapple Cookies"

"""
use Ecto.Schema
import Ecto.Changeset
@@ -10,7 +52,6 @@ defmodule LangChain.Chains.TextToTitleChain do
alias __MODULE__
alias LangChain.Chains.LLMChain
alias LangChain.LangChainError
alias LangChain.Message
alias LangChain.Utils
alias LangChain.Utils.ChainResult

@@ -19,12 +60,13 @@ defmodule LangChain.Chains.TextToTitleChain do
field :llm, :any, virtual: true
field :input_text, :string
field :fallback_title, :string, default: "New topic"
field :examples, {:array, :string}, default: []
field :verbose, :boolean, default: false
end

@type t :: %TextToTitleChain{}

@create_fields [:llm, :input_text, :fallback_title, :verbose]
@create_fields [:llm, :input_text, :fallback_title, :examples, :verbose]
@required_fields [:llm, :input_text]

@doc """
@@ -86,15 +128,22 @@ defmodule LangChain.Chains.TextToTitleChain do
def run(%TextToTitleChain{} = chain, opts \\ []) do
messages =
[
Message.new_system!(
"You expertly summarize a user's prompt into a short title or phrase to represent a conversation."
),
PromptTemplate.new!(%{
role: :system,
text: """
You expertly summarize the User Text into a short title or phrase to represent a conversation.

<%= if @examples != [] do %>Follow the style, approximate length, and format of the following examples:
<%= for example <- @examples do %>- <%= example %>
<% end %><% end %>
"""
}),
PromptTemplate.new!(%{
role: :user,
text: "Generate and return the title and nothing else. Prompt:\n<%= @input %>"
text: "Generate and return the title and nothing else. User Text:\n<%= @input %>"
})
]
|> PromptTemplate.to_messages!(%{input: chain.input_text})
|> PromptTemplate.to_messages!(%{input: chain.input_text, examples: chain.examples})

%{llm: chain.llm, verbose: chain.verbose}
|> LLMChain.new!()
22 changes: 22 additions & 0 deletions test/chains/text_to_title_chain_test.exs
Original file line number Diff line number Diff line change
@@ -94,5 +94,27 @@ defmodule LangChain.Chains.TextToTitleChainTest do

assert fallback_title == TextToTitleChain.evaluate(title_chain)
end

@tag live_call: true, live_open_ai: true
test "supports using examples", %{llm: llm, input_text: input_text} do
data = %{
llm: llm,
input_text: input_text,
fallback_title: "Default new title",
examples: [
"Blog Post: Making Delicious and Healthy Smoothies",
"System Email: Notifying Users of Planned Downtime"
],
verbose: true
}

result_title =
data
|> TextToTitleChain.new!()
|> TextToTitleChain.evaluate()

assert String.starts_with?(result_title, "Blog Post:")
assert String.contains?(result_title, "Pineapple")
end
end
end