シンプルにLLMプログラミング ell : The Language Model Programming Library を試す
ellという、LLMを用いた言語モデルプログラミング(Language Model Program :LMP)を行うライブラリを試してみました。
Function callingなどベータ版の機能はあるものの、pythonの関数と同じ感覚でLLMを呼び出すことができ、加えて強力な可視化とバージョン管理の機能まで備えているようです。
従来のAPIコールを使った方法(OpenAI API,LangChain)
OpenAI APIを使った例
LLMを呼び出す方法は、たとえば一般的なOpenAIのAPIを使うと次のような感じでした:
import openai
openai.api_key = "your-api-key-here"
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Say hello to Sam Altman!"}
]
response = openai.ChatCompletion.create(
model="gpt-4",
messages=messages
)
print(response['choices'][0]['message']['content'])
LangChainの例
LangChainを使うとロジックはすっきりしますが、コードはまだ煩雑な印象ですよね:
from langchain import OpenAI, ConversationChain
llm = OpenAI(model_name="gpt-4", openai_api_key="your-api-key-here")
conversation = ConversationChain(llm=llm)
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Say hello to Sam Altman!"}
]
response = conversation.predict(input=messages[-1]["content"])
print(response)
ellを用いたLLMコーディング
これに対して、ellでは、システムプロンプトをpython関数の定義のdocstringに記述して、ユーザープロンプトは関数の返り値で記載して関数を呼び出すことで、LLMの呼び出しが普通の関数の感覚で使えます!:
import ell
@ell.simple(model="gpt-4")
def hello(name: str):
"""You are a helpful assistant.""" # システムプロンプト
return f"Say hello to {name}!" # ユーザープロンプト
print(hello("Sam Altman"))
@ell.simple()デコレータの使用 :
@ell.simpleデコレータを関数定義の前に加えることで、Python関数をLanguage Model Program(LMP)の形式に変換します。具体的には以下のことが行われます:
関数のdocstringがシステムメッセージになります。
関数の返り値がユーザーメッセージになります。
デコレータがAPIコールを処理し、モデルの応答を返します。
このアプローチにより、プロンプトが読みやすく、普通のコードユニットのように取り扱うことができます。
ell.system、ell.user、ell.assistantによるさらなる柔軟な記述
docstringを使う方法のほか、ell.system、ell.user、ell.assistantを用いて、明示的に各メッセージを定義することもできます。
import ell
@ell.simple(model="gpt-4")
def enthusiastic_hello(name: str):
return [
ell.system("You are a helpful assistant."),
ell.user(f"Say hello to {name}!"),
ell.assistant("Hello! I'd be happy to greet Sam Altman."),
ell.user("Great! Now do it more enthusiastically.")
]
print(enthusiastic_hello("Sam Altman"))
ellを用いることで、かなり読みやすいコードになりました。
入出力を通常のpythonの文字列操作と同じ感覚で操作できるので、プロンプトを動的に生成するコードもシンプルにいい感じで書けそうです。
import ell
import random
def get_random_adjective():
adjectives = ["enthusiastic", "cheerful", "warm", "friendly"]
return random.choice(adjectives)
@ell.simple(model="gpt-4")
def hello(name: str):
"""You are a helpful assistant."""
adjective = get_random_adjective()
return f"Say a {adjective} hello to {name}!"
print(hello("Sam Altman"))
@ell.complex()デコレータの使用 :
私はまだ試していませんが、@ell.simpleデコレータの代わりに@ell.complexデコレータを用いることで、シンプルなテキストだけでなくPydanticを用いた構造化された出力や、@ell.toolデコレータで定義したツール関数の呼び出し、テキストや画像を含むさまざまな種類の入出力、およびチャットの会話履歴を処理できるとのこと。
サンプルコードを眺めると、実現できることはlangchainとかと大差ないけれど、よりシンプルな記載方法でコーディングできそうです。
強力な可視化・バージョン管理ツール ell-studio
次のように初期化することで、LLM動作の可視化やバージョン管理機能を使うことができます。コードに加えた変更、入出力の履歴を追跡し、変更に応じたコミットメッセージを自動生成しローカル環境のデータベースに保存して履歴が確認できるので、プロンプトの試行錯誤が容易になりそうです。:
ell.init(store='./logdir', autocommit=True, verbose=True)
コンソール上にLLMへの入出力がリッチな感じで表示されるほか、ell-studioを実行することで、webブラウザ上のかっこいいGUIで視覚的により良いプロンプトを探索することもできます。
ell-studio -storage ./logdir
感想
ellはまだマイナーですが、とてもシンプルなコーディングできるので好印象を持ちました。また、langsmithのような可視化とバージョン管理ツールもすでに用意されているので、今後、LLMを活用したプログラムを書く場合の有力な選択肢になるのかもと思いました。みなさまもお試しあれ。