@@ -143,8 +143,188 @@ Question: The endpoint https://api.chucknorris.io/jokes/random returns a joke ab
143143```
144144
145145
146- ### The PipInstall action
146+ ### Using the Mixin class
147+ The Mixin gives the option to use the pip install command from the ` code_it ` virtualenv manager, effectively adding package installation powers to your LLM inside langchain.
147148
149+ ** Note that the Mixin does not work as well as the task execution tool.**
150+
151+ The model quite often fails to use the new actions appropriately.
152+
153+ Code from: https://github.com/paolorechia/learn-langchain/blob/main/langchain_app/agents/coder_plot_chart_mixin_test.py
154+
155+ ``` python
156+ rom langchain.agents import (
157+ AgentExecutor,
158+ LLMSingleActionAgent,
159+ Tool,
160+ AgentOutputParser,
161+ )
162+ from langchain.prompts import StringPromptTemplate
163+ from langchain import LLMChain
164+ from langchain_app.models.vicuna_request_llm import VicunaLLM
165+ from langchain.schema import AgentAction, AgentFinish
166+
167+ from code_it.langchain.python_langchain_tool_mixin import LangchainPythonToolMixin
168+
169+ import re
170+ from typing import List, Union
171+
172+
173+ llm = VicunaLLM()
174+
175+ code_editor = LangchainPythonToolMixin()
176+
177+ tools = [
178+ code_editor.build_add_code_tool(),
179+ code_editor.build_run_tool(),
180+ code_editor.build_pip_install()
181+ ]
182+
183+ template = """ You're a programmer AI.
184+
185+ You are asked to code a certain task.
186+ You have access to a Code Editor, that can be used through the following tools:
187+
188+ {tools}
189+
190+
191+ You should ALWAYS think what to do next.
192+
193+ Use the following format:
194+
195+ Task: the input task you must implement
196+ Current Source Code: Your current code state that you are editing
197+ Thought: you should always think about what to code next
198+ Action: the action to take, should be one of [{tool_names} ]
199+ Action Input: the input to the action
200+ Observation: The result of your last action
201+ ... (this Thought/Action/Action Input/Source Code/Code Result can repeat N times)
202+
203+ Thought: I have finished the task
204+ Task Completed: the task has been implemented
205+
206+ Example task:
207+ Task: the input task you must implement
208+
209+ Thought: To start, we need to add the line of code to print 'hello world'
210+ Action: CodeEditorAddCode
211+ Action Input:
212+ print("hello world") end of llm ouput
213+ Observation:None
214+
215+ Thought: I have added the line of code to print 'hello world'. I should execute the code to test the output
216+ Action: CodeEditorRunCode
217+ Action Input:
218+
219+ Observation:Program Succeeded
220+ Stdout:b'hello world\n '
221+ Stderr:b''
222+
223+ Thought: The output is correct, it should be 'hello world'
224+ Action: None
225+ Action Input:
226+ Output is correct
227+
228+ Observation:None is not a valid tool, try another one.
229+
230+ Thought: I have concluded that the output is correct
231+ Task Completed: the task is completed.
232+
233+
234+ REMEMBER: don't install the same package more than once
235+
236+ Now we begin with a real task!
237+
238+ Task: {input}
239+ Source Code: {source_code}
240+
241+ {agent_scratchpad}
242+
243+ Thought:"""
244+
245+
246+ # Set up a prompt template
247+ class CodeEditorPromptTemplate (StringPromptTemplate ):
248+ # The template to use
249+ template: str
250+ code_editor: LangchainPythonToolMixin
251+ tools: List[Tool]
252+
253+ def format (self , ** kwargs ) -> str :
254+ # Get the intermediate steps (AgentAction, Observation tuples)
255+ # Format them in a particular way
256+ intermediate_steps = kwargs.pop(" intermediate_steps" )
257+ thoughts = " "
258+ for action, observation in intermediate_steps:
259+ thoughts += action.log
260+ thoughts += f " \n Observation: { observation} \n Thought: "
261+ # Set the agent_scratchpad variable to that value
262+ kwargs[" agent_scratchpad" ] = thoughts
263+ kwargs[" source_code" ] = code_editor.display_code()
264+ kwargs[" tools" ] = " \n " .join(
265+ [f " { tool.name} : { tool.description} " for tool in self .tools]
266+ )
267+ kwargs[" tool_names" ] = " , " .join([tool.name for tool in self .tools])
268+ return self .template.format(** kwargs)
269+
270+
271+ prompt = CodeEditorPromptTemplate(
272+ template = template,
273+ code_editor = code_editor,
274+ tools = tools,
275+ input_variables = [" input" , " intermediate_steps" ],
276+ )
277+
278+
279+ class CodeEditorOutputParser (AgentOutputParser ):
280+ def parse (self , llm_output : str ) -> Union[AgentAction, AgentFinish]:
281+ print (" llm output: " , llm_output, " end of llm ouput" )
282+ # Check if agent should finish
283+ if " Task Completed:" in llm_output:
284+ return AgentFinish(
285+ # Return values is generally always a dictionary with a single `output` key
286+ # It is not recommended to try anything else at the moment :)
287+ return_values = {" output" : llm_output},
288+ log = llm_output,
289+ )
290+ # Parse out the action and action input
291+ regex = r " Action\s * \d * \s * :( . *? ) \n Action\s * \d * \s * Input\s * \d * \s * :[\s ]* ( . * ) "
292+ match = re.search(regex, llm_output, re.DOTALL )
293+ if not match:
294+ raise ValueError (f " Could not parse LLM output: ` { llm_output} ` " )
295+ action = match.group(1 ).strip()
296+ action_input = match.group(2 )
297+ # Return the action and action input
298+ return AgentAction(
299+ tool = action, tool_input = action_input.strip(" " ).strip(' "' ), log = llm_output
300+ )
301+
302+
303+ output_parser = CodeEditorOutputParser()
304+
305+ llm_chain = LLMChain(llm = llm, prompt = prompt)
306+ llm = VicunaLLM()
307+
308+ tool_names = [tool.name for tool in tools]
309+ agent = LLMSingleActionAgent(
310+ llm_chain = llm_chain,
311+ output_parser = output_parser,
312+ stop = [" \n Observation:" ],
313+ allowed_tools = tool_names,
314+ )
315+
316+ agent_executor = AgentExecutor.from_agent_and_tools(
317+ agent = agent, tools = tools, verbose = True
318+ )
319+
320+ agent_executor.run(
321+ """
322+ Your job is to plot an example chart using matplotlib. Create your own random data.
323+ Run this code only when you're finished.
324+ DO NOT add code and run into a single step.
325+ """
326+ )
327+ ```
148328
149329
150330
0 commit comments