Class: Langchain::Assistant
- Inherits:
-
Object
- Object
- Langchain::Assistant
- Defined in:
- lib/langchain/assistants/assistant.rb
Overview
Assistants are Agent-like objects that leverage helpful instructions, LLMs, tools and knowledge to respond to user queries. Assistants can be configured with an LLM of your choice (currently only OpenAI), any vector search database and easily extended with additional tools.
Instance Attribute Summary collapse
-
#instructions ⇒ Object
Returns the value of attribute instructions.
-
#llm ⇒ Object
readonly
Returns the value of attribute llm.
-
#thread ⇒ Object
readonly
Returns the value of attribute thread.
-
#tools ⇒ Object
Returns the value of attribute tools.
Instance Method Summary collapse
-
#add_message(content: nil, role: "user", tool_calls: [], tool_call_id: nil) ⇒ Array<Langchain::Message>
Add a user message to the thread.
-
#add_message_and_run(content:, auto_tool_execution: false) ⇒ Array<Langchain::Message>
Add a user message to the thread and run the assistant.
-
#clear_thread! ⇒ Array
Delete all messages in the thread.
-
#initialize(llm:, thread:, tools: [], instructions: nil) ⇒ Assistant
constructor
Create a new assistant.
-
#run(auto_tool_execution: false) ⇒ Array<Langchain::Message>
Run the assistant.
-
#submit_tool_output(tool_call_id:, output:) ⇒ Array<Langchain::Message>
Submit tool output to the thread.
Constructor Details
#initialize(llm:, thread:, tools: [], instructions: nil) ⇒ Assistant
Create a new assistant
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/langchain/assistants/assistant.rb', line 16 def initialize( llm:, thread:, tools: [], instructions: nil ) raise ArgumentError, "Invalid LLM; currently only Langchain::LLM::OpenAI is supported" unless llm.instance_of?(Langchain::LLM::OpenAI) raise ArgumentError, "Thread must be an instance of Langchain::Thread" unless thread.is_a?(Langchain::Thread) raise ArgumentError, "Tools must be an array of Langchain::Tool::Base instance(s)" unless tools.is_a?(Array) && tools.all? { |tool| tool.is_a?(Langchain::Tool::Base) } @llm = llm @thread = thread @tools = tools @instructions = instructions # The first message in the thread should be the system instructions # TODO: What if the user added old messages and the system instructions are already in there? Should this overwrite the existing instructions? (role: "system", content: instructions) if instructions end |
Instance Attribute Details
#instructions ⇒ Object
Returns the value of attribute instructions.
7 8 9 |
# File 'lib/langchain/assistants/assistant.rb', line 7 def instructions @instructions end |
#llm ⇒ Object (readonly)
Returns the value of attribute llm.
7 8 9 |
# File 'lib/langchain/assistants/assistant.rb', line 7 def llm @llm end |
#thread ⇒ Object (readonly)
Returns the value of attribute thread.
7 8 9 |
# File 'lib/langchain/assistants/assistant.rb', line 7 def thread @thread end |
#tools ⇒ Object
Returns the value of attribute tools.
8 9 10 |
# File 'lib/langchain/assistants/assistant.rb', line 8 def tools @tools end |
Instance Method Details
#add_message(content: nil, role: "user", tool_calls: [], tool_call_id: nil) ⇒ Array<Langchain::Message>
Add a user message to the thread
43 44 45 46 |
# File 'lib/langchain/assistants/assistant.rb', line 43 def (content: nil, role: "user", tool_calls: [], tool_call_id: nil) = (role: role, content: content, tool_calls: tool_calls, tool_call_id: tool_call_id) thread.() end |
#add_message_and_run(content:, auto_tool_execution: false) ⇒ Array<Langchain::Message>
Add a user message to the thread and run the assistant
113 114 115 116 |
# File 'lib/langchain/assistants/assistant.rb', line 113 def (content:, auto_tool_execution: false) (content: content, role: "user") run(auto_tool_execution: auto_tool_execution) end |
#clear_thread! ⇒ Array
Delete all messages in the thread
131 132 133 134 |
# File 'lib/langchain/assistants/assistant.rb', line 131 def clear_thread! # TODO: If this a bug? Should we keep the "system" message? thread. = [] end |
#run(auto_tool_execution: false) ⇒ Array<Langchain::Message>
Run the assistant
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/langchain/assistants/assistant.rb', line 52 def run(auto_tool_execution: false) if thread..empty? Langchain.logger.warn("No messages in the thread") return end running = true while running # TODO: I think we need to look at all messages and not just the last one. case ( = thread..last).role when "system" # Do nothing running = false when "assistant" if .tool_calls.any? if auto_tool_execution run_tools(.tool_calls) else # Maybe log and tell the user that there's outstanding tool calls? running = false end else # Last message was from the assistant without any tools calls. # Do nothing running = false end when "user" # Run it! response = chat_with_llm if response.tool_calls # Re-run the while(running) loop to process the tool calls running = true (role: response.role, tool_calls: response.tool_calls) elsif response.chat_completion # Stop the while(running) loop and add the assistant's response to the thread running = false (role: response.role, content: response.chat_completion) end when "tool" # Run it! response = chat_with_llm running = true if response.tool_calls (role: response.role, tool_calls: response.tool_calls) elsif response.chat_completion (role: response.role, content: response.chat_completion) end end end thread. end |
#submit_tool_output(tool_call_id:, output:) ⇒ Array<Langchain::Message>
Submit tool output to the thread
123 124 125 126 |
# File 'lib/langchain/assistants/assistant.rb', line 123 def submit_tool_output(tool_call_id:, output:) # TODO: Validate that `tool_call_id` is valid (role: "tool", content: output, tool_call_id: tool_call_id) end |