Skip to content

Commit 4c2d1f7

Browse files
authored
Update README.md
1 parent 76601e8 commit 4c2d1f7

1 file changed

Lines changed: 181 additions & 1 deletion

File tree

README.md

Lines changed: 181 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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"\nObservation: {observation}\nThought: "
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*:(.*?)\nAction\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=["\nObservation:"],
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

Comments
 (0)