Langchain Agents機能について


はじめに

本日はLngchainの6つの機能のうちの1つであるChainsについて解説していきます。

Langchain Agentsとは

Langchain Agentsは、言語モデルに渡されたツールを用いてモデル自体が次にどのようなアクションをとるかを徹底し、実行し、観察し、完了するまで繰り返す機能です。具体的な使用例としては、Google検索をするツールとPythonのコードを実行するツールを渡すことで、最新の情報に関する質問が来た時には検索をし、Pythonの実行結果などを求められた時は実際にインタープリターで実行することができます。

Langchain Agentsの主な機能

Langchain Agentの機能は主に4つあります。

1. Tools

Toolsはエージェントというロボットが外界とやり取りをするための機能です。現在、多数の機能が用意されています。

現在、これだけの数の機能が用意されています。

Apify
Bash
Bing Search
ChatGPT Plugins
Google Search
Google Serper API
Human as a tool
IFTTT WebHooks
OpenWeatherMap API
Python REPL
Requests
Search Tools
SearxNG Search API
SerpAPI
Wikipedia API
Wolfram Alpha
Zapier Natural Language Actions API
Example with SimpleSequentialChain

2. Agents

Agentsはフロントの内容に応じてツールを使い分け、自動で開放を生成するロボットの機能です。現時点では4種類のAgentsが存在しています。

2.1. Zero-shot Reaction Description

Toolの説明文章などからツールを用いるか決めるエージェントです。このToolを用いるためには、Toolのデスクリプションがしっかりと書かれている必要があります。

2.2. React Docstore

文章を扱うことに特化したAgentです。具体的にはSearch Toolという文書自体を探すツールとPickup Toolという文章内で用語を探すToolを用いています。

2.3. Self-ask Quiz Search

質問に対する答えを事実に基づいて調べてくれるAgentです。Google検索APIなどのツールを用いて、検索結果などの何かしらの根拠となる中間的な回答を利用して、質問に対する回答を生成しています。

2.4. Conversational React Description

会話を扱うことに特化したエージェントです。具体的には、Memoryというモジュールを使って、過去のチャット上のやり取りを用いて最適な回答を生成しています。

3. Toolkits

Toolkitsは特定のユースケースに応じてツールを初期搭載したAgentsの機能です。

4. Agent Executor

Agent Executorはエージェントの行動を実行するための機能です。

Pythonを用いた具体的な実装方法

環境構築

ラングチェインを用いるためには、まずpip install langchainを実行してインストールします。

!pip3 install langchain openai

また、OpenAIのモデルを用いるためにはpip install openaiを実行します。ライブラリのインストールが完了したら、OpenAIのAPIキーを設定します。

import os

os.environ["OPENAI_API_KEY"] = "your openai_API_key"

1. Toolsの使い方

Toolの名前を格納した配列を作成し、「load_tools」という関数に渡して実行することで、Toolのオブジェクトを生成できます。

ここでは、Pythonを実行するためのToolを読み込んでいます。

それでは実行してみましょう。

from langchain.agents import load_tools

tool_names = ["python_repl"]
tools = load_tools(tool_names)
print(tools)

これに対する実行結果は次の通りです。

[PythonREPLTool(name='Python_REPL', description='A Python shell. Use this to execute python commands. Input should be a valid python command. If you want to see the output of a value, you should print it out with `print(...)`.', args_schema=None, return_direct=False, verbose=False, callbacks=None, callback_manager=None, tags=None, metadata=None, handle_tool_error=False, python_repl=PythonREPL(globals={'__name__': 'langchain.tools.python.tool', '__doc__': 'A tool for running python code in a REPL.', '__package__': 'langchain.tools.python', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7b4642a0cd00>, '__spec__': ModuleSpec(name='langchain.tools.python.tool', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7b4642a0cd00>, origin='/usr/local/lib/python3.10/dist-packages/langchain/tools/python/tool.py'), '__file__': '/usr/local/lib/python3.10/dist-packages/langchain/tools/python/tool.py', '__cached__': '/usr/local/lib/python3.10/dist-packages/langchain/tools/python/__pycache__/tool.cpython-310.pyc', '__builtins__': {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>, origin='built-in'), '__build_class__': <built-in function __build_class__>, '__import__': <built-in function __import__>, 'abs': <built-in function abs>, 'all': <built-in function all>, 'any': <built-in function any>, 'ascii': <built-in function ascii>, 'bin': <built-in function bin>, 'breakpoint': <built-in function breakpoint>, 'callable': <built-in function callable>, 'chr': <built-in function chr>, 'compile': <built-in function compile>, 'delattr': <built-in function delattr>, 'dir': <built-in function dir>, 'divmod': <built-in function divmod>, 'eval': <built-in function eval>, 'exec': <built-in function exec>, 'format': <built-in function format>, 'getattr': <built-in function getattr>, 'globals': <built-in function globals>, 'hasattr': <built-in function hasattr>, 'hash': <built-in function hash>, 'hex': <built-in function hex>, 'id': <built-in function id>, 'input': <bound method Kernel.raw_input of <google.colab._kernel.Kernel object at 0x7b46831502e0>>, 'isinstance': <built-in function isinstance>, 'issubclass': <built-in function issubclass>, 'iter': <built-in function iter>, 'aiter': <built-in function aiter>, 'len': <built-in function len>, 'locals': <built-in function locals>, 'max': <built-in function max>, 'min': <built-in function min>, 'next': <built-in function next>, 'anext': <built-in function anext>, 'oct': <built-in function oct>, 'ord': <built-in function ord>, 'pow': <built-in function pow>, 'print': <built-in function print>, 'repr': <built-in function repr>, 'round': <built-in function round>, 'setattr': <built-in function setattr>, 'sorted': <built-in function sorted>, 'sum': <built-in function sum>, 'vars': <built-in function vars>, 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': <class 'bool'>, 'memoryview': <class 'memoryview'>, 'bytearray': <class 'bytearray'>, 'bytes': <class 'bytes'>, 'classmethod': <class 'classmethod'>, 'complex': <class 'complex'>, 'dict': <class 'dict'>, 'enumerate': <class 'enumerate'>, 'filter': <class 'filter'>, 'float': <class 'float'>, 'frozenset': <class 'frozenset'>, 'property': <class 'property'>, 'int': <class 'int'>, 'list': <class 'list'>, 'map': <class 'map'>, 'object': <class 'object'>, 'range': <class 'range'>, 'reversed': <class 'reversed'>, 'set': <class 'set'>, 'slice': <class 'slice'>, 'staticmethod': <class 'staticmethod'>, 'str': <class 'str'>, 'super': <class 'super'>, 'tuple': <class 'tuple'>, 'type': <class 'type'>, 'zip': <class 'zip'>, '__debug__': True, 'BaseException': <class 'BaseException'>, 'Exception': <class 'Exception'>, 'TypeError': <class 'TypeError'>, 'StopAsyncIteration': <class 'StopAsyncIteration'>, 'StopIteration': <class 'StopIteration'>, 'GeneratorExit': <class 'GeneratorExit'>, 'SystemExit': <class 'SystemExit'>, 'KeyboardInterrupt': <class 'KeyboardInterrupt'>, 'ImportError': <class 'ImportError'>, 'ModuleNotFoundError': <class 'ModuleNotFoundError'>, 'OSError': <class 'OSError'>, 'EnvironmentError': <class 'OSError'>, 'IOError': <class 'OSError'>, 'EOFError': <class 'EOFError'>, 'RuntimeError': <class 'RuntimeError'>, 'RecursionError': <class 'RecursionError'>, 'NotImplementedError': <class 'NotImplementedError'>, 'NameError': <class 'NameError'>, 'UnboundLocalError': <class 'UnboundLocalError'>, 'AttributeError': <class 'AttributeError'>, 'SyntaxError': <class 'SyntaxError'>, 'IndentationError': <class 'IndentationError'>, 'TabError': <class 'TabError'>, 'LookupError': <class 'LookupError'>, 'IndexError': <class 'IndexError'>, 'KeyError': <class 'KeyError'>, 'ValueError': <class 'ValueError'>, 'UnicodeError': <class 'UnicodeError'>, 'UnicodeEncodeError': <class 'UnicodeEncodeError'>, 'UnicodeDecodeError': <class 'UnicodeDecodeError'>, 'UnicodeTranslateError': <class 'UnicodeTranslateError'>, 'AssertionError': <class 'AssertionError'>, 'ArithmeticError': <class 'ArithmeticError'>, 'FloatingPointError': <class 'FloatingPointError'>, 'OverflowError': <class 'OverflowError'>, 'ZeroDivisionError': <class 'ZeroDivisionError'>, 'SystemError': <class 'SystemError'>, 'ReferenceError': <class 'ReferenceError'>, 'MemoryError': <class 'MemoryError'>, 'BufferError': <class 'BufferError'>, 'Warning': <class 'Warning'>, 'UserWarning': <class 'UserWarning'>, 'EncodingWarning': <class 'EncodingWarning'>, 'DeprecationWarning': <class 'DeprecationWarning'>, 'PendingDeprecationWarning': <class 'PendingDeprecationWarning'>, 'SyntaxWarning': <class 'SyntaxWarning'>, 'RuntimeWarning': <class 'RuntimeWarning'>, 'FutureWarning': <class 'FutureWarning'>, 'ImportWarning': <class 'ImportWarning'>, 'UnicodeWarning': <class 'UnicodeWarning'>, 'BytesWarning': <class 'BytesWarning'>, 'ResourceWarning': <class 'ResourceWarning'>, 'ConnectionError': <class 'ConnectionError'>, 'BlockingIOError': <class 'BlockingIOError'>, 'BrokenPipeError': <class 'BrokenPipeError'>, 'ChildProcessError': <class 'ChildProcessError'>, 'ConnectionAbortedError': <class 'ConnectionAbortedError'>, 'ConnectionRefusedError': <class 'ConnectionRefusedError'>, 'ConnectionResetError': <class 'ConnectionResetError'>, 'FileExistsError': <class 'FileExistsError'>, 'FileNotFoundError': <class 'FileNotFoundError'>, 'IsADirectoryError': <class 'IsADirectoryError'>, 'NotADirectoryError': <class 'NotADirectoryError'>, 'InterruptedError': <class 'InterruptedError'>, 'PermissionError': <class 'PermissionError'>, 'ProcessLookupError': <class 'ProcessLookupError'>, 'TimeoutError': <class 'TimeoutError'>, 'open': <built-in function open>, 'copyright': Copyright (c) 2001-2022 Python Software Foundation.
All Rights Reserved.

Copyright (c) 2000 BeOpen.com.
All Rights Reserved.

Copyright (c) 1995-2001 Corporation for National Research Initiatives.
All Rights Reserved.

Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
All Rights Reserved., 'credits':     Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
    for supporting Python development.  See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object., '__IPYTHON__': True, 'display': <function display at 0x7b468aa348b0>, 'execfile': <function execfile at 0x7b467216a680>, 'runfile': <function runfile at 0x7b4672074310>, 'get_ipython': <bound method InteractiveShell.get_ipython of <google.colab._shell.Shell object at 0x7b4683150370>>}, 'ast': <module 'ast' from '/usr/lib/python3.10/ast.py'>, 'asyncio': <module 'asyncio' from '/usr/lib/python3.10/asyncio/__init__.py'>, 're': <module 're' from '/usr/lib/python3.10/re.py'>, 'sys': <module 'sys' (built-in)>, 'redirect_stdout': <class 'contextlib.redirect_stdout'>, 'StringIO': <class '_io.StringIO'>, 'Any': typing.Any, 'Dict': typing.Dict, 'Optional': typing.Optional, 'Field': <cyfunction Field at 0x7b46700918a0>, 'root_validator': <cyfunction root_validator at 0x7b46703cb2a0>, 'AsyncCallbackManagerForToolRun': <class 'langchain.callbacks.manager.AsyncCallbackManagerForToolRun'>, 'CallbackManagerForToolRun': <class 'langchain.callbacks.manager.CallbackManagerForToolRun'>, 'BaseTool': <class 'langchain.tools.base.BaseTool'>, 'PythonREPL': <class 'langchain.utilities.python.PythonREPL'>, '_get_default_python_repl': <function _get_default_python_repl at 0x7b46429e8c10>, 'sanitize_input': <function sanitize_input at 0x7b46429e8e50>, 'PythonREPLTool': <class 'langchain.tools.python.tool.PythonREPLTool'>, 'PythonAstREPLTool': <class 'langchain.tools.python.tool.PythonAstREPLTool'>}, locals=None), sanitize_input=True)]

このようにPythonのツールが読み込まれています。

自分のオリジナルのToolを作成したい場合は、「Tool」というクラスの中に名前(name)、実行する関数(func)、説明(description)の3つを記入することで対応できます。

ここまでのプログラムをまとめると、次の通りです。

from langchain.llms import OpenAI
from langchain.chains import LLMMathChain
from langchain.agents import Tool
from langchain.agents import load_tools

tool_names = ["python_repl"]
tools = load_tools(tool_names)

llm = OpenAI(model_name="text-davinci-003")
llm_math_chain = LLMMathChain(llm=llm, verbose=True)

tools.append(
    Tool(
        name="Calculator",
        func=llm_math_chain.run,
        description="useful for when you need to answer questions about math"
    ),
)
print(tools)
print(len(tools))

これに対する実行結果は次の通りです。

[PythonREPLTool(name='Python REPL', description='A Python shell. Use this to execute python commands. Input should be a valid python command. If you want to see the output of a value, you should print it out with `print(...)`.', args_schema=None, return_direct=False, verbose=False, callbacks=None, callback_manager=None, python_repl=PythonREPL(globals={'__name__': 'langchain.tools.python.tool', '__doc__': 'A tool for running python code in a REPL.', '__package__': 'langchain.tools.python', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f8d3d93cdf0>, '__spec__': ModuleSpec(name='langchain.tools.python.tool', loader=<_frozen_importlib_external.SourceFileLoader object at 0x7f8d3d93cdf0>, origin='/usr/local/lib/python3.10/dist-packages/langchain/tools/python/tool.py'), '__file__': '/usr/local/lib/python3.10/dist-packages/langchain/tools/python/tool.py', '__cached__': '/usr/local/lib/python3.10/dist-packages/langchain/tools/python/__pycache__/tool.cpython-310.pyc', '__builtins__': {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>, origin='built-in'), '__build_class__': <built-in function __build_class__>, '__import__': <built-in function __import__>, 'abs': <built-in function abs>, 'all': <built-in function all>, 'any': <built-in function any>, 'ascii': <built-in function ascii>, 'bin': <built-in function bin>, 'breakpoint': <built-in function breakpoint>, 'callable': <built-in function callable>, 'chr': <built-in function chr>, 'compile': <built-in function compile>, 'delattr': <built-in function delattr>, 'dir': <built-in function dir>, 'divmod': <built-in function divmod>, 'eval': <built-in function eval>, 'exec': <built-in function exec>, 'format': <built-in function format>, 'getattr': <built-in function getattr>, 'globals': <built-in function globals>, 'hasattr': <built-in function hasattr>, 'hash': <built-in function hash>, 'hex': <built-in function hex>, 'id': <built-in function id>, 'input': <bound method Kernel.raw_input of <google.colab._kernel.Kernel object at 0x7f8d7eba25f0>>, 'isinstance': <built-in function isinstance>, 'issubclass': <built-in function issubclass>, 'iter': <built-in function iter>, 'aiter': <built-in function aiter>, 'len': <built-in function len>, 'locals': <built-in function locals>, 'max': <built-in function max>, 'min': <built-in function min>, 'next': <built-in function next>, 'anext': <built-in function anext>, 'oct': <built-in function oct>, 'ord': <built-in function ord>, 'pow': <built-in function pow>, 'print': <built-in function print>, 'repr': <built-in function repr>, 'round': <built-in function round>, 'setattr': <built-in function setattr>, 'sorted': <built-in function sorted>, 'sum': <built-in function sum>, 'vars': <built-in function vars>, 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': <class 'bool'>, 'memoryview': <class 'memoryview'>, 'bytearray': <class 'bytearray'>, 'bytes': <class 'bytes'>, 'classmethod': <class 'classmethod'>, 'complex': <class 'complex'>, 'dict': <class 'dict'>, 'enumerate': <class 'enumerate'>, 'filter': <class 'filter'>, 'float': <class 'float'>, 'frozenset': <class 'frozenset'>, 'property': <class 'property'>, 'int': <class 'int'>, 'list': <class 'list'>, 'map': <class 'map'>, 'object': <class 'object'>, 'range': <class 'range'>, 'reversed': <class 'reversed'>, 'set': <class 'set'>, 'slice': <class 'slice'>, 'staticmethod': <class 'staticmethod'>, 'str': <class 'str'>, 'super': <class 'super'>, 'tuple': <class 'tuple'>, 'type': <class 'type'>, 'zip': <class 'zip'>, '__debug__': True, 'BaseException': <class 'BaseException'>, 'Exception': <class 'Exception'>, 'TypeError': <class 'TypeError'>, 'StopAsyncIteration': <class 'StopAsyncIteration'>, 'StopIteration': <class 'StopIteration'>, 'GeneratorExit': <class 'GeneratorExit'>, 'SystemExit': <class 'SystemExit'>, 'KeyboardInterrupt': <class 'KeyboardInterrupt'>, 'ImportError': <class 'ImportError'>, 'ModuleNotFoundError': <class 'ModuleNotFoundError'>, 'OSError': <class 'OSError'>, 'EnvironmentError': <class 'OSError'>, 'IOError': <class 'OSError'>, 'EOFError': <class 'EOFError'>, 'RuntimeError': <class 'RuntimeError'>, 'RecursionError': <class 'RecursionError'>, 'NotImplementedError': <class 'NotImplementedError'>, 'NameError': <class 'NameError'>, 'UnboundLocalError': <class 'UnboundLocalError'>, 'AttributeError': <class 'AttributeError'>, 'SyntaxError': <class 'SyntaxError'>, 'IndentationError': <class 'IndentationError'>, 'TabError': <class 'TabError'>, 'LookupError': <class 'LookupError'>, 'IndexError': <class 'IndexError'>, 'KeyError': <class 'KeyError'>, 'ValueError': <class 'ValueError'>, 'UnicodeError': <class 'UnicodeError'>, 'UnicodeEncodeError': <class 'UnicodeEncodeError'>, 'UnicodeDecodeError': <class 'UnicodeDecodeError'>, 'UnicodeTranslateError': <class 'UnicodeTranslateError'>, 'AssertionError': <class 'AssertionError'>, 'ArithmeticError': <class 'ArithmeticError'>, 'FloatingPointError': <class 'FloatingPointError'>, 'OverflowError': <class 'OverflowError'>, 'ZeroDivisionError': <class 'ZeroDivisionError'>, 'SystemError': <class 'SystemError'>, 'ReferenceError': <class 'ReferenceError'>, 'MemoryError': <class 'MemoryError'>, 'BufferError': <class 'BufferError'>, 'Warning': <class 'Warning'>, 'UserWarning': <class 'UserWarning'>, 'EncodingWarning': <class 'EncodingWarning'>, 'DeprecationWarning': <class 'DeprecationWarning'>, 'PendingDeprecationWarning': <class 'PendingDeprecationWarning'>, 'SyntaxWarning': <class 'SyntaxWarning'>, 'RuntimeWarning': <class 'RuntimeWarning'>, 'FutureWarning': <class 'FutureWarning'>, 'ImportWarning': <class 'ImportWarning'>, 'UnicodeWarning': <class 'UnicodeWarning'>, 'BytesWarning': <class 'BytesWarning'>, 'ResourceWarning': <class 'ResourceWarning'>, 'ConnectionError': <class 'ConnectionError'>, 'BlockingIOError': <class 'BlockingIOError'>, 'BrokenPipeError': <class 'BrokenPipeError'>, 'ChildProcessError': <class 'ChildProcessError'>, 'ConnectionAbortedError': <class 'ConnectionAbortedError'>, 'ConnectionRefusedError': <class 'ConnectionRefusedError'>, 'ConnectionResetError': <class 'ConnectionResetError'>, 'FileExistsError': <class 'FileExistsError'>, 'FileNotFoundError': <class 'FileNotFoundError'>, 'IsADirectoryError': <class 'IsADirectoryError'>, 'NotADirectoryError': <class 'NotADirectoryError'>, 'InterruptedError': <class 'InterruptedError'>, 'PermissionError': <class 'PermissionError'>, 'ProcessLookupError': <class 'ProcessLookupError'>, 'TimeoutError': <class 'TimeoutError'>, 'open': <built-in function open>, 'copyright': Copyright (c) 2001-2023 Python Software Foundation.
All Rights Reserved.

Copyright (c) 2000 BeOpen.com.
All Rights Reserved.

Copyright (c) 1995-2001 Corporation for National Research Initiatives.
All Rights Reserved.

Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
All Rights Reserved., 'credits':     Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
    for supporting Python development.  See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object., '__IPYTHON__': True, 'display': <function display at 0x7f8d8072fd90>, 'execfile': <function execfile at 0x7f8d64445900>, 'runfile': <function runfile at 0x7f8d6430f490>, '__pybind11_internals_v4_gcc_libstdcpp_cxxabi1013__': <capsule object NULL at 0x7f8d36eb4ff0>, '__pybind11_internals_v4_gcc_libstdcpp_cxxabi1014__': <capsule object NULL at 0x7f8d36eb5f20>, 'get_ipython': <bound method InteractiveShell.get_ipython of <google.colab._shell.Shell object at 0x7f8d7eba2680>>}, 'ast': <module 'ast' from '/usr/lib/python3.10/ast.py'>, 'sys': <module 'sys' (built-in)>, 'StringIO': <class '_io.StringIO'>, 'Any': typing.Any, 'Dict': typing.Dict, 'Optional': typing.Optional, 'Field': <cyfunction Field at 0x7f8d3f574930>, 'root_validator': <cyfunction root_validator at 0x7f8d5c37e330>, 'AsyncCallbackManagerForToolRun': <class 'langchain.callbacks.manager.AsyncCallbackManagerForToolRun'>, 'CallbackManagerForToolRun': <class 'langchain.callbacks.manager.CallbackManagerForToolRun'>, 'BaseTool': <class 'langchain.tools.base.BaseTool'>, 'PythonREPL': <class 'langchain.utilities.python.PythonREPL'>, '_get_default_python_repl': <function _get_default_python_repl at 0x7f8d3d917be0>, 'PythonREPLTool': <class 'langchain.tools.python.tool.PythonREPLTool'>, 'PythonAstREPLTool': <class 'langchain.tools.python.tool.PythonAstREPLTool'>}, locals=None), sanitize_input=True), Tool(name='Calculator', description='useful for when you need to answer questions about math', args_schema=None, return_direct=False, verbose=False, callbacks=None, callback_manager=None, func=<bound method Chain.run of LLMMathChain(memory=None, callbacks=None, callback_manager=None, verbose=True, llm_chain=LLMChain(memory=None, callbacks=None, callback_manager=None, verbose=False, prompt=PromptTemplate(input_variables=['question'], output_parser=None, partial_variables={}, template='Translate a math problem into a expression that can be executed using Python\'s numexpr library. Use the output of running this code to answer the question.\n\nQuestion: ${{Question with math problem.}}\n```text\n${{single line mathematical expression that solves the problem}}\n```\n...numexpr.evaluate(text)...\n```output\n${{Output of running the code}}\n```\nAnswer: ${{Answer}}\n\nBegin.\n\nQuestion: What is 37593 * 67?\n\n```text\n37593 * 67\n```\n...numexpr.evaluate("37593 * 67")...\n```output\n2518731\n```\nAnswer: 2518731\n\nQuestion: {question}\n', template_format='f-string', validate_template=True), llm=OpenAI(cache=None, verbose=False, callbacks=None, callback_manager=None, client=<class 'openai.api_resources.completion.Completion'>, model_name='text-davinci-003', temperature=0.7, max_tokens=256, top_p=1, frequency_penalty=0, presence_penalty=0, n=1, best_of=1, model_kwargs={}, openai_api_key=None, openai_api_base=None, openai_organization=None, batch_size=20, request_timeout=None, logit_bias={}, max_retries=6, streaming=False, allowed_special=set(), disallowed_special='all'), output_key='text'), llm=OpenAI(cache=None, verbose=False, callbacks=None, callback_manager=None, client=<class 'openai.api_resources.completion.Completion'>, model_name='text-davinci-003', temperature=0.7, max_tokens=256, top_p=1, frequency_penalty=0, presence_penalty=0, n=1, best_of=1, model_kwargs={}, openai_api_key=None, openai_api_base=None, openai_organization=None, batch_size=20, request_timeout=None, logit_bias={}, max_retries=6, streaming=False, allowed_special=set(), disallowed_special='all'), prompt=PromptTemplate(input_variables=['question'], output_parser=None, partial_variables={}, template='Translate a math problem into a expression that can be executed using Python\'s numexpr library. Use the output of running this code to answer the question.\n\nQuestion: ${{Question with math problem.}}\n```text\n${{single line mathematical expression that solves the problem}}\n```\n...numexpr.evaluate(text)...\n```output\n${{Output of running the code}}\n```\nAnswer: ${{Answer}}\n\nBegin.\n\nQuestion: What is 37593 * 67?\n\n```text\n37593 * 67\n```\n...numexpr.evaluate("37593 * 67")...\n```output\n2518731\n```\nAnswer: 2518731\n\nQuestion: {question}\n', template_format='f-string', validate_template=True), input_key='question', output_key='answer')>, coroutine=None)]
2
/usr/local/lib/python3.10/dist-packages/langchain/chains/llm_math/base.py:50: UserWarning: Directly instantiating an LLMMathChain with an llm is deprecated. Please instantiate with llm_chain argument or using the from_llm class method.
  warnings.warn(

実行した結果、このように「Pythonのツール」と「オリジナルのツール」の両方を格納した配列が作成できます。

2. Agentsの使い方

「DockDockGoの検索機能」と「LLMの計算機能」を活用し、特定のプロンプトを処理しています。「DockDockGo」は、Googleと同じようにウェブ検索可能なAPIを提供しています。複雑なAPIキーの取得手順は必要なく、無料で利用できる特徴があります。

「duckduckgo-search」をインストールするための手順を以下に示します。

!pip3 install duckduckgo-search

「現在の20代の日本人男性の平均的な腕立ての回数を教えて。そして、腕立ての回数は73回だったので、その差を2乗した結果を教えて。」というプロンプトを実行していきます。

from langchain.llms import OpenAI
from langchain.chains import LLMMathChain
from langchain.agents import Tool
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.tools import DuckDuckGoSearchRun

llm = OpenAI(model_name="text-davinci-003")

tool_names = ["llm-math"]
tools = load_tools(tool_names, llm=llm)

search = DuckDuckGoSearchRun()
tools.append(
    Tool(
        name="duckduckgo-search",
        func=search.run,
        description="useful for when you need to search for latest information in web"
    )
)

agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("""
現在の20代の日本人男性の平均的な腕立ての回数を教えて。
そして、腕立ての回数は73回だったので、その差を2乗した結果を教えて。
""")

これに対する実行結果は次の通りです。

> Entering new AgentExecutor chain...
 I need to find out the average number of arm push ups for 20-something Japanese men, and also the result of squaring the difference.
Action: duckduckgo-search
Action Input: "20代 日本人男性 平均的な腕立ての回数"
Observation: フィットネスメディアQOOLを運営するORGOは、「腕立て伏せの平均回数」に関する調査を実施し、その結果を126日に発表した。調査は16日~17 ... 腕立て伏せの男女で年齢別の平均回数2つ目は「30代」です。. 30代男性の平均回数は20回です。. 20代と比較すると筋肉・体力の衰えるスピードは若干緩やかになります。. この年代になると10代でスポーツをやっていた人とそうでなかった人の差がなくなり ... 腕立て伏せの男女別の平均回数【10回は楽勝だけど平均以上! ? 】 この記事のまとめ 胸を鍛えるのに効果的なトレーニング「腕立て伏せ」。 中学生や高校生の時に、友達と 何回できるか? 回数を競い合った人も多いですよね。 当サイト【とれらぼ】では、 男性と女性それぞれの腕立て伏せの平均回数 を紹介! また、毎日やった方が効果的なのか? 回数の目安についても解説! 胸の自重トレーニングで王道メニューといったら「腕立て伏せ」ですよね。 中学生や高校生の時、 友達と「何回できるか? 」競争したことはみんなあるはず! 過去に、腕立て伏せブームがありました。 筋肉番付や スポーツマンNO1決定戦で『3分間で何回できるかチャレンジ』があり、当時高校生だったぼくはテレビに釘付けになっていたのを覚えています。 18歳ぐらいの男の腕立て伏せの平均回数ってどれくらいですか?分かる人いませんか? ... 20歳男、171cm51kgです 食事が苦手で体重が増えません それ以前に、あまり体が大きくならない体質だと思います ただほんと子供みたいな体って言われて、体型で舐め ... 定番の「腕立て伏せ(プッシュアップ)」の応用編として、効果的な全身トレーニングに変えるやり方と種類を解説します。また20代~60代まで ...
Thought: Based on the information I found, it looks like the average number of arm push ups for 20-something Japanese men is 20.

Action: Calculator
Action Input: (73-20)^2
Observation: Answer: 2809
Thought: I now know the final answer
Final Answer: 20代の日本人男性の平均的な腕立ての回数は20回で、腕立ての回数は73回だったので、その差を2乗した結果は2809です。

> Finished chain.
20代の日本人男性の平均的な腕立ての回数は20回で、腕立ての回数は73回だったので、その差を2乗した結果は2809です。

実行した結果、DockDockGo Searchツールを用いて20代の平均腕立て回数を調べ、そのデータと演算ツールを使って私の腕立ての回数との差を2乗した結果を求めることができました。

3. Toolkitsの使い方

Toolkitsはたくさんあり、全てを紹介することはできないため、「create_python_agent」というPythonの実行に特化したツールを紹介します。

このToolkitを用いて「3つ目の素数は何?」と質問すると、Pythonのツールを用いて演算結果を返してくれます。

from langchain.llms import OpenAI
from langchain.agents.agent_toolkits import create_python_agent
from langchain.tools.python.tool import PythonREPLTool

llm = OpenAI(model_name="text-davinci-003")
agent_executor = create_python_agent(
    llm=llm,
    tool=PythonREPLTool(),
    verbose=True,
)
agent_executor.run("5の階乗は何?")

これに対する実行結果は次の通りです。


> Entering new AgentExecutor chain...
WARNING:langchain.utilities.python:Python REPL can execute arbitrary code. Use with caution.
 I need to use a math function to calculate the factorial of 5
Action: Python_REPL
Action Input: from math import factorial
Observation: 
Thought: I can now use the factorial function to calculate the factorial of 5
Action: Python_REPL
Action Input: print(factorial(5))
Observation: 120

Thought: I now know the final answer
Final Answer: 5の階乗は120です。

> Finished chain.
5の階乗は120です。

4. Agent Executorの使い方

Agent Executorはここまで紹介してきたような実行をするためのインスタンスになるため、先ほど紹介したソースコードにおける「agent_executor」にあたります。

# 「3. Toolkitsの使い方」と同じ内容。
from langchain.llms import OpenAI
from langchain.agents.agent_toolkits import create_python_agent
from langchain.tools.python.tool import PythonREPLTool

llm = OpenAI(model_name="text-davinci-003")
agent_executor = create_python_agent(
    llm=llm,
    tool=PythonREPLTool(),
    verbose=True,
)
agent_executor.run("5の階乗は何?")

最後に

これでLangChainの各機能についての概要説明は以上となります。

この記事が気に入ったらサポートをしてみませんか?