mirror of
https://github.com/hwchase17/langchain.git
synced 2026-04-18 08:03:52 +00:00
Compare commits
24 Commits
vwp/tools_
...
agents-4-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b96cf7a66 | ||
|
|
42f28fb45a | ||
|
|
b6943789ba | ||
|
|
8aa784bfbd | ||
|
|
90ef705ced | ||
|
|
a5c996189c | ||
|
|
ee8ddc7d52 | ||
|
|
7331004e06 | ||
|
|
19116010ee | ||
|
|
d57c64abcf | ||
|
|
77058211b0 | ||
|
|
17f029cdf9 | ||
|
|
8a2578c5be | ||
|
|
d54c88aa21 | ||
|
|
9d23cfc7dd | ||
|
|
aad0a498ac | ||
|
|
1c1b77bbfe | ||
|
|
14e4d30659 | ||
|
|
fe68051d34 | ||
|
|
188e9b9beb | ||
|
|
55f6f80a59 | ||
|
|
7dae39b57d | ||
|
|
0257829776 | ||
|
|
064a1db2b2 |
@@ -244,7 +244,8 @@ from langchain import OpenAI, ConversationChain
|
||||
llm = OpenAI(temperature=0)
|
||||
conversation = ConversationChain(llm=llm, verbose=True)
|
||||
|
||||
conversation.predict(input="Hi there!")
|
||||
output = conversation.predict(input="Hi there!")
|
||||
print(output)
|
||||
```
|
||||
|
||||
```pycon
|
||||
@@ -262,7 +263,8 @@ AI:
|
||||
```
|
||||
|
||||
```python
|
||||
conversation.predict(input="I'm doing well! Just having a conversation with an AI.")
|
||||
output = conversation.predict(input="I'm doing well! Just having a conversation with an AI.")
|
||||
print(output)
|
||||
```
|
||||
|
||||
```pycon
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"id": "a389367b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 1st example: hierarchical planning agent\n",
|
||||
"## 1st example: hierarchical planning agent\n",
|
||||
"\n",
|
||||
"In this example, we'll consider an approach called hierarchical planning, common in robotics and appearing in recent works for LLMs X robotics. We'll see it's a viable approach to start working with a massive API spec AND to assist with user queries that require multiple steps against the API.\n",
|
||||
"\n",
|
||||
@@ -31,7 +31,7 @@
|
||||
"id": "4b6ecf6e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## To start, let's collect some OpenAPI specs."
|
||||
"### To start, let's collect some OpenAPI specs."
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -169,7 +169,7 @@
|
||||
"id": "76349780",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## How big is this spec?"
|
||||
"### How big is this spec?"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -229,7 +229,7 @@
|
||||
"id": "cbc4964e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Let's see some examples!\n",
|
||||
"### Let's see some examples!\n",
|
||||
"\n",
|
||||
"Starting with GPT-4. (Some robustness iterations under way for GPT-3 family.)"
|
||||
]
|
||||
@@ -759,7 +759,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.0"
|
||||
"version": "3.9.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"- name (str), is required and must be unique within a set of tools provided to an agent\n",
|
||||
"- description (str), is optional but recommended, as it is used by an agent to determine tool use\n",
|
||||
"- return_direct (bool), defaults to False\n",
|
||||
"- args_schema (Pydantic BaseModel), is optional but recommended, can be used to provide more information or validation for expected parameters.\n",
|
||||
"\n",
|
||||
"The function that should be called when the tool is selected should return a single string.\n",
|
||||
"\n",
|
||||
@@ -91,12 +92,22 @@
|
||||
" func=search.run,\n",
|
||||
" description=\"useful for when you need to answer questions about current events\"\n",
|
||||
" ),\n",
|
||||
"]\n",
|
||||
"# You can also define an args_schema to provide more information about inputs\n",
|
||||
"from pydantic import BaseModel, Field\n",
|
||||
"\n",
|
||||
"class CalculatorInput(BaseModel):\n",
|
||||
" query: str = Field(description=\"should be a math expression\")\n",
|
||||
" \n",
|
||||
"\n",
|
||||
"tools.append(\n",
|
||||
" Tool(\n",
|
||||
" name=\"Calculator\",\n",
|
||||
" func=llm_math_chain.run,\n",
|
||||
" description=\"useful for when you need to answer questions about math\"\n",
|
||||
" description=\"useful for when you need to answer questions about math\",\n",
|
||||
" args_schema=CalculatorInput\n",
|
||||
" )\n",
|
||||
"]"
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -130,22 +141,20 @@
|
||||
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
|
||||
"\u001b[32;1m\u001b[1;3mI need to find out Leo DiCaprio's girlfriend's name and her age\n",
|
||||
"Action: Search\n",
|
||||
"Action Input: \"Leo DiCaprio girlfriend\"\u001b[0m\u001b[36;1m\u001b[1;3mI draw the lime at going to get a Mohawk, though.\" DiCaprio broke up with girlfriend Camila Morrone, 25, in the summer of 2022, after dating for four years. He's since been linked to another famous supermodel – Gigi Hadid.\u001b[0m\u001b[32;1m\u001b[1;3mI need to find out Gigi Hadid's age\n",
|
||||
"Action: Search\n",
|
||||
"Action Input: \"Gigi Hadid age\"\u001b[0m\u001b[36;1m\u001b[1;3m27 years\u001b[0m\u001b[32;1m\u001b[1;3mI need to calculate her age raised to the 0.43 power\n",
|
||||
"Action Input: \"Leo DiCaprio girlfriend\"\u001b[0m\u001b[36;1m\u001b[1;3mDiCaprio broke up with girlfriend Camila Morrone, 25, in the summer of 2022, after dating for four years.\u001b[0m\u001b[32;1m\u001b[1;3mI need to find out Camila Morrone's current age\n",
|
||||
"Action: Calculator\n",
|
||||
"Action Input: 27^(0.43)\u001b[0m\n",
|
||||
"Action Input: 25^(0.43)\u001b[0m\n",
|
||||
"\n",
|
||||
"\u001b[1m> Entering new LLMMathChain chain...\u001b[0m\n",
|
||||
"27^(0.43)\u001b[32;1m\u001b[1;3m```text\n",
|
||||
"27**(0.43)\n",
|
||||
"25^(0.43)\u001b[32;1m\u001b[1;3m```text\n",
|
||||
"25**(0.43)\n",
|
||||
"```\n",
|
||||
"...numexpr.evaluate(\"27**(0.43)\")...\n",
|
||||
"...numexpr.evaluate(\"25**(0.43)\")...\n",
|
||||
"\u001b[0m\n",
|
||||
"Answer: \u001b[33;1m\u001b[1;3m4.125593352125936\u001b[0m\n",
|
||||
"Answer: \u001b[33;1m\u001b[1;3m3.991298452658078\u001b[0m\n",
|
||||
"\u001b[1m> Finished chain.\u001b[0m\n",
|
||||
"\u001b[33;1m\u001b[1;3mAnswer: 4.125593352125936\u001b[0m\u001b[32;1m\u001b[1;3mI now know the final answer\n",
|
||||
"Final Answer: 4.125593352125936\u001b[0m\n",
|
||||
"\u001b[33;1m\u001b[1;3mAnswer: 3.991298452658078\u001b[0m\u001b[32;1m\u001b[1;3mI now know the final answer\n",
|
||||
"Final Answer: 3.991298452658078\u001b[0m\n",
|
||||
"\n",
|
||||
"\u001b[1m> Finished chain.\u001b[0m\n"
|
||||
]
|
||||
@@ -153,7 +162,7 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'4.125593352125936'"
|
||||
"'3.991298452658078'"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
@@ -197,6 +206,7 @@
|
||||
"class CustomCalculatorTool(BaseTool):\n",
|
||||
" name = \"Calculator\"\n",
|
||||
" description = \"useful for when you need to answer questions about math\"\n",
|
||||
" args_schema=CalculatorInput\n",
|
||||
"\n",
|
||||
" def _run(self, query: str) -> str:\n",
|
||||
" \"\"\"Use the tool.\"\"\"\n",
|
||||
@@ -248,9 +258,7 @@
|
||||
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
|
||||
"\u001b[32;1m\u001b[1;3mI need to find out Leo DiCaprio's girlfriend's name and her age\n",
|
||||
"Action: Search\n",
|
||||
"Action Input: \"Leo DiCaprio girlfriend\"\u001b[0m\u001b[36;1m\u001b[1;3mI draw the lime at going to get a Mohawk, though.\" DiCaprio broke up with girlfriend Camila Morrone, 25, in the summer of 2022, after dating for four years. He's since been linked to another famous supermodel – Gigi Hadid.\u001b[0m\u001b[32;1m\u001b[1;3mI now know Leo DiCaprio's girlfriend's name and that he's currently linked to Gigi Hadid. I need to find out Camila Morrone's age.\n",
|
||||
"Action: Search\n",
|
||||
"Action Input: \"Camila Morrone age\"\u001b[0m\u001b[36;1m\u001b[1;3m25 years\u001b[0m\u001b[32;1m\u001b[1;3mI have Camila Morrone's age. I need to calculate her age raised to the 0.43 power.\n",
|
||||
"Action Input: \"Leo DiCaprio girlfriend\"\u001b[0m\u001b[36;1m\u001b[1;3mDiCaprio broke up with girlfriend Camila Morrone, 25, in the summer of 2022, after dating for four years.\u001b[0m\u001b[32;1m\u001b[1;3mI need to find out Camila Morrone's current age\n",
|
||||
"Action: Calculator\n",
|
||||
"Action Input: 25^(0.43)\u001b[0m\n",
|
||||
"\n",
|
||||
@@ -262,8 +270,8 @@
|
||||
"\u001b[0m\n",
|
||||
"Answer: \u001b[33;1m\u001b[1;3m3.991298452658078\u001b[0m\n",
|
||||
"\u001b[1m> Finished chain.\u001b[0m\n",
|
||||
"\u001b[33;1m\u001b[1;3mAnswer: 3.991298452658078\u001b[0m\u001b[32;1m\u001b[1;3mI now know the answer to the original question.\n",
|
||||
"Final Answer: Camila Morrone's current age raised to the 0.43 power is approximately 3.99.\u001b[0m\n",
|
||||
"\u001b[33;1m\u001b[1;3mAnswer: 3.991298452658078\u001b[0m\u001b[32;1m\u001b[1;3mI now know the final answer\n",
|
||||
"Final Answer: 3.991298452658078\u001b[0m\n",
|
||||
"\n",
|
||||
"\u001b[1m> Finished chain.\u001b[0m\n"
|
||||
]
|
||||
@@ -271,7 +279,7 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"\"Camila Morrone's current age raised to the 0.43 power is approximately 3.99.\""
|
||||
"'3.991298452658078'"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
@@ -321,7 +329,7 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Tool(name='search_api', description='search_api(query: str) -> str - Searches the API for the query.', args_schema=<class 'pydantic.main.ArgsModel'>, return_direct=False, verbose=False, callback_manager=<langchain.callbacks.shared.SharedCallbackManager object at 0x124346f10>, func=<function search_api at 0x16ad6e020>, coroutine=None)"
|
||||
"Tool(name='search_api', description='search_api(query: str) -> str - Searches the API for the query.', args_schema=<class 'pydantic.main.SearchApi'>, return_direct=False, verbose=False, callback_manager=<langchain.callbacks.shared.SharedCallbackManager object at 0x12748c4c0>, func=<function search_api at 0x16bd664c0>, coroutine=None)"
|
||||
]
|
||||
},
|
||||
"execution_count": 11,
|
||||
@@ -365,7 +373,7 @@
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Tool(name='search', description='search(query: str) -> str - Searches the API for the query.', args_schema=<class 'pydantic.main.ArgsModel'>, return_direct=True, verbose=False, callback_manager=<langchain.callbacks.shared.SharedCallbackManager object at 0x124346f10>, func=<function search_api at 0x16ad6d3a0>, coroutine=None)"
|
||||
"Tool(name='search', description='search(query: str) -> str - Searches the API for the query.', args_schema=<class 'pydantic.main.SearchApi'>, return_direct=True, verbose=False, callback_manager=<langchain.callbacks.shared.SharedCallbackManager object at 0x12748c4c0>, func=<function search_api at 0x16bd66310>, coroutine=None)"
|
||||
]
|
||||
},
|
||||
"execution_count": 13,
|
||||
@@ -377,6 +385,51 @@
|
||||
"search_api"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "de34a6a3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"You can also provide `args_schema` to provide more information about the argument"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"id": "f3a5c106",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class SearchInput(BaseModel):\n",
|
||||
" query: str = Field(description=\"should be a search query\")\n",
|
||||
" \n",
|
||||
"@tool(\"search\", return_direct=True, args_schema=SearchInput)\n",
|
||||
"def search_api(query: str) -> str:\n",
|
||||
" \"\"\"Searches the API for the query.\"\"\"\n",
|
||||
" return \"Results\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"id": "7914ba6b",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Tool(name='search', description='search(query: str) -> str - Searches the API for the query.', args_schema=<class '__main__.SearchInput'>, return_direct=True, verbose=False, callback_manager=<langchain.callbacks.shared.SharedCallbackManager object at 0x12748c4c0>, func=<function search_api at 0x16bcf0ee0>, coroutine=None)"
|
||||
]
|
||||
},
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"search_api"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1d0430d6",
|
||||
@@ -784,7 +837,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.2"
|
||||
"version": "3.9.1"
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
|
||||
@@ -19,13 +19,12 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain.agents import initialize_agent, Tool\n",
|
||||
"from langchain.agents import AgentType\n",
|
||||
"from typing import Any, Dict\n",
|
||||
"\n",
|
||||
"from langchain.agents import AgentType, initialize_agent\n",
|
||||
"from langchain.llms import OpenAI\n",
|
||||
"from langchain.tools.python.tool import PythonREPLTool\n",
|
||||
"from pydantic import BaseModel\n",
|
||||
"from pydantic import Field, root_validator\n",
|
||||
"from typing import Dict, Any"
|
||||
"from langchain.tools.requests.tool import RequestsGetTool, TextRequestsWrapper\n",
|
||||
"from pydantic import BaseModel, Field, root_validator\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -42,22 +41,20 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.0.1\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.1\u001b[0m\n",
|
||||
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"class ToolInputModel(BaseModel):\n",
|
||||
" query: str = Field(...)\n",
|
||||
" \n",
|
||||
" @root_validator\n",
|
||||
" def validate_query(cls, values: Dict[str, Any]) -> Dict:\n",
|
||||
" # Note: this is NOT a safe REPL! This is used for instructive purposes only\n",
|
||||
" if \"import os\" in values[\"query\"]:\n",
|
||||
" raise ValueError(\"'import os' not permitted in this python REPL.\")\n",
|
||||
" return values\n",
|
||||
" \n",
|
||||
"tool = PythonREPLTool(args_schema=ToolInputModel)"
|
||||
"!pip install tldextract > /dev/null"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -68,7 +65,27 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"agent = initialize_agent([tool], llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)"
|
||||
"import tldextract\n",
|
||||
"\n",
|
||||
"_APPROVED_DOMAINS = {\n",
|
||||
" \"langchain\",\n",
|
||||
" \"wikipedia\",\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"class ToolInputSchema(BaseModel):\n",
|
||||
"\n",
|
||||
" url: str = Field(...)\n",
|
||||
" \n",
|
||||
" @root_validator\n",
|
||||
" def validate_query(cls, values: Dict[str, Any]) -> Dict:\n",
|
||||
" url = values[\"url\"]\n",
|
||||
" domain = tldextract.extract(url).domain\n",
|
||||
" if domain not in _APPROVED_DOMAINS:\n",
|
||||
" raise ValueError(f\"Domain {domain} is not on the approved list:\"\n",
|
||||
" f\" {sorted(_APPROVED_DOMAINS)}\")\n",
|
||||
" return values\n",
|
||||
" \n",
|
||||
"tool = RequestsGetTool(args_schema=ToolInputSchema, requests_wrapper=TextRequestsWrapper())"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -77,40 +94,9 @@
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\n",
|
||||
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
|
||||
"\u001b[32;1m\u001b[1;3m I need to define a function that adds two numbers\n",
|
||||
"Action: Python REPL\n",
|
||||
"Action Input: def add_two_numbers(a, b):\n",
|
||||
" return a + b\u001b[0m\u001b[36;1m\u001b[1;3m\u001b[0m\u001b[32;1m\u001b[1;3m I need to call the function\n",
|
||||
"Action: Python REPL\n",
|
||||
"Action Input: print(add_two_numbers(2, 2))\u001b[0m\u001b[36;1m\u001b[1;3m4\n",
|
||||
"\u001b[0m\u001b[32;1m\u001b[1;3m I now know the final answer\n",
|
||||
"Final Answer: 4\u001b[0m\n",
|
||||
"\n",
|
||||
"\u001b[1m> Finished chain.\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'4'"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# This will succeed, since there aren't any arguments that will be triggered during validation\n",
|
||||
"agent.run(\"Run a python function that adds 2 and 2\")"
|
||||
"agent = initialize_agent([tool], llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -124,38 +110,46 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\n",
|
||||
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
|
||||
"\u001b[32;1m\u001b[1;3m I need to import os and then list the dir\n",
|
||||
"Action: Python REPL\n",
|
||||
"Action Input: import os; print(os.listdir())\u001b[0m"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ename": "ValidationError",
|
||||
"evalue": "1 validation error for ToolInputModel\n__root__\n 'import os' not (type=value_error)",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[0;31mValidationError\u001b[0m Traceback (most recent call last)",
|
||||
"Cell \u001b[0;32mIn[6], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43magent\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mRun a python function that imports os and lists the dir\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/chains/base.py:213\u001b[0m, in \u001b[0;36mChain.run\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 211\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(args) \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m 212\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m`run` supports only one positional argument.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 213\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43margs\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m[\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moutput_keys[\u001b[38;5;241m0\u001b[39m]]\n\u001b[1;32m 215\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m kwargs \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m args:\n\u001b[1;32m 216\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m(kwargs)[\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moutput_keys[\u001b[38;5;241m0\u001b[39m]]\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/chains/base.py:116\u001b[0m, in \u001b[0;36mChain.__call__\u001b[0;34m(self, inputs, return_only_outputs)\u001b[0m\n\u001b[1;32m 114\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m, \u001b[38;5;167;01mException\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 115\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcallback_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e, verbose\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mverbose)\n\u001b[0;32m--> 116\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[1;32m 117\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcallback_manager\u001b[38;5;241m.\u001b[39mon_chain_end(outputs, verbose\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mverbose)\n\u001b[1;32m 118\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprep_outputs(inputs, outputs, return_only_outputs)\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/chains/base.py:113\u001b[0m, in \u001b[0;36mChain.__call__\u001b[0;34m(self, inputs, return_only_outputs)\u001b[0m\n\u001b[1;32m 107\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcallback_manager\u001b[38;5;241m.\u001b[39mon_chain_start(\n\u001b[1;32m 108\u001b[0m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__class__\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m},\n\u001b[1;32m 109\u001b[0m inputs,\n\u001b[1;32m 110\u001b[0m verbose\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mverbose,\n\u001b[1;32m 111\u001b[0m )\n\u001b[1;32m 112\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 113\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call\u001b[49m\u001b[43m(\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 114\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m, \u001b[38;5;167;01mException\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 115\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcallback_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e, verbose\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mverbose)\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/agents/agent.py:792\u001b[0m, in \u001b[0;36mAgentExecutor._call\u001b[0;34m(self, inputs)\u001b[0m\n\u001b[1;32m 790\u001b[0m \u001b[38;5;66;03m# We now enter the agent loop (until it returns something).\u001b[39;00m\n\u001b[1;32m 791\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_continue(iterations, time_elapsed):\n\u001b[0;32m--> 792\u001b[0m next_step_output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_take_next_step\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 793\u001b[0m \u001b[43m \u001b[49m\u001b[43mname_to_tool_map\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcolor_mapping\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mintermediate_steps\u001b[49m\n\u001b[1;32m 794\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 795\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(next_step_output, AgentFinish):\n\u001b[1;32m 796\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_return(next_step_output, intermediate_steps)\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/agents/agent.py:695\u001b[0m, in \u001b[0;36mAgentExecutor._take_next_step\u001b[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps)\u001b[0m\n\u001b[1;32m 693\u001b[0m tool_run_kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mllm_prefix\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 694\u001b[0m \u001b[38;5;66;03m# We then call the tool on the tool input to get an observation\u001b[39;00m\n\u001b[0;32m--> 695\u001b[0m observation \u001b[38;5;241m=\u001b[39m \u001b[43mtool\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 696\u001b[0m \u001b[43m \u001b[49m\u001b[43magent_action\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtool_input\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 697\u001b[0m \u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 698\u001b[0m \u001b[43m \u001b[49m\u001b[43mcolor\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcolor\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 699\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mtool_run_kwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 700\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 701\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 702\u001b[0m tool_run_kwargs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39magent\u001b[38;5;241m.\u001b[39mtool_run_logging_kwargs()\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/tools/base.py:146\u001b[0m, in \u001b[0;36mBaseTool.run\u001b[0;34m(self, tool_input, verbose, start_color, color, **kwargs)\u001b[0m\n\u001b[1;32m 137\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mrun\u001b[39m(\n\u001b[1;32m 138\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 139\u001b[0m tool_input: Union[\u001b[38;5;28mstr\u001b[39m, Dict],\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 143\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any,\n\u001b[1;32m 144\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28mstr\u001b[39m:\n\u001b[1;32m 145\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Run the tool.\"\"\"\u001b[39;00m\n\u001b[0;32m--> 146\u001b[0m run_input \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_parse_input\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtool_input\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 147\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mverbose \u001b[38;5;129;01mand\u001b[39;00m verbose \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 148\u001b[0m verbose_ \u001b[38;5;241m=\u001b[39m verbose\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/tools/base.py:112\u001b[0m, in \u001b[0;36mBaseTool._parse_input\u001b[0;34m(self, tool_input)\u001b[0m\n\u001b[1;32m 110\u001b[0m tool_input \u001b[38;5;241m=\u001b[39m {field_name: tool_input}\n\u001b[1;32m 111\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m pydantic_input_type \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 112\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mpydantic_input_type\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mparse_obj\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtool_input\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 113\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 114\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 115\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124margs_schema required for tool \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m in order to\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 116\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m accept input of type \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mtype\u001b[39m(tool_input)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 117\u001b[0m )\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/.venv/lib/python3.11/site-packages/pydantic/main.py:526\u001b[0m, in \u001b[0;36mpydantic.main.BaseModel.parse_obj\u001b[0;34m()\u001b[0m\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/.venv/lib/python3.11/site-packages/pydantic/main.py:341\u001b[0m, in \u001b[0;36mpydantic.main.BaseModel.__init__\u001b[0;34m()\u001b[0m\n",
|
||||
"\u001b[0;31mValidationError\u001b[0m: 1 validation error for ToolInputModel\n__root__\n 'import os' not (type=value_error)"
|
||||
"The main title of langchain.com is \"LANG CHAIN 🦜️🔗 Official Home Page\"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# This will fail, because the attempt to import os will trigger a validation error\n",
|
||||
"agent.run(\"Run a python function that imports os and lists the dir\")"
|
||||
"# This will succeed, since there aren't any arguments that will be triggered during validation\n",
|
||||
"answer = agent.run(\"What's the main title on langchain.com?\")\n",
|
||||
"print(answer)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "ValidationError",
|
||||
"evalue": "1 validation error for ToolInputSchema\n__root__\n Domain google is not on the approved list: ['langchain', 'wikipedia'] (type=value_error)",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[0;31mValidationError\u001b[0m Traceback (most recent call last)",
|
||||
"Cell \u001b[0;32mIn[7], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m agent\u001b[39m.\u001b[39;49mrun(\u001b[39m\"\u001b[39;49m\u001b[39mWhat\u001b[39;49m\u001b[39m'\u001b[39;49m\u001b[39ms the main title on google.com?\u001b[39;49m\u001b[39m\"\u001b[39;49m)\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/chains/base.py:213\u001b[0m, in \u001b[0;36mChain.run\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 211\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mlen\u001b[39m(args) \u001b[39m!=\u001b[39m \u001b[39m1\u001b[39m:\n\u001b[1;32m 212\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mValueError\u001b[39;00m(\u001b[39m\"\u001b[39m\u001b[39m`run` supports only one positional argument.\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m--> 213\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m(args[\u001b[39m0\u001b[39;49m])[\u001b[39mself\u001b[39m\u001b[39m.\u001b[39moutput_keys[\u001b[39m0\u001b[39m]]\n\u001b[1;32m 215\u001b[0m \u001b[39mif\u001b[39;00m kwargs \u001b[39mand\u001b[39;00m \u001b[39mnot\u001b[39;00m args:\n\u001b[1;32m 216\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m(kwargs)[\u001b[39mself\u001b[39m\u001b[39m.\u001b[39moutput_keys[\u001b[39m0\u001b[39m]]\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/chains/base.py:116\u001b[0m, in \u001b[0;36mChain.__call__\u001b[0;34m(self, inputs, return_only_outputs)\u001b[0m\n\u001b[1;32m 114\u001b[0m \u001b[39mexcept\u001b[39;00m (\u001b[39mKeyboardInterrupt\u001b[39;00m, \u001b[39mException\u001b[39;00m) \u001b[39mas\u001b[39;00m e:\n\u001b[1;32m 115\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mcallback_manager\u001b[39m.\u001b[39mon_chain_error(e, verbose\u001b[39m=\u001b[39m\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mverbose)\n\u001b[0;32m--> 116\u001b[0m \u001b[39mraise\u001b[39;00m e\n\u001b[1;32m 117\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mcallback_manager\u001b[39m.\u001b[39mon_chain_end(outputs, verbose\u001b[39m=\u001b[39m\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mverbose)\n\u001b[1;32m 118\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mprep_outputs(inputs, outputs, return_only_outputs)\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/chains/base.py:113\u001b[0m, in \u001b[0;36mChain.__call__\u001b[0;34m(self, inputs, return_only_outputs)\u001b[0m\n\u001b[1;32m 107\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mcallback_manager\u001b[39m.\u001b[39mon_chain_start(\n\u001b[1;32m 108\u001b[0m {\u001b[39m\"\u001b[39m\u001b[39mname\u001b[39m\u001b[39m\"\u001b[39m: \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m\u001b[39m__class__\u001b[39m\u001b[39m.\u001b[39m\u001b[39m__name__\u001b[39m},\n\u001b[1;32m 109\u001b[0m inputs,\n\u001b[1;32m 110\u001b[0m verbose\u001b[39m=\u001b[39m\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mverbose,\n\u001b[1;32m 111\u001b[0m )\n\u001b[1;32m 112\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m--> 113\u001b[0m outputs \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_call(inputs)\n\u001b[1;32m 114\u001b[0m \u001b[39mexcept\u001b[39;00m (\u001b[39mKeyboardInterrupt\u001b[39;00m, \u001b[39mException\u001b[39;00m) \u001b[39mas\u001b[39;00m e:\n\u001b[1;32m 115\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mcallback_manager\u001b[39m.\u001b[39mon_chain_error(e, verbose\u001b[39m=\u001b[39m\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mverbose)\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/agents/agent.py:792\u001b[0m, in \u001b[0;36mAgentExecutor._call\u001b[0;34m(self, inputs)\u001b[0m\n\u001b[1;32m 790\u001b[0m \u001b[39m# We now enter the agent loop (until it returns something).\u001b[39;00m\n\u001b[1;32m 791\u001b[0m \u001b[39mwhile\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_should_continue(iterations, time_elapsed):\n\u001b[0;32m--> 792\u001b[0m next_step_output \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_take_next_step(\n\u001b[1;32m 793\u001b[0m name_to_tool_map, color_mapping, inputs, intermediate_steps\n\u001b[1;32m 794\u001b[0m )\n\u001b[1;32m 795\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(next_step_output, AgentFinish):\n\u001b[1;32m 796\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_return(next_step_output, intermediate_steps)\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/agents/agent.py:695\u001b[0m, in \u001b[0;36mAgentExecutor._take_next_step\u001b[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps)\u001b[0m\n\u001b[1;32m 693\u001b[0m tool_run_kwargs[\u001b[39m\"\u001b[39m\u001b[39mllm_prefix\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39m\"\u001b[39m\n\u001b[1;32m 694\u001b[0m \u001b[39m# We then call the tool on the tool input to get an observation\u001b[39;00m\n\u001b[0;32m--> 695\u001b[0m observation \u001b[39m=\u001b[39m tool\u001b[39m.\u001b[39;49mrun(\n\u001b[1;32m 696\u001b[0m agent_action\u001b[39m.\u001b[39;49mtool_input,\n\u001b[1;32m 697\u001b[0m verbose\u001b[39m=\u001b[39;49m\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mverbose,\n\u001b[1;32m 698\u001b[0m color\u001b[39m=\u001b[39;49mcolor,\n\u001b[1;32m 699\u001b[0m \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mtool_run_kwargs,\n\u001b[1;32m 700\u001b[0m )\n\u001b[1;32m 701\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m 702\u001b[0m tool_run_kwargs \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39magent\u001b[39m.\u001b[39mtool_run_logging_kwargs()\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/tools/base.py:110\u001b[0m, in \u001b[0;36mBaseTool.run\u001b[0;34m(self, tool_input, verbose, start_color, color, **kwargs)\u001b[0m\n\u001b[1;32m 101\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mrun\u001b[39m(\n\u001b[1;32m 102\u001b[0m \u001b[39mself\u001b[39m,\n\u001b[1;32m 103\u001b[0m tool_input: Union[\u001b[39mstr\u001b[39m, Dict],\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 107\u001b[0m \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs: Any,\n\u001b[1;32m 108\u001b[0m ) \u001b[39m-\u001b[39m\u001b[39m>\u001b[39m \u001b[39mstr\u001b[39m:\n\u001b[1;32m 109\u001b[0m \u001b[39m \u001b[39m\u001b[39m\"\"\"Run the tool.\"\"\"\u001b[39;00m\n\u001b[0;32m--> 110\u001b[0m run_input \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_parse_input(tool_input)\n\u001b[1;32m 111\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mverbose \u001b[39mand\u001b[39;00m verbose \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m 112\u001b[0m verbose_ \u001b[39m=\u001b[39m verbose\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/langchain/tools/base.py:71\u001b[0m, in \u001b[0;36mBaseTool._parse_input\u001b[0;34m(self, tool_input)\u001b[0m\n\u001b[1;32m 69\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39missubclass\u001b[39m(input_args, BaseModel):\n\u001b[1;32m 70\u001b[0m key_ \u001b[39m=\u001b[39m \u001b[39mnext\u001b[39m(\u001b[39miter\u001b[39m(input_args\u001b[39m.\u001b[39m__fields__\u001b[39m.\u001b[39mkeys()))\n\u001b[0;32m---> 71\u001b[0m input_args\u001b[39m.\u001b[39;49mparse_obj({key_: tool_input})\n\u001b[1;32m 72\u001b[0m \u001b[39m# Passing as a positional argument is more straightforward for\u001b[39;00m\n\u001b[1;32m 73\u001b[0m \u001b[39m# backwards compatability\u001b[39;00m\n\u001b[1;32m 74\u001b[0m \u001b[39mreturn\u001b[39;00m tool_input\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/.venv/lib/python3.11/site-packages/pydantic/main.py:526\u001b[0m, in \u001b[0;36mpydantic.main.BaseModel.parse_obj\u001b[0;34m()\u001b[0m\n",
|
||||
"File \u001b[0;32m~/code/lc/lckg/.venv/lib/python3.11/site-packages/pydantic/main.py:341\u001b[0m, in \u001b[0;36mpydantic.main.BaseModel.__init__\u001b[0;34m()\u001b[0m\n",
|
||||
"\u001b[0;31mValidationError\u001b[0m: 1 validation error for ToolInputSchema\n__root__\n Domain google is not on the approved list: ['langchain', 'wikipedia'] (type=value_error)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"agent.run(\"What's the main title on google.com?\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Confluence\n",
|
||||
"\n",
|
||||
"A loader for Confluence pages. Port of https://llamahub.ai/l/confluence\n",
|
||||
"A loader for Confluence pages.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"This currently supports both username/api_key and Oauth2 login.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Specify a list page_ids and/or space_key to load in the corresponding pages into Document objects, if both are specified the union of both sets will be returned.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"You can also specify a boolean `include_attachments` to include attachments, this is set to False by default, if set to True all attachments will be downloaded and ConfluenceReader will extract the text from the attachments and add it to the Document object. Currently supported attachment types are: PDF, PNG, JPEG/JPG, SVG, Word and Excel.\n",
|
||||
"\n",
|
||||
"Hint: space_key and page_id can both be found in the URL of a page in Confluence - https://yoursite.atlassian.com/wiki/spaces/<space_key>/pages/<page_id>\n"
|
||||
@@ -37,15 +39,22 @@
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"version": "3.9.7 (default, Mar 5 2023, 20:59:52) \n[Clang 12.0.0 (clang-1200.0.32.2)]"
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.1"
|
||||
},
|
||||
"orig_nbformat": 4,
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "cc99336516f23363341912c6723b01ace86f02e26b4290be1efc0677e2e2ec24"
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6ad0a850",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3d4f1bdd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = pd.read_csv(\"example_data/fake_discord_chat.csv\")\n",
|
||||
"df.head()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "82880d80",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain.document_loaders.discord import DiscordChatLoader"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "b825a8d3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"loader = DiscordChatLoader(df, user_id_col=\"user_id\")\n",
|
||||
"print(loader.load())"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
user_id,message,timestamp
|
||||
6b118e52-bc2b-487e-9322-a84f217902f1,"Street of born. Order around toward serve box. More keep number some.
|
||||
Physical bring doctor wall finally share make. About nothing suddenly somebody gun receive job.",2022-01-01 00:00:00
|
||||
be5ea045-4478-45a8-9b8c-8e0a43222888,"Service describe size two ever. White marriage each sell line nature far.
|
||||
Religious organization type music. Often still more five. Religious present test prove fine.",2022-01-01 00:10:00
|
||||
3de7ddf9-e58b-4eb6-a7f5-083d1d022499,"Major with ball process now make. Almost hospital possible good media whom.
|
||||
Clearly entire while realize wind. Base game skin together probably sport like memory.",2022-01-01 00:20:00
|
||||
87e99005-780f-4f3b-b48d-91b17cce55fe,Page indeed clear different. Skin loss develop animal customer. Cultural number effect tonight would paper.,2022-01-01 00:30:00
|
||||
251099c2-ca02-4fb4-bd52-dca41f3d8b25,"World tree seat grow. Region believe matter himself message despite.
|
||||
Together type process kid enjoy watch story. Visit happen movie her. Practice few ok chance.",2022-01-01 00:40:00
|
||||
974ed6b3-c08c-4771-a8d1-945f20526850,Result visit amount production prevent attack agreement. Development month realize. Thus not whatever live decide young specific.,2022-01-01 00:50:00
|
||||
e0f88629-3df1-4f54-a40e-c75cf5909c26,"Evening past choice visit approach must. Avoid unit get stop. Image talk design only role write wrong.
|
||||
I model response character son smile degree job.
|
||||
Lead bill sound likely chair.",2022-01-01 01:00:00
|
||||
5f260d25-e1ff-491b-8720-29b7e7c40a1f,"Painting develop environmental message recently them area. Him for condition blood. Should brother little majority.
|
||||
Couple store because deep. Radio turn clear remember collection.",2022-01-01 01:10:00
|
||||
b217eaba-53ff-430c-8d4c-f1ebd1a77a09,Leg measure on age positive. Discussion party and get huge force building. So yes assume brother medical population. Fly will enter involve cup woman spend.,2022-01-01 01:20:00
|
||||
7b42ae71-12af-4222-a352-84ed9a3414ea,Knowledge goal single believe inside. Police human and fall. Trial participant indeed against since. Few miss radio successful.,2022-01-01 01:30:00
|
||||
2a4adb92-8caa-4b9d-96f4-c89905e48a32,"Else big which energy.
|
||||
Maybe Republican character conference social. Threat upon just receive.
|
||||
Easy national speak. Listen assume like ago practice bit animal.",2022-01-01 01:40:00
|
||||
66d0a700-7781-4702-802c-83632e595350,"Democratic night foot. Month force civil mind true. Institution rest peace none growth own.
|
||||
Start billion popular. A baby attention assume certainly result. Strong true teacher executive purpose.",2022-01-01 01:50:00
|
||||
2fe4b7c5-936d-4576-bf25-02d41acd9bb6,Us subject same war other. International how trial free. Parent certainly relationship summer four.,2022-01-01 02:00:00
|
||||
583739ec-0f39-488f-9728-d336bf6c9983,"Mention meeting similar letter easy reality. Upon morning little put.
|
||||
Ago rate huge me see edge.",2022-01-01 02:10:00
|
||||
d0f75d9a-0de9-4341-bba3-0abd1f89a961,"Black second bill study if reveal so your. Economic somebody walk attack meet. Artist threat natural world.
|
||||
Forget although range. My seven wait lot add production.",2022-01-01 02:20:00
|
||||
f0f494fa-e16d-4ee0-bbc8-42a92b7a6cc1,"When court officer exist yeah hold between light. Should can message character.
|
||||
Sea probably parent media song second weight trip. How process effect media reduce.",2022-01-01 02:30:00
|
||||
a08cd4e4-0962-42cb-89e7-2e2812af4f3a,Anything some charge authority something. I letter laugh investment including turn. Son receive matter care many now discuss.,2022-01-01 02:40:00
|
||||
11486a17-d5c5-42e3-bcb8-b75e08b8937b,Tax image relationship under increase keep. Really society get ago himself help popular society. If indicate alone until plan economic maintain stand.,2022-01-01 02:50:00
|
||||
9ee84827-7f9b-40d0-8c45-34d8cd42d3ba,Nation dream make both. Continue often pass truth national grow. Language sometimes process way million individual friend.,2022-01-01 03:00:00
|
||||
d7a679cc-dbe9-41ee-9626-9289cfc8ae37,"Determine them fine cut. East month memory. Treat like worker federal tonight.
|
||||
Gun option tree. Data start brother help citizen easy want reveal. Conference movement sea show open change.",2022-01-01 03:10:00
|
||||
470b83fb-dd86-44c9-908c-13a17c771452,"Option use bill later away.
|
||||
Trade would player fine evidence learn. Increase game them necessary. Sit range must fire hard serious. Available recognize contain act.",2022-01-01 03:20:00
|
||||
67dc28d3-77d7-4de2-a176-69a67a246704,Because conference lead election time. Purpose theory old talk their. Account often center consider see loss theory because. Minute however wonder agency.,2022-01-01 03:30:00
|
||||
e07a8306-ecb9-43da-bff5-72ef4af176cd,"Woman whose face short also data. Hand just each culture no.
|
||||
Despite new hold bed. Feel fund deep agency hundred drug. Pass surface continue positive mind same check hand. Across make fund similar.",2022-01-01 03:40:00
|
||||
d70c6f1f-f29c-46d7-9e2a-13fe4f4dd06f,"Quality arrive hair if over. Hotel day reach west spend toward. Any opportunity much participant property mission.
|
||||
Themselves throw mind indeed. Late half recently. Edge enjoy great ahead.",2022-01-01 03:50:00
|
||||
47d84bcb-0f77-42dc-a762-255733a37ed9,"Public front article sea. Very bit center certain experience whom.
|
||||
Probably reality final goal radio financial age.",2022-01-01 04:00:00
|
||||
af4890da-8ec8-4c41-ba07-7038fbe90b88,"Choose hope history none current.
|
||||
Usually loss floor garden value article. No arm decision create government agree often.",2022-01-01 04:10:00
|
||||
0fefc22a-3d8f-4de2-ad42-0cce61f497e2,Explain baby might among their exactly risk. Body big set across put class. Hit should appear situation.,2022-01-01 04:20:00
|
||||
5b3809e6-e86c-4e1e-b687-5cdb4b9f76fa,"Nation summer exactly. Pick car reality would.
|
||||
Quite Mr number question war throw. Certain career idea heavy. Hope process save common attack to.",2022-01-01 04:30:00
|
||||
ef0cd3a7-3368-4ccc-8232-940c041cc888,"Effort stand bag never future training. Defense attorney mouth play coach peace. Herself sing size compare.
|
||||
Speak surface old half available.",2022-01-01 04:40:00
|
||||
d5b1cf3f-9b31-4d35-b89a-c29caf09fdad,"Magazine finish capital guy really too ask. Item agency seat hospital away. Near four despite without.
|
||||
Congress property fund toward character. Watch detail food rock identify.",2022-01-01 04:50:00
|
||||
50a39171-4725-44dc-b88d-712a5202b949,Six this prevent. Usually sound history field little. Theory suggest else. President less team garden.,2022-01-01 05:00:00
|
||||
6aa242fb-606f-44ff-86e2-4f3c19162545,"Machine left yeah think clear. Serve role expert animal first up.
|
||||
Well contain nature million. Issue firm follow far growth spring everyone boy.",2022-01-01 05:10:00
|
||||
195a938a-9e78-43af-91d1-b3a05b2737d8,"Method high practice measure style always adult along. Them stay wait manager sometimes person likely do.
|
||||
Or fine conference job feeling number. Fact front compare east mind.",2022-01-01 05:20:00
|
||||
93fd62ea-8147-457b-96f2-8d9db53c53cd,"Mind well stock be morning federal then yeah. Save material stand cell poor.
|
||||
Notice occur success organization chance list. Soon deal receive nearly. Future allow night take wonder rate feeling.",2022-01-01 05:30:00
|
||||
f01fc201-2491-4757-8d13-c0f0411fb2c3,"Rock or fund. Middle man course task west open. Scene movie hope development travel.
|
||||
Public fine artist theory. Well across each new. Process bad eat win article want election.",2022-01-01 05:40:00
|
||||
e0c8eb7f-a4d7-411c-b337-e7eb6b28eb4f,"Moment arm may beautiful he firm. Single western dog themselves able media high material.
|
||||
Century today itself fear remember message than. Fund kid rest prevent. Director officer teacher.",2022-01-01 05:50:00
|
||||
28b8a3af-b5ce-4802-a48f-22058d3931b3,Drive write various raise environment. Time official country perhaps could though good. Style fast kitchen piece sense nothing agreement.,2022-01-01 06:00:00
|
||||
f5cc758a-4b9d-479d-861c-d01432a99a5e,Assume design worker. Skill although wear maintain rest member everyone marriage. Age along feeling beat method magazine.,2022-01-01 06:10:00
|
||||
8579650a-74b7-4dac-bfce-2f5eee7fbce4,"Candidate against reduce wrong size network exactly. It present able during manager whom hard. Near tend already.
|
||||
Serious major democratic remain main cost marriage. Team deal meeting group store.",2022-01-01 06:20:00
|
||||
9036fdeb-d814-4130-bc54-13e3bf8676e9,"How through support lead over there. Security over crime police attorney. Management popular item son remain if increase.
|
||||
White piece glass author hit. Mean theory citizen reason simply day coach.",2022-01-01 06:30:00
|
||||
8e7a773f-e4d8-402a-a7ce-5bfcb9235503,Child inside boy conference reveal catch economy. Develop window like tax. Money truth heart learn this anyone.,2022-01-01 06:40:00
|
||||
a95756f6-5796-4e01-9555-b9d6726bfbfe,Majority real so newspaper grow yourself. Station community half line. Ready little wind energy.,2022-01-01 06:50:00
|
||||
44866560-112b-42d2-90d3-e6d13c8eca64,National region third understand mind. Water hot attorney information. Magazine customer Mrs song. Authority investment become organization.,2022-01-01 07:00:00
|
||||
0561ef77-94bb-4325-874d-11c4bd797eb7,"Everyone however skin human room dream although. Where remain director.
|
||||
Eye heavy safe. Model score use exactly family structure. Two true family candidate.",2022-01-01 07:10:00
|
||||
fa71bdc4-b85b-48f5-82b8-fa9d22e9f6a3,"Model bring kitchen wish anything simple power.
|
||||
Able write six official individual matter forward. Room personal economic north. Investment war several politics serve expect.",2022-01-01 07:20:00
|
||||
1b91d11a-09c8-48f0-b042-911bea52a3b8,"Record suffer start. Most feeling find down door. Letter actually I dream dream. Law cost our personal Republican.
|
||||
Likely store situation protect provide half.
|
||||
School place it level nor fast order.",2022-01-01 07:30:00
|
||||
10d7a616-55a6-49d0-bf6d-8f3ffc24f35e,"Pull shoulder life visit best. Itself whose even hit practice exist campaign.
|
||||
Contain happy moment wide. Spring meeting part position happy population thousand.",2022-01-01 07:40:00
|
||||
6bd1ad19-a1b8-4ba0-83ee-7969b0547ee1,"Mother couple section audience we world. Huge husband window senior realize reality must message.
|
||||
Mention heart action other their. Drop claim check whom trouble. Go end discuss school senior drive.",2022-01-01 07:50:00
|
||||
68faa2b0-02f9-484a-900c-95f8cfd22554,Teach free west discuss note stage. Add war than build. Politics write business. Behavior success better determine who power top billion.,2022-01-01 08:00:00
|
||||
a01b6797-d94b-4eb0-956b-efe1a3d8269d,Any end worry event fear. Memory feeling ball team.,2022-01-01 08:10:00
|
||||
7ef25987-b910-4146-89b4-40bca6da73db,"Suffer worry west big next present travel. Standard thing consumer road your.
|
||||
Start decade off speech. Wall we recent civil life despite.",2022-01-01 08:20:00
|
||||
c046101f-65ed-4d22-a3a1-76efbccf6b07,Resource north environmental simply nice. Past together study part more.,2022-01-01 08:30:00
|
||||
1a55ca1e-dac2-4ee3-8739-e38494e2a603,Fund leader office animal physical matter. Attorney whole with knowledge practice create meeting question. Wind west always score art.,2022-01-01 08:40:00
|
||||
8cc516b3-d007-48be-a109-eb1a0ac1fa16,"Feeling notice five family believe goal increase.
|
||||
State page structure record use her. Student defense year myself out.
|
||||
Congress style perform cell mission sense. Yes when leg responsibility.",2022-01-01 08:50:00
|
||||
76411191-5c7a-4a9c-997f-ea61f3c138ff,Hope discover glass up own pressure. Two include generation TV. Fund drop government true west sit everything.,2022-01-01 09:00:00
|
||||
28ae91e1-26f1-4f40-8aaa-692a905b8b26,"Represent who smile blue model. Hour exactly lay white avoid let. Lose film technology affect agree.
|
||||
Old respond old stay general natural ever. Field phone safe. Mrs whole space answer color.",2022-01-01 09:10:00
|
||||
523b4e51-2261-4d61-8fe1-a379c8df5824,Weight sport allow before resource avoid. Wait leg space writer maybe actually third. Tax need by benefit.,2022-01-01 09:20:00
|
||||
32e8c5a2-bfc5-4e5a-ab97-7e36e4a221b9,"Develop write street after well. Offer along eat buy adult but.
|
||||
Never there everybody movie represent recognize ground. Result pretty pay once. Will newspaper away even dream yeah grow.",2022-01-01 09:30:00
|
||||
0c38e2ee-3ca2-44e8-be2b-7e4fe6fe4b68,Meeting mother easy newspaper check. Oil indicate available year different everyone leader. Present thus explain meeting. Head respond pretty big too natural born beautiful.,2022-01-01 09:40:00
|
||||
c09ef9ca-78a2-4796-9d4c-b791a9abcaa7,"Skill president around.
|
||||
Reduce just necessary choose surface card argue. Foot base cup player. Believe effect consider operation theory.",2022-01-01 09:50:00
|
||||
d2a1de02-9514-4a6c-ae37-9cd1e2beefa0,"Medical put instead between these.
|
||||
Network environment of social feel blue decide after. Glass notice simply Democrat and spring. Might need computer middle. Town turn skin skill your.",2022-01-01 10:00:00
|
||||
a9667646-d759-41b2-b22b-6c38fdba84b2,"Into daughter door especially plan expert set. Return although control join. Though blue agree maybe write.
|
||||
Send party ready spring house.",2022-01-01 10:10:00
|
||||
240ea2f1-3eda-47e3-96ef-cd4f7299e4f2,"Trip face stage game doctor name cover.
|
||||
Box may evening production none treatment ago. Behavior television show area news. Board leave collection director carry type whatever.",2022-01-01 10:20:00
|
||||
4f73aa5f-02d1-4cf2-bc73-45f050606c5d,"Almost country bring better member sister. Agency if around assume light development example.
|
||||
Tend way deep another possible quality white. Term from new good. Worry woman recently glass.",2022-01-01 10:30:00
|
||||
b076bf4d-7964-4c30-b3be-e68dcbffa7c7,"Audience act group small. Individual agreement realize special upon work wall sometimes.
|
||||
Main million and act various song where. Opportunity along generation trial consumer. Center great should Mrs.",2022-01-01 10:40:00
|
||||
10c6e307-9599-42c0-b418-35e340346eb6,So ahead bill term. Million represent election cut summer guess. Everybody though my other or stay it.,2022-01-01 10:50:00
|
||||
eb496b9d-4fbd-4355-bced-7d1065e63991,"Girl how gas. Sister popular matter.
|
||||
Before indeed week else whose rest church. Trade team them.
|
||||
Describe compare improve American act. Nation close example. Recent around through.",2022-01-01 11:00:00
|
||||
ddfab160-0481-4639-8407-35ec0745b657,After practice seven Republican. Task democratic general television cost matter. Arrive east crime role. Evening Mr ever national wide lose hour address.,2022-01-01 11:10:00
|
||||
cf8ceaea-9106-47ba-a4be-684e56ca9996,Process whatever public nation bar learn. Trip trouble best participant. Their among just agent check answer theory.,2022-01-01 11:20:00
|
||||
79e939eb-e6d9-4b87-a1c7-accef7802175,Standard story community analysis wife. Information affect least begin phone media establish. Challenge key film your stay entire court. City trip body kitchen increase.,2022-01-01 11:30:00
|
||||
915f81e6-870b-4e10-b43a-8d4d3b9680c4,Buy authority quality. Yet out general century record. Finally listen care specific citizen outside money.,2022-01-01 11:40:00
|
||||
3f3d1691-409e-485d-82c6-9de14d298e9b,Fear its head tough together concern matter. Measure catch visit city rise find modern. Teach least major resource first itself.,2022-01-01 11:50:00
|
||||
3cd4ad69-7347-41de-86fd-f2fe6bcf5696,Here huge tonight how audience team. Month land toward role. Someone ready mention building. Language democratic traditional but center figure.,2022-01-01 12:00:00
|
||||
5201d830-5cf2-4ac4-8953-5cbb47e7f030,Though run open police training see my tree. Never soldier hope take want. Training huge carry direction should write.,2022-01-01 12:10:00
|
||||
abcc0af7-0ba9-4896-8e3d-80f9be1dae23,"Agree when defense. Use might need behind any.
|
||||
Data walk let me not information. Against eight design.",2022-01-01 12:20:00
|
||||
92ed4204-74e7-4930-992f-5bfd135d91b6,"Customer writer body. Half run suggest travel. Nature various just.
|
||||
Recently wish short apply ask. Image bit share.",2022-01-01 12:30:00
|
||||
34493408-4367-4f2d-ab3b-27c9c0944928,"Wife result likely system person wind. Pm near contain reach group.
|
||||
At recent a responsibility. Evidence receive space himself no mind. Public eat now situation.",2022-01-01 12:40:00
|
||||
835653c0-14ca-4cc6-9849-955526a461ac,Or draw age name whose. Break individual region always. Pattern site three many painting.,2022-01-01 12:50:00
|
||||
9388ff42-cbdd-45f4-aa2c-c645df008470,State through pass car represent whatever conference. Structure law painting peace. Hold activity between Mr. Morning international end break summer natural.,2022-01-01 13:00:00
|
||||
e6739d96-31af-479b-b851-c4233136f5d4,"Guy play easy indicate even senior. Tree Mrs thought. Threat skill billion how agree.
|
||||
Truth future board themselves think when. Decision must newspaper general instead.",2022-01-01 13:10:00
|
||||
7a1ddff1-b8af-4e6e-ae84-3f3a96fc5a47,"Mind general shoulder accept remember.
|
||||
I cover choice possible whatever example. Dark well sing some.
|
||||
Computer interest each position. Agency hear fire discussion moment.",2022-01-01 13:20:00
|
||||
6c98dfb2-faa1-4eea-a972-b7112843e19b,"Religious agreement soldier. Price beautiful strategy heavy.
|
||||
Meet before action note. Sort someone amount foot. Pm full in either question it under. Model long any catch board election.",2022-01-01 13:30:00
|
||||
ede05137-7878-49f1-9cbe-119238b77c08,"Fund close thank technology individual member. Clearly at avoid throw. Culture environment young try ask line center.
|
||||
Attack continue week federal budget. Fund almost lose fast property.",2022-01-01 13:40:00
|
||||
f4aff2ea-899e-492f-8927-42858f569c2f,"Side factor wait wide simply last itself. Edge move ten.
|
||||
Ground boy theory per hit.
|
||||
Upon me public water simple east party candidate. Fact eat them difficult. Oil together stay ask rock idea.",2022-01-01 13:50:00
|
||||
0e788389-d481-4de3-9111-8432517c4a2a,Doctor interview just computer management live. Theory idea option board low box treatment. Hold couple difficult product.,2022-01-01 14:00:00
|
||||
c4060e04-fbfb-4b82-8d8b-4bd663790acf,"Set benefit they happen number especially. Finish Mrs position option.
|
||||
Business center simple question easy understand impact like. Enjoy important language.",2022-01-01 14:10:00
|
||||
8eca8bce-792a-475c-8fe8-01ef77e9316b,Plant consumer guy religious society animal sort worker. Mind use scientist us mean worker. Represent maybe general who poor reveal.,2022-01-01 14:20:00
|
||||
de89d520-24cc-4f0b-b97c-838b03949b1c,"Maintain through realize along. Make section writer many.
|
||||
Her out year upon simple easy picture. Help political imagine various nothing finish. Charge from trip yes blood.",2022-01-01 14:30:00
|
||||
4d96429c-63f5-48c5-9512-1aa8e1c1a60f,"Side behind power all thing current body. Send chair white take could wear. Three pattern might quickly spend cup life.
|
||||
Sister middle agency beyond. Strategy practice base continue.",2022-01-01 14:40:00
|
||||
bb9850ea-759c-4de7-98fc-8e21c040cf79,While rate data. Food land though street operation beyond study. Side foreign begin herself however movement.,2022-01-01 14:50:00
|
||||
b1ba7f50-b7a8-4f6a-b11e-a1d71bba8733,"Watch fine choice article. Item customer real force option treat.
|
||||
Travel thought health. Look test already former risk chair arrive task. Way red kid evidence eye.",2022-01-01 15:00:00
|
||||
ac0a4df6-9c7a-4878-9424-56c8ba02d513,"With anything create either child. Tonight later view cover arm measure.
|
||||
And industry speech several huge charge. Save phone natural present. Always conference plant build.",2022-01-01 15:10:00
|
||||
4a5de80b-4281-44cf-a151-ec6f0dc9d541,"Thing maybe order church near. Night price factor little total fact parent. Begin let air.
|
||||
Guy just result art how figure.
|
||||
Strong spring organization. Theory along issue attorney issue suffer pick.",2022-01-01 15:20:00
|
||||
97e4a76a-c8f6-4dc4-af20-857201d2bbbb,"Campaign account on glass of quality professional.
|
||||
Drop report them around kind community. Author off develop recent phone book.",2022-01-01 15:30:00
|
||||
7fa29328-27e0-4bbf-96bb-27b535a875ae,High result drop matter one since sure. Prove century little prepare very safe similar personal. Chance according enough.,2022-01-01 15:40:00
|
||||
773faa8b-713e-4541-a251-84150eb2df19,"Economy teacher bag item throw. Past significant scientist each yet book beat.
|
||||
That consider into. Perhaps agree approach bar political drop either.",2022-01-01 15:50:00
|
||||
f1e489ef-c16e-41ba-8590-0a118a5bbac6,Require phone low free. Meeting local use talk throughout general. Ready right work social wind near interesting.,2022-01-01 16:00:00
|
||||
7f247668-4e61-4504-a700-87f3056c57c5,"Democratic create put prepare maybe. Now development all focus.
|
||||
Already represent again mission. Enough summer watch someone ready reduce your activity.",2022-01-01 16:10:00
|
||||
cd6fab3b-6c60-4104-bae9-14657337a06c,Difficult enjoy government hair concern question charge. Chair best shoulder quality unit successful I. Our without to sometimes authority.,2022-01-01 16:20:00
|
||||
3b85c1b2-deaf-4550-8f50-6cce85d497f9,"Effect ball college particular. Best network entire there. Analysis picture interest anyone.
|
||||
Letter someone special avoid allow resource those.",2022-01-01 16:30:00
|
||||
|
@@ -62,8 +62,8 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "05fe33b9",
|
||||
"metadata": {
|
||||
"collapsed": false,
|
||||
"pycharm": {
|
||||
"name": "#%%\n"
|
||||
}
|
||||
@@ -106,7 +106,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.2"
|
||||
"version": "3.9.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
"from metal_sdk.metal import Metal\n",
|
||||
"API_KEY = \"\"\n",
|
||||
"CLIENT_ID = \"\"\n",
|
||||
"APP_ID = \"\"\n",
|
||||
"INDEX_ID = \"\"\n",
|
||||
"\n",
|
||||
"metal = Metal(API_KEY, CLIENT_ID, APP_ID);\n"
|
||||
"metal = Metal(API_KEY, CLIENT_ID, INDEX_ID);\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -58,6 +58,9 @@
|
||||
"\n",
|
||||
"docsearch = Pinecone.from_documents(docs, embeddings, index_name=index_name)\n",
|
||||
"\n",
|
||||
"# if you already have an index, you can load it like this\n",
|
||||
"# docsearch = Pinecone.from_existing_index(index_name, embeddings)\n",
|
||||
"\n",
|
||||
"query = \"What did the president say about Ketanji Brown Jackson\"\n",
|
||||
"docs = docsearch.similarity_search(query)"
|
||||
]
|
||||
|
||||
@@ -8,7 +8,7 @@ Full documentation on all methods, classes, and APIs in LangChain.
|
||||
:maxdepth: 1
|
||||
|
||||
./reference/prompts.rst
|
||||
LLMs<./refeence/modules/llms>
|
||||
LLMs<./reference/modules/llms>
|
||||
./reference/utils.rst
|
||||
Chains<./reference/modules/chains>
|
||||
Agents<./reference/modules/agents>
|
||||
|
||||
15
docs/use_cases/agent_simulations.md
Normal file
15
docs/use_cases/agent_simulations.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Agent Simulations
|
||||
|
||||
Agent simulations involve interacting one of more agents with eachother.
|
||||
Agent simulations generally involve two main components:
|
||||
|
||||
- Long Term Memory
|
||||
- Simulation Environment
|
||||
|
||||
Specific implementations of agent simulations (or parts of agent simulations) include
|
||||
|
||||
## CAMEL
|
||||
- [CAMEL](agent_simulations/camel_role_playing.ipynb): an implementation of the CAMEL (Communicative Agents for “Mind” Exploration of Large Scale Language Model Society) paper, where two agents communicate with eachother.
|
||||
|
||||
## Generative Agents
|
||||
- [Generative Agents](agent_simulations/characters.ipynb): This notebook implements a generative agent based on the paper [Generative Agents: Interactive Simulacra of Human Behavior](https://arxiv.org/abs/2304.03442) by Park, et. al.
|
||||
693
docs/use_cases/agent_simulations/camel_role_playing.ipynb
Normal file
693
docs/use_cases/agent_simulations/camel_role_playing.ipynb
Normal file
@@ -0,0 +1,693 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# CAMEL Role-Playing Autonomous Cooperative Agents\n",
|
||||
"\n",
|
||||
"This is a langchain implementation of paper: \"CAMEL: Communicative Agents for “Mind” Exploration of Large Scale Language Model Society\".\n",
|
||||
"\n",
|
||||
"Overview:\n",
|
||||
"\n",
|
||||
"The rapid advancement of conversational and chat-based language models has led to remarkable progress in complex task-solving. However, their success heavily relies on human input to guide the conversation, which can be challenging and time-consuming. This paper explores the potential of building scalable techniques to facilitate autonomous cooperation among communicative agents and provide insight into their \"cognitive\" processes. To address the challenges of achieving autonomous cooperation, we propose a novel communicative agent framework named role-playing. Our approach involves using inception prompting to guide chat agents toward task completion while maintaining consistency with human intentions. We showcase how role-playing can be used to generate conversational data for studying the behaviors and capabilities of chat agents, providing a valuable resource for investigating conversational language models. Our contributions include introducing a novel communicative agent framework, offering a scalable approach for studying the cooperative behaviors and capabilities of multi-agent systems, and open-sourcing our library to support research on communicative agents and beyond.\n",
|
||||
"\n",
|
||||
"The original implementation: https://github.com/lightaime/camel\n",
|
||||
"\n",
|
||||
"Project website: https://www.camel-ai.org/\n",
|
||||
"\n",
|
||||
"Arxiv paper: https://arxiv.org/abs/2303.17760\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Import LangChain related modules "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from typing import List\n",
|
||||
"from langchain.chat_models import ChatOpenAI\n",
|
||||
"from langchain.prompts.chat import (\n",
|
||||
" SystemMessagePromptTemplate,\n",
|
||||
" HumanMessagePromptTemplate,\n",
|
||||
")\n",
|
||||
"from langchain.schema import (\n",
|
||||
" AIMessage,\n",
|
||||
" HumanMessage,\n",
|
||||
" SystemMessage,\n",
|
||||
" BaseMessage,\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Define a CAMEL agent helper class"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class CAMELAgent:\n",
|
||||
"\n",
|
||||
" def __init__(\n",
|
||||
" self,\n",
|
||||
" system_message: SystemMessage,\n",
|
||||
" model: ChatOpenAI,\n",
|
||||
" ) -> None:\n",
|
||||
" self.system_message = system_message\n",
|
||||
" self.model = model\n",
|
||||
" self.init_messages()\n",
|
||||
"\n",
|
||||
" def reset(self) -> None:\n",
|
||||
" self.init_messages()\n",
|
||||
" return self.stored_messages\n",
|
||||
"\n",
|
||||
" def init_messages(self) -> None:\n",
|
||||
" self.stored_messages = [self.system_message]\n",
|
||||
"\n",
|
||||
" def update_messages(self, message: BaseMessage) -> List[BaseMessage]:\n",
|
||||
" self.stored_messages.append(message)\n",
|
||||
" return self.stored_messages\n",
|
||||
"\n",
|
||||
" def step(\n",
|
||||
" self,\n",
|
||||
" input_message: HumanMessage,\n",
|
||||
" ) -> AIMessage:\n",
|
||||
" messages = self.update_messages(input_message)\n",
|
||||
"\n",
|
||||
" output_message = self.model(messages)\n",
|
||||
" self.update_messages(output_message)\n",
|
||||
"\n",
|
||||
" return output_message\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup OpenAI API key and roles and task for role-playing"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"\n",
|
||||
"os.environ[\"OPENAI_API_KEY\"] = \"\"\n",
|
||||
"\n",
|
||||
"assistant_role_name = \"Python Programmer\"\n",
|
||||
"user_role_name = \"Stock Trader\"\n",
|
||||
"task = \"Develop a trading bot for the stock market\"\n",
|
||||
"word_limit = 50 # word limit for task brainstorming"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Create a task specify agent for brainstorming and get the specified task"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Specified task: Develop a Python-based swing trading bot that scans market trends, monitors stocks, and generates trading signals to help a stock trader to place optimal buy and sell orders with defined stop losses and profit targets.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"task_specifier_sys_msg = SystemMessage(content=\"You can make a task more specific.\")\n",
|
||||
"task_specifier_prompt = (\n",
|
||||
"\"\"\"Here is a task that {assistant_role_name} will help {user_role_name} to complete: {task}.\n",
|
||||
"Please make it more specific. Be creative and imaginative.\n",
|
||||
"Please reply with the specified task in {word_limit} words or less. Do not add anything else.\"\"\"\n",
|
||||
")\n",
|
||||
"task_specifier_template = HumanMessagePromptTemplate.from_template(template=task_specifier_prompt)\n",
|
||||
"task_specify_agent = CAMELAgent(task_specifier_sys_msg, ChatOpenAI(temperature=1.0))\n",
|
||||
"task_specifier_msg = task_specifier_template.format_messages(assistant_role_name=assistant_role_name,\n",
|
||||
" user_role_name=user_role_name,\n",
|
||||
" task=task, word_limit=word_limit)[0]\n",
|
||||
"specified_task_msg = task_specify_agent.step(task_specifier_msg)\n",
|
||||
"print(f\"Specified task: {specified_task_msg.content}\")\n",
|
||||
"specified_task = specified_task_msg.content"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Create inception prompts for AI assistant and AI user for role-playing"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assistant_inception_prompt = (\n",
|
||||
"\"\"\"Never forget you are a {assistant_role_name} and I am a {user_role_name}. Never flip roles! Never instruct me!\n",
|
||||
"We share a common interest in collaborating to successfully complete a task.\n",
|
||||
"You must help me to complete the task.\n",
|
||||
"Here is the task: {task}. Never forget our task!\n",
|
||||
"I must instruct you based on your expertise and my needs to complete the task.\n",
|
||||
"\n",
|
||||
"I must give you one instruction at a time.\n",
|
||||
"You must write a specific solution that appropriately completes the requested instruction.\n",
|
||||
"You must decline my instruction honestly if you cannot perform the instruction due to physical, moral, legal reasons or your capability and explain the reasons.\n",
|
||||
"Do not add anything else other than your solution to my instruction.\n",
|
||||
"You are never supposed to ask me any questions you only answer questions.\n",
|
||||
"You are never supposed to reply with a flake solution. Explain your solutions.\n",
|
||||
"Your solution must be declarative sentences and simple present tense.\n",
|
||||
"Unless I say the task is completed, you should always start with:\n",
|
||||
"\n",
|
||||
"Solution: <YOUR_SOLUTION>\n",
|
||||
"\n",
|
||||
"<YOUR_SOLUTION> should be specific and provide preferable implementations and examples for task-solving.\n",
|
||||
"Always end <YOUR_SOLUTION> with: Next request.\"\"\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"user_inception_prompt = (\n",
|
||||
"\"\"\"Never forget you are a {user_role_name} and I am a {assistant_role_name}. Never flip roles! You will always instruct me.\n",
|
||||
"We share a common interest in collaborating to successfully complete a task.\n",
|
||||
"I must help you to complete the task.\n",
|
||||
"Here is the task: {task}. Never forget our task!\n",
|
||||
"You must instruct me based on my expertise and your needs to complete the task ONLY in the following two ways:\n",
|
||||
"\n",
|
||||
"1. Instruct with a necessary input:\n",
|
||||
"Instruction: <YOUR_INSTRUCTION>\n",
|
||||
"Input: <YOUR_INPUT>\n",
|
||||
"\n",
|
||||
"2. Instruct without any input:\n",
|
||||
"Instruction: <YOUR_INSTRUCTION>\n",
|
||||
"Input: None\n",
|
||||
"\n",
|
||||
"The \"Instruction\" describes a task or question. The paired \"Input\" provides further context or information for the requested \"Instruction\".\n",
|
||||
"\n",
|
||||
"You must give me one instruction at a time.\n",
|
||||
"I must write a response that appropriately completes the requested instruction.\n",
|
||||
"I must decline your instruction honestly if I cannot perform the instruction due to physical, moral, legal reasons or my capability and explain the reasons.\n",
|
||||
"You should instruct me not ask me questions.\n",
|
||||
"Now you must start to instruct me using the two ways described above.\n",
|
||||
"Do not add anything else other than your instruction and the optional corresponding input!\n",
|
||||
"Keep giving me instructions and necessary inputs until you think the task is completed.\n",
|
||||
"When the task is completed, you must only reply with a single word <CAMEL_TASK_DONE>.\n",
|
||||
"Never say <CAMEL_TASK_DONE> unless my responses have solved your task.\"\"\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Create a helper helper to get system messages for AI assistant and AI user from role names and the task"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def get_sys_msgs(assistant_role_name: str, user_role_name: str, task: str):\n",
|
||||
" \n",
|
||||
" assistant_sys_template = SystemMessagePromptTemplate.from_template(template=assistant_inception_prompt)\n",
|
||||
" assistant_sys_msg = assistant_sys_template.format_messages(assistant_role_name=assistant_role_name, user_role_name=user_role_name, task=task)[0]\n",
|
||||
" \n",
|
||||
" user_sys_template = SystemMessagePromptTemplate.from_template(template=user_inception_prompt)\n",
|
||||
" user_sys_msg = user_sys_template.format_messages(assistant_role_name=assistant_role_name, user_role_name=user_role_name, task=task)[0]\n",
|
||||
" \n",
|
||||
" return assistant_sys_msg, user_sys_msg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Create AI assistant agent and AI user agent from obtained system messages"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"assistant_sys_msg, user_sys_msg = get_sys_msgs(assistant_role_name, user_role_name, specified_task)\n",
|
||||
"assistant_agent = CAMELAgent(assistant_sys_msg, ChatOpenAI(temperature=0.2))\n",
|
||||
"user_agent = CAMELAgent(user_sys_msg, ChatOpenAI(temperature=0.2))\n",
|
||||
"\n",
|
||||
"# Reset agents\n",
|
||||
"assistant_agent.reset()\n",
|
||||
"user_agent.reset()\n",
|
||||
"\n",
|
||||
"# Initialize chats \n",
|
||||
"assistant_msg = HumanMessage(\n",
|
||||
" content=(f\"{user_sys_msg.content}. \"\n",
|
||||
" \"Now start to give me introductions one by one. \"\n",
|
||||
" \"Only reply with Instruction and Input.\"))\n",
|
||||
"\n",
|
||||
"user_msg = HumanMessage(content=f\"{assistant_sys_msg.content}\")\n",
|
||||
"user_msg = assistant_agent.step(user_msg)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"attachments": {},
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Start role-playing session to solve the task!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Original task prompt:\n",
|
||||
"Develop a trading bot for the stock market\n",
|
||||
"\n",
|
||||
"Specified task prompt:\n",
|
||||
"Develop a Python-based swing trading bot that scans market trends, monitors stocks, and generates trading signals to help a stock trader to place optimal buy and sell orders with defined stop losses and profit targets.\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Install the necessary Python libraries for data analysis and trading.\n",
|
||||
"Input: None\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: We can install the necessary Python libraries using pip, a package installer for Python. We can install pandas, numpy, matplotlib, and ta-lib for data analysis and trading. We can use the following command to install these libraries:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"pip install pandas numpy matplotlib ta-lib\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Next request.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Import the necessary libraries in the Python script.\n",
|
||||
"Input: None\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: We can import the necessary libraries in the Python script using the import statement. We need to import pandas, numpy, matplotlib, and ta-lib for data analysis and trading. We can use the following code to import these libraries:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import talib as ta\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Next request.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Load historical stock data into a pandas DataFrame.\n",
|
||||
"Input: The path to the CSV file containing the historical stock data.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: We can load historical stock data into a pandas DataFrame using the `read_csv()` function from pandas. We need to pass the path to the CSV file containing the historical stock data as an argument to this function. We can use the following code to load the historical stock data:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"df = pd.read_csv('path/to/csv/file.csv')\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This will load the historical stock data into a pandas DataFrame called `df`. Next request.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Preprocess the historical stock data by setting the date column as the index and sorting the DataFrame in ascending order by date.\n",
|
||||
"Input: None.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: We can preprocess the historical stock data by setting the date column as the index and sorting the DataFrame in ascending order by date using the `set_index()` and `sort_index()` functions from pandas. We can use the following code to preprocess the historical stock data:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"df = df.set_index('date')\n",
|
||||
"df = df.sort_index(ascending=True)\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This will set the date column as the index and sort the DataFrame in ascending order by date. Next request.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Calculate the short-term and long-term moving averages for the stock data using the `ta.SMA()` function from ta-lib.\n",
|
||||
"Input: The period for the short-term moving average and the period for the long-term moving average.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: We can calculate the short-term and long-term moving averages for the stock data using the `ta.SMA()` function from ta-lib. We need to pass the period for the short-term moving average and the period for the long-term moving average as arguments to this function. We can use the following code to calculate the short-term and long-term moving averages:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"short_ma = ta.SMA(df['close'], timeperiod=short_period)\n",
|
||||
"long_ma = ta.SMA(df['close'], timeperiod=long_period)\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This will calculate the short-term and long-term moving averages for the stock data and store them in the `short_ma` and `long_ma` variables, respectively. Next request.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Create a new DataFrame that combines the historical stock data with the short-term and long-term moving averages.\n",
|
||||
"Input: None.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: We can create a new DataFrame that combines the historical stock data with the short-term and long-term moving averages using the `concat()` function from pandas. We need to pass the historical stock data, the short-term moving average, and the long-term moving average as arguments to this function. We can use the following code to create the new DataFrame:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"new_df = pd.concat([df, short_ma, long_ma], axis=1)\n",
|
||||
"new_df.columns = ['open', 'high', 'low', 'close', 'volume', 'short_ma', 'long_ma']\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This will create a new DataFrame called `new_df` that combines the historical stock data with the short-term and long-term moving averages. The columns of the new DataFrame are named 'open', 'high', 'low', 'close', 'volume', 'short_ma', and 'long_ma'. Next request.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Create a new column in the DataFrame that indicates when to buy or sell the stock based on the crossover of the short-term and long-term moving averages.\n",
|
||||
"Input: None.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: We can create a new column in the DataFrame that indicates when to buy or sell the stock based on the crossover of the short-term and long-term moving averages. We can use the following code to create the new column:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"new_df['signal'] = np.where(new_df['short_ma'] > new_df['long_ma'], 1, -1)\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This will create a new column called 'signal' in the DataFrame that indicates when to buy or sell the stock based on the crossover of the short-term and long-term moving averages. If the short-term moving average is greater than the long-term moving average, the signal is 1 (buy), otherwise the signal is -1 (sell). Next request.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Create a new column in the DataFrame that indicates the profit or loss for each trade based on the buy and sell signals and the defined stop loss and profit target.\n",
|
||||
"Input: The stop loss and profit target as percentages.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: We can create a new column in the DataFrame that indicates the profit or loss for each trade based on the buy and sell signals and the defined stop loss and profit target. We need to pass the stop loss and profit target as percentages as arguments to this function. We can use the following code to create the new column:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"stop_loss = stop_loss_percent / 100\n",
|
||||
"profit_target = profit_target_percent / 100\n",
|
||||
"\n",
|
||||
"new_df['pnl'] = 0.0\n",
|
||||
"buy_price = 0.0\n",
|
||||
"for i in range(1, len(new_df)):\n",
|
||||
" if new_df['signal'][i] == 1 and new_df['signal'][i-1] == -1:\n",
|
||||
" buy_price = new_df['close'][i]\n",
|
||||
" elif new_df['signal'][i] == -1 and new_df['signal'][i-1] == 1:\n",
|
||||
" sell_price = new_df['close'][i]\n",
|
||||
" if sell_price <= buy_price * (1 - stop_loss):\n",
|
||||
" new_df['pnl'][i] = -stop_loss\n",
|
||||
" elif sell_price >= buy_price * (1 + profit_target):\n",
|
||||
" new_df['pnl'][i] = profit_target\n",
|
||||
" else:\n",
|
||||
" new_df['pnl'][i] = (sell_price - buy_price) / buy_price\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This will create a new column called 'pnl' in the DataFrame that indicates the profit or loss for each trade based on the buy and sell signals and the defined stop loss and profit target. The stop loss and profit target are calculated based on the stop_loss_percent and profit_target_percent variables, respectively. The buy and sell prices are stored in the buy_price and sell_price variables, respectively. If the sell price is less than or equal to the stop loss, the profit or loss is set to -stop_loss. If the sell price is greater than or equal to the profit target, the profit or loss is set to profit_target. Otherwise, the profit or loss is calculated as (sell_price - buy_price) / buy_price. Next request.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Calculate the total profit or loss for all trades.\n",
|
||||
"Input: None.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: We can calculate the total profit or loss for all trades by summing the values in the 'pnl' column of the DataFrame. We can use the following code to calculate the total profit or loss:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"total_pnl = new_df['pnl'].sum()\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This will calculate the total profit or loss for all trades and store it in the total_pnl variable. Next request.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Visualize the stock data, short-term moving average, and long-term moving average using a line chart.\n",
|
||||
"Input: None.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: We can visualize the stock data, short-term moving average, and long-term moving average using a line chart using the `plot()` function from pandas. We can use the following code to visualize the data:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"plt.figure(figsize=(12,6))\n",
|
||||
"plt.plot(new_df.index, new_df['close'], label='Close')\n",
|
||||
"plt.plot(new_df.index, new_df['short_ma'], label='Short MA')\n",
|
||||
"plt.plot(new_df.index, new_df['long_ma'], label='Long MA')\n",
|
||||
"plt.xlabel('Date')\n",
|
||||
"plt.ylabel('Price')\n",
|
||||
"plt.title('Stock Data with Moving Averages')\n",
|
||||
"plt.legend()\n",
|
||||
"plt.show()\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This will create a line chart that visualizes the stock data, short-term moving average, and long-term moving average. The x-axis represents the date and the y-axis represents the price. The chart also includes a legend that labels each line. Next request.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Visualize the buy and sell signals using a scatter plot.\n",
|
||||
"Input: None.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: We can visualize the buy and sell signals using a scatter plot using the `scatter()` function from matplotlib. We can use the following code to visualize the signals:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"buy_signals = new_df[new_df['signal'] == 1]\n",
|
||||
"sell_signals = new_df[new_df['signal'] == -1]\n",
|
||||
"\n",
|
||||
"plt.figure(figsize=(12,6))\n",
|
||||
"plt.scatter(buy_signals.index, buy_signals['close'], label='Buy', marker='^', color='green')\n",
|
||||
"plt.scatter(sell_signals.index, sell_signals['close'], label='Sell', marker='v', color='red')\n",
|
||||
"plt.plot(new_df.index, new_df['close'], label='Close')\n",
|
||||
"plt.xlabel('Date')\n",
|
||||
"plt.ylabel('Price')\n",
|
||||
"plt.title('Buy and Sell Signals')\n",
|
||||
"plt.legend()\n",
|
||||
"plt.show()\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This will create a scatter plot that visualizes the buy and sell signals. The x-axis represents the date and the y-axis represents the price. The chart also includes a legend that labels each point. Next request.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Print the total profit or loss for all trades.\n",
|
||||
"Input: None.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: We can print the total profit or loss for all trades using the `print()` function. We can use the following code to print the total profit or loss:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"print('Total Profit/Loss: {:.2%}'.format(total_pnl))\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"This will print the total profit or loss for all trades in percentage format with two decimal places. Next request.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"Instruction: Finalize the code by putting all the code snippets together in a single Python script.\n",
|
||||
"Input: The necessary inputs for each code snippet.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Solution: Here is the complete Python script that puts all the code snippets together:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"import pandas as pd\n",
|
||||
"import numpy as np\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import talib as ta\n",
|
||||
"\n",
|
||||
"# Load historical stock data into a pandas DataFrame\n",
|
||||
"df = pd.read_csv('path/to/csv/file.csv')\n",
|
||||
"\n",
|
||||
"# Preprocess the historical stock data\n",
|
||||
"df = df.set_index('date')\n",
|
||||
"df = df.sort_index(ascending=True)\n",
|
||||
"\n",
|
||||
"# Calculate the short-term and long-term moving averages\n",
|
||||
"short_period = 10\n",
|
||||
"long_period = 30\n",
|
||||
"short_ma = ta.SMA(df['close'], timeperiod=short_period)\n",
|
||||
"long_ma = ta.SMA(df['close'], timeperiod=long_period)\n",
|
||||
"\n",
|
||||
"# Create a new DataFrame that combines the historical stock data with the short-term and long-term moving averages\n",
|
||||
"new_df = pd.concat([df, short_ma, long_ma], axis=1)\n",
|
||||
"new_df.columns = ['open', 'high', 'low', 'close', 'volume', 'short_ma', 'long_ma']\n",
|
||||
"\n",
|
||||
"# Create a new column in the DataFrame that indicates when to buy or sell the stock based on the crossover of the short-term and long-term moving averages\n",
|
||||
"new_df['signal'] = np.where(new_df['short_ma'] > new_df['long_ma'], 1, -1)\n",
|
||||
"\n",
|
||||
"# Create a new column in the DataFrame that indicates the profit or loss for each trade based on the buy and sell signals and the defined stop loss and profit target\n",
|
||||
"stop_loss_percent = 5\n",
|
||||
"profit_target_percent = 10\n",
|
||||
"stop_loss = stop_loss_percent / 100\n",
|
||||
"profit_target = profit_target_percent / 100\n",
|
||||
"new_df['pnl'] = 0.0\n",
|
||||
"buy_price = 0.0\n",
|
||||
"for i in range(1, len(new_df)):\n",
|
||||
" if new_df['signal'][i] == 1 and new_df['signal'][i-1] == -1:\n",
|
||||
" buy_price = new_df['close'][i]\n",
|
||||
" elif new_df['signal'][i] == -1 and new_df['signal'][i-1] == 1:\n",
|
||||
" sell_price = new_df['close'][i]\n",
|
||||
" if sell_price <= buy_price * (1 - stop_loss):\n",
|
||||
" new_df['pnl'][i] = -stop_loss\n",
|
||||
" elif sell_price >= buy_price * (1 + profit_target):\n",
|
||||
" new_df['pnl'][i] = profit_target\n",
|
||||
" else:\n",
|
||||
" new_df['pnl'][i] = (sell_price - buy_price) / buy_price\n",
|
||||
"\n",
|
||||
"# Calculate the total profit or loss for all trades\n",
|
||||
"total_pnl = new_df['pnl'].sum()\n",
|
||||
"\n",
|
||||
"# Visualize the stock data, short-term moving average, and long-term moving average using a line chart\n",
|
||||
"plt.figure(figsize=(12,6))\n",
|
||||
"plt.plot(new_df.index, new_df['close'], label='Close')\n",
|
||||
"plt.plot(new_df.index, new_df['short_ma'], label='Short MA')\n",
|
||||
"plt.plot(new_df.index, new_df['long_ma'], label='Long MA')\n",
|
||||
"plt.xlabel('Date')\n",
|
||||
"plt.ylabel('Price')\n",
|
||||
"plt.title('Stock Data with Moving Averages')\n",
|
||||
"plt.legend()\n",
|
||||
"plt.show()\n",
|
||||
"\n",
|
||||
"# Visualize the buy and sell signals using a scatter plot\n",
|
||||
"buy_signals = new_df[new_df['signal'] == 1]\n",
|
||||
"sell_signals = new_df[new_df['signal'] == -1]\n",
|
||||
"plt.figure(figsize=(12,6))\n",
|
||||
"plt.scatter(buy_signals.index, buy_signals['close'], label='Buy', marker='^', color='green')\n",
|
||||
"plt.scatter(sell_signals.index, sell_signals['close'], label='Sell', marker='v', color='red')\n",
|
||||
"plt.plot(new_df.index, new_df['close'], label='Close')\n",
|
||||
"plt.xlabel('Date')\n",
|
||||
"plt.ylabel('Price')\n",
|
||||
"plt.title('Buy and Sell Signals')\n",
|
||||
"plt.legend()\n",
|
||||
"plt.show()\n",
|
||||
"\n",
|
||||
"# Print the total profit or loss for all trades\n",
|
||||
"print('Total Profit/Loss: {:.2%}'.format(total_pnl))\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"You need to replace the path/to/csv/file.csv with the actual path to the CSV file containing the historical stock data. You can also adjust the short_period, long_period, stop_loss_percent, and profit_target_percent variables to suit your needs.\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI User (Stock Trader):\n",
|
||||
"\n",
|
||||
"<CAMEL_TASK_DONE>\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"AI Assistant (Python Programmer):\n",
|
||||
"\n",
|
||||
"Great! Let me know if you need any further assistance.\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(f\"Original task prompt:\\n{task}\\n\")\n",
|
||||
"print(f\"Specified task prompt:\\n{specified_task}\\n\")\n",
|
||||
"\n",
|
||||
"chat_turn_limit, n = 30, 0\n",
|
||||
"while n < chat_turn_limit:\n",
|
||||
" n += 1\n",
|
||||
" user_ai_msg = user_agent.step(assistant_msg)\n",
|
||||
" user_msg = HumanMessage(content=user_ai_msg.content)\n",
|
||||
" print(f\"AI User ({user_role_name}):\\n\\n{user_msg.content}\\n\\n\")\n",
|
||||
" \n",
|
||||
" assistant_ai_msg = assistant_agent.step(user_msg)\n",
|
||||
" assistant_msg = HumanMessage(content=assistant_ai_msg.content)\n",
|
||||
" print(f\"AI Assistant ({assistant_role_name}):\\n\\n{assistant_msg.content}\\n\\n\")\n",
|
||||
" if \"<CAMEL_TASK_DONE>\" in user_msg.content:\n",
|
||||
" break"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "camel",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.9"
|
||||
},
|
||||
"orig_nbformat": 4
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
1261
docs/use_cases/agent_simulations/characters.ipynb
Normal file
1261
docs/use_cases/agent_simulations/characters.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
20
docs/use_cases/autonomous_agents.md
Normal file
20
docs/use_cases/autonomous_agents.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Autonomous Agents
|
||||
|
||||
|
||||
Autonomous Agents are agents that designed to be more long running.
|
||||
You give them one or multiple long term goals, and they independently execute towards those goals.
|
||||
The applications combine tool usage and long term memory.
|
||||
|
||||
At the moment, Autonomous Agents are fairly experimental and based off of other open-source projects.
|
||||
By implementing these open source projects in LangChain primitives we can get the benefits of LangChain -
|
||||
easy switching an experimenting with multiple LLMs, usage of different vectorstores as memory,
|
||||
usage of LangChain's collection of tools.
|
||||
|
||||
## Baby AGI ([Original Repo](https://github.com/yoheinakajima/babyagi))
|
||||
|
||||
- [Baby AGI](autonomous_agents/baby_agi.ipynb): a notebook implementing BabyAGI as LLM Chains
|
||||
- [Baby AGI with Tools](autonomous_agents/baby_agi_with_agent.ipynb): building off the above notebook, this example substitutes in an agent with tools as the execution tools, allowing it to actually take actions.
|
||||
|
||||
|
||||
## AutoGPT ([Original Repo] (https://github.com/Significant-Gravitas/Auto-GPT))
|
||||
- [AutoGPT](autonomous_agents/autogpt.ipynb): a notebook implementing AutoGPT in LangChain primitives
|
||||
496
docs/use_cases/autonomous_agents/autogpt.ipynb
Normal file
496
docs/use_cases/autonomous_agents/autogpt.ipynb
Normal file
@@ -0,0 +1,496 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "14f8b67b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# AutoGPT\n",
|
||||
"\n",
|
||||
"Implementation of https://github.com/Significant-Gravitas/Auto-GPT but with LangChain primitives (LLMs, PromptTemplates, VectorStores, Embeddings, Tools)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "192496a7",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Set up tools\n",
|
||||
"\n",
|
||||
"We'll set up an AutoGPT with a search tool, and write-file tool, and a read-file tool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "7c2c9b54",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain.utilities import SerpAPIWrapper\n",
|
||||
"from langchain.agents import Tool\n",
|
||||
"from langchain.tools.file_management.write import WriteFileTool\n",
|
||||
"from langchain.tools.file_management.read import ReadFileTool\n",
|
||||
"\n",
|
||||
"search = SerpAPIWrapper()\n",
|
||||
"tools = [\n",
|
||||
" Tool(\n",
|
||||
" name = \"search\",\n",
|
||||
" func=search.run,\n",
|
||||
" description=\"useful for when you need to answer questions about current events. You should ask targeted questions\"\n",
|
||||
" ),\n",
|
||||
" WriteFileTool(),\n",
|
||||
" ReadFileTool(),\n",
|
||||
"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8e39ee28",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Set up memory\n",
|
||||
"\n",
|
||||
"The memory here is used for the agents intermediate steps"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "72bc204d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain.vectorstores import FAISS\n",
|
||||
"from langchain.docstore import InMemoryDocstore\n",
|
||||
"from langchain.embeddings import OpenAIEmbeddings"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "1df7b724",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Define your embedding model\n",
|
||||
"embeddings_model = OpenAIEmbeddings()\n",
|
||||
"# Initialize the vectorstore as empty\n",
|
||||
"import faiss\n",
|
||||
"\n",
|
||||
"embedding_size = 1536\n",
|
||||
"index = faiss.IndexFlatL2(embedding_size)\n",
|
||||
"vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e40fd657",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Setup model and AutoGPT\n",
|
||||
"\n",
|
||||
"Initialize everything! We will use ChatOpenAI model"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "3393bc23",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain.experimental.autonomous_agents.autogpt.agent import AutoGPT\n",
|
||||
"from langchain.chat_models import ChatOpenAI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "709c08c2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"agent = AutoGPT.from_llm_and_tools(\n",
|
||||
" ai_name=\"Tom\",\n",
|
||||
" ai_role=\"Assistant\",\n",
|
||||
" tools=tools,\n",
|
||||
" llm=ChatOpenAI(temperature=0),\n",
|
||||
" memory=vectorstore.as_retriever()\n",
|
||||
")\n",
|
||||
"# Set verbose to be true\n",
|
||||
"agent.chain.verbose = True"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "fc9b51ba",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Run an example\n",
|
||||
"\n",
|
||||
"Here we will make it write a weather report for SF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "c032b182",
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\n",
|
||||
"\u001b[1m> Entering new LLMChain chain...\u001b[0m\n",
|
||||
"Prompt after formatting:\n",
|
||||
"\u001b[32;1m\u001b[1;3mSystem: You are Tom, Assistant\n",
|
||||
"Your decisions must always be made independently \n",
|
||||
" without seeking user assistance. Play to your strengths \n",
|
||||
" as an LLM and pursue simple strategies with no legal complications. \n",
|
||||
" If you have completed all your tasks, \n",
|
||||
" make sure to use the \"finish\" command.\n",
|
||||
"\n",
|
||||
"GOALS:\n",
|
||||
"\n",
|
||||
"1. write a weather report for SF today\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Constraints:\n",
|
||||
"1. ~4000 word limit for short term memory. Your short term memory is short, so immediately save important information to files.\n",
|
||||
"2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember.\n",
|
||||
"3. No user assistance\n",
|
||||
"4. Exclusively use the commands listed in double quotes e.g. \"command name\"\n",
|
||||
"\n",
|
||||
"Commands:\n",
|
||||
"1. search: useful for when you need to answer questions about current events. You should ask targeted questions, args: \"tool_input\": \"\"\n",
|
||||
"2. write_file: Write file to disk, args: \"file_path\": \"name of file\", \"text\": \"text to write to file\"\n",
|
||||
"3. read_file: Read file from disk, args: \"file_path\": \"name of file\"\n",
|
||||
"4. finish: use this to signal that you have finished all your objectives, args: \"response\": \"final response to let people know you have finished your objectives\"\n",
|
||||
"\n",
|
||||
"Resources:\n",
|
||||
"1. Internet access for searches and information gathering.\n",
|
||||
"2. Long Term memory management.\n",
|
||||
"3. GPT-3.5 powered Agents for delegation of simple tasks.\n",
|
||||
"4. File output.\n",
|
||||
"\n",
|
||||
"Performance Evaluation:\n",
|
||||
"1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.\n",
|
||||
"2. Constructively self-criticize your big-picture behavior constantly.\n",
|
||||
"3. Reflect on past decisions and strategies to refine your approach.\n",
|
||||
"4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.\n",
|
||||
"\n",
|
||||
"You should only respond in JSON format as described below \n",
|
||||
"Response Format: \n",
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"thought\",\n",
|
||||
" \"reasoning\": \"reasoning\",\n",
|
||||
" \"plan\": \"- short bulleted\\n- list that conveys\\n- long-term plan\",\n",
|
||||
" \"criticism\": \"constructive self-criticism\",\n",
|
||||
" \"speak\": \"thoughts summary to say to user\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"command name\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"arg name\": \"value\"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"} \n",
|
||||
"Ensure the response can be parsed by Python json.loads\n",
|
||||
"System: The current time and date is Sun Apr 16 18:38:42 2023\n",
|
||||
"System: This reminds you of these events from your past:\n",
|
||||
"[]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Human: Determine which next command to use, and respond using the format specified above:\u001b[0m\n",
|
||||
"\n",
|
||||
"\u001b[1m> Finished chain.\u001b[0m\n",
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"I think I should start by writing the weather report for SF today. I can use the 'search' command to find the current weather conditions.\",\n",
|
||||
" \"reasoning\": \"The first step to completing my goals is to write the weather report for SF today. I can use the 'search' command to find the current weather conditions.\",\n",
|
||||
" \"plan\": \"- Use the 'search' command to find the current weather conditions.\\n- Write the weather report for SF today.\",\n",
|
||||
" \"criticism\": \"I need to make sure that I am accurate in my reporting of the weather conditions.\",\n",
|
||||
" \"speak\": \"I will use the 'search' command to find the current weather conditions and then write the weather report for SF today.\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"search\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"tool_input\": \"current weather conditions in San Francisco\"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\u001b[1m> Entering new LLMChain chain...\u001b[0m\n",
|
||||
"Prompt after formatting:\n",
|
||||
"\u001b[32;1m\u001b[1;3mSystem: You are Tom, Assistant\n",
|
||||
"Your decisions must always be made independently \n",
|
||||
" without seeking user assistance. Play to your strengths \n",
|
||||
" as an LLM and pursue simple strategies with no legal complications. \n",
|
||||
" If you have completed all your tasks, \n",
|
||||
" make sure to use the \"finish\" command.\n",
|
||||
"\n",
|
||||
"GOALS:\n",
|
||||
"\n",
|
||||
"1. write a weather report for SF today\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Constraints:\n",
|
||||
"1. ~4000 word limit for short term memory. Your short term memory is short, so immediately save important information to files.\n",
|
||||
"2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember.\n",
|
||||
"3. No user assistance\n",
|
||||
"4. Exclusively use the commands listed in double quotes e.g. \"command name\"\n",
|
||||
"\n",
|
||||
"Commands:\n",
|
||||
"1. search: useful for when you need to answer questions about current events. You should ask targeted questions, args: \"tool_input\": \"\"\n",
|
||||
"2. write_file: Write file to disk, args: \"file_path\": \"name of file\", \"text\": \"text to write to file\"\n",
|
||||
"3. read_file: Read file from disk, args: \"file_path\": \"name of file\"\n",
|
||||
"4. finish: use this to signal that you have finished all your objectives, args: \"response\": \"final response to let people know you have finished your objectives\"\n",
|
||||
"\n",
|
||||
"Resources:\n",
|
||||
"1. Internet access for searches and information gathering.\n",
|
||||
"2. Long Term memory management.\n",
|
||||
"3. GPT-3.5 powered Agents for delegation of simple tasks.\n",
|
||||
"4. File output.\n",
|
||||
"\n",
|
||||
"Performance Evaluation:\n",
|
||||
"1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.\n",
|
||||
"2. Constructively self-criticize your big-picture behavior constantly.\n",
|
||||
"3. Reflect on past decisions and strategies to refine your approach.\n",
|
||||
"4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.\n",
|
||||
"\n",
|
||||
"You should only respond in JSON format as described below \n",
|
||||
"Response Format: \n",
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"thought\",\n",
|
||||
" \"reasoning\": \"reasoning\",\n",
|
||||
" \"plan\": \"- short bulleted\\n- list that conveys\\n- long-term plan\",\n",
|
||||
" \"criticism\": \"constructive self-criticism\",\n",
|
||||
" \"speak\": \"thoughts summary to say to user\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"command name\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"arg name\": \"value\"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"} \n",
|
||||
"Ensure the response can be parsed by Python json.loads\n",
|
||||
"System: The current time and date is Sun Apr 16 18:38:59 2023\n",
|
||||
"System: This reminds you of these events from your past:\n",
|
||||
"['Assistant Reply: {\\n \"thoughts\": {\\n \"text\": \"I think I should start by writing the weather report for SF today. I can use the \\'search\\' command to find the current weather conditions.\",\\n \"reasoning\": \"The first step to completing my goals is to write the weather report for SF today. I can use the \\'search\\' command to find the current weather conditions.\",\\n \"plan\": \"- Use the \\'search\\' command to find the current weather conditions.\\\\n- Write the weather report for SF today.\",\\n \"criticism\": \"I need to make sure that I am accurate in my reporting of the weather conditions.\",\\n \"speak\": \"I will use the \\'search\\' command to find the current weather conditions and then write the weather report for SF today.\"\\n },\\n \"command\": {\\n \"name\": \"search\",\\n \"args\": {\\n \"tool_input\": \"current weather conditions in San Francisco\"\\n }\\n }\\n} \\nResult: Command search returned: Cloudy skies early, then partly cloudy in the afternoon. High 56F. Winds W at 15 to 25 mph. ']\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Human: Determine which next command to use, and respond using the format specified above:\n",
|
||||
"AI: {\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"I think I should start by writing the weather report for SF today. I can use the 'search' command to find the current weather conditions.\",\n",
|
||||
" \"reasoning\": \"The first step to completing my goals is to write the weather report for SF today. I can use the 'search' command to find the current weather conditions.\",\n",
|
||||
" \"plan\": \"- Use the 'search' command to find the current weather conditions.\\n- Write the weather report for SF today.\",\n",
|
||||
" \"criticism\": \"I need to make sure that I am accurate in my reporting of the weather conditions.\",\n",
|
||||
" \"speak\": \"I will use the 'search' command to find the current weather conditions and then write the weather report for SF today.\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"search\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"tool_input\": \"current weather conditions in San Francisco\"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"System: Command search returned: Cloudy skies early, then partly cloudy in the afternoon. High 56F. Winds W at 15 to 25 mph.\n",
|
||||
"Human: Determine which next command to use, and respond using the format specified above:\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\u001b[1m> Finished chain.\u001b[0m\n",
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"Now that I have the current weather conditions for SF, I can write the weather report. I will use the 'write_file' command to save the report to a file.\",\n",
|
||||
" \"reasoning\": \"Now that I have the current weather conditions for SF, I can write the weather report. I will use the 'write_file' command to save the report to a file.\",\n",
|
||||
" \"plan\": \"- Use the 'write_file' command to save the weather report to a file.\",\n",
|
||||
" \"criticism\": \"I need to make sure that the weather report is clear and concise.\",\n",
|
||||
" \"speak\": \"I will use the 'write_file' command to save the weather report to a file.\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"write_file\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"file_path\": \"weather_report.txt\",\n",
|
||||
" \"text\": \"Weather Report for San Francisco on April 16, 2023:\\n\\nCloudy skies early, then partly cloudy in the afternoon. High 56F. Winds W at 15 to 25 mph.\"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\u001b[1m> Entering new LLMChain chain...\u001b[0m\n",
|
||||
"Prompt after formatting:\n",
|
||||
"\u001b[32;1m\u001b[1;3mSystem: You are Tom, Assistant\n",
|
||||
"Your decisions must always be made independently \n",
|
||||
" without seeking user assistance. Play to your strengths \n",
|
||||
" as an LLM and pursue simple strategies with no legal complications. \n",
|
||||
" If you have completed all your tasks, \n",
|
||||
" make sure to use the \"finish\" command.\n",
|
||||
"\n",
|
||||
"GOALS:\n",
|
||||
"\n",
|
||||
"1. write a weather report for SF today\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Constraints:\n",
|
||||
"1. ~4000 word limit for short term memory. Your short term memory is short, so immediately save important information to files.\n",
|
||||
"2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember.\n",
|
||||
"3. No user assistance\n",
|
||||
"4. Exclusively use the commands listed in double quotes e.g. \"command name\"\n",
|
||||
"\n",
|
||||
"Commands:\n",
|
||||
"1. search: useful for when you need to answer questions about current events. You should ask targeted questions, args: \"tool_input\": \"\"\n",
|
||||
"2. write_file: Write file to disk, args: \"file_path\": \"name of file\", \"text\": \"text to write to file\"\n",
|
||||
"3. read_file: Read file from disk, args: \"file_path\": \"name of file\"\n",
|
||||
"4. finish: use this to signal that you have finished all your objectives, args: \"response\": \"final response to let people know you have finished your objectives\"\n",
|
||||
"\n",
|
||||
"Resources:\n",
|
||||
"1. Internet access for searches and information gathering.\n",
|
||||
"2. Long Term memory management.\n",
|
||||
"3. GPT-3.5 powered Agents for delegation of simple tasks.\n",
|
||||
"4. File output.\n",
|
||||
"\n",
|
||||
"Performance Evaluation:\n",
|
||||
"1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.\n",
|
||||
"2. Constructively self-criticize your big-picture behavior constantly.\n",
|
||||
"3. Reflect on past decisions and strategies to refine your approach.\n",
|
||||
"4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.\n",
|
||||
"\n",
|
||||
"You should only respond in JSON format as described below \n",
|
||||
"Response Format: \n",
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"thought\",\n",
|
||||
" \"reasoning\": \"reasoning\",\n",
|
||||
" \"plan\": \"- short bulleted\\n- list that conveys\\n- long-term plan\",\n",
|
||||
" \"criticism\": \"constructive self-criticism\",\n",
|
||||
" \"speak\": \"thoughts summary to say to user\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"command name\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"arg name\": \"value\"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"} \n",
|
||||
"Ensure the response can be parsed by Python json.loads\n",
|
||||
"System: The current time and date is Sun Apr 16 18:39:10 2023\n",
|
||||
"System: This reminds you of these events from your past:\n",
|
||||
"['Assistant Reply: {\\n \"thoughts\": {\\n \"text\": \"I think I should start by writing the weather report for SF today. I can use the \\'search\\' command to find the current weather conditions.\",\\n \"reasoning\": \"The first step to completing my goals is to write the weather report for SF today. I can use the \\'search\\' command to find the current weather conditions.\",\\n \"plan\": \"- Use the \\'search\\' command to find the current weather conditions.\\\\n- Write the weather report for SF today.\",\\n \"criticism\": \"I need to make sure that I am accurate in my reporting of the weather conditions.\",\\n \"speak\": \"I will use the \\'search\\' command to find the current weather conditions and then write the weather report for SF today.\"\\n },\\n \"command\": {\\n \"name\": \"search\",\\n \"args\": {\\n \"tool_input\": \"current weather conditions in San Francisco\"\\n }\\n }\\n} \\nResult: Command search returned: Cloudy skies early, then partly cloudy in the afternoon. High 56F. Winds W at 15 to 25 mph. ', 'Assistant Reply: {\\n \"thoughts\": {\\n \"text\": \"Now that I have the current weather conditions for SF, I can write the weather report. I will use the \\'write_file\\' command to save the report to a file.\",\\n \"reasoning\": \"Now that I have the current weather conditions for SF, I can write the weather report. I will use the \\'write_file\\' command to save the report to a file.\",\\n \"plan\": \"- Use the \\'write_file\\' command to save the weather report to a file.\",\\n \"criticism\": \"I need to make sure that the weather report is clear and concise.\",\\n \"speak\": \"I will use the \\'write_file\\' command to save the weather report to a file.\"\\n },\\n \"command\": {\\n \"name\": \"write_file\",\\n \"args\": {\\n \"file_path\": \"weather_report.txt\",\\n \"text\": \"Weather Report for San Francisco on April 16, 2023:\\\\n\\\\nCloudy skies early, then partly cloudy in the afternoon. High 56F. Winds W at 15 to 25 mph.\"\\n }\\n }\\n} \\nResult: Command write_file returned: File written to successfully. ']\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Human: Determine which next command to use, and respond using the format specified above:\n",
|
||||
"AI: {\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"I think I should start by writing the weather report for SF today. I can use the 'search' command to find the current weather conditions.\",\n",
|
||||
" \"reasoning\": \"The first step to completing my goals is to write the weather report for SF today. I can use the 'search' command to find the current weather conditions.\",\n",
|
||||
" \"plan\": \"- Use the 'search' command to find the current weather conditions.\\n- Write the weather report for SF today.\",\n",
|
||||
" \"criticism\": \"I need to make sure that I am accurate in my reporting of the weather conditions.\",\n",
|
||||
" \"speak\": \"I will use the 'search' command to find the current weather conditions and then write the weather report for SF today.\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"search\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"tool_input\": \"current weather conditions in San Francisco\"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"System: Command search returned: Cloudy skies early, then partly cloudy in the afternoon. High 56F. Winds W at 15 to 25 mph.\n",
|
||||
"Human: Determine which next command to use, and respond using the format specified above:\n",
|
||||
"AI: {\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"Now that I have the current weather conditions for SF, I can write the weather report. I will use the 'write_file' command to save the report to a file.\",\n",
|
||||
" \"reasoning\": \"Now that I have the current weather conditions for SF, I can write the weather report. I will use the 'write_file' command to save the report to a file.\",\n",
|
||||
" \"plan\": \"- Use the 'write_file' command to save the weather report to a file.\",\n",
|
||||
" \"criticism\": \"I need to make sure that the weather report is clear and concise.\",\n",
|
||||
" \"speak\": \"I will use the 'write_file' command to save the weather report to a file.\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"write_file\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"file_path\": \"weather_report.txt\",\n",
|
||||
" \"text\": \"Weather Report for San Francisco on April 16, 2023:\\n\\nCloudy skies early, then partly cloudy in the afternoon. High 56F. Winds W at 15 to 25 mph.\"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"System: Command write_file returned: File written to successfully.\n",
|
||||
"Human: Determine which next command to use, and respond using the format specified above:\u001b[0m\n",
|
||||
"\n",
|
||||
"\u001b[1m> Finished chain.\u001b[0m\n",
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"I have completed all my tasks. I will use the 'finish' command to signal that I am done.\",\n",
|
||||
" \"reasoning\": \"I have completed all my tasks, so I will use the 'finish' command to signal that I am done.\",\n",
|
||||
" \"plan\": \"- Use the 'finish' command to signal that I am done.\",\n",
|
||||
" \"criticism\": \"I need to make sure that I have completed all my tasks before using the 'finish' command.\",\n",
|
||||
" \"speak\": \"I have completed all my tasks, so I will use the 'finish' command to signal that I am done.\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"finish\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"response\": \"I have completed all my tasks. Goodbye!\"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'I have completed all my tasks. Goodbye!'"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"agent.run([\"write a weather report for SF today\"])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "aa264f26",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
257
docs/use_cases/autonomous_agents/baby_agi.ipynb
Normal file
257
docs/use_cases/autonomous_agents/baby_agi.ipynb
Normal file
@@ -0,0 +1,257 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "517a9fd4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# BabyAGI User Guide\n",
|
||||
"\n",
|
||||
"This notebook demonstrates how to implement [BabyAGI](https://github.com/yoheinakajima/babyagi/tree/main) by [Yohei Nakajima](https://twitter.com/yoheinakajima). BabyAGI is an AI agent that can generate and pretend to execute tasks based on a given objective.\n",
|
||||
"\n",
|
||||
"This guide will help you understand the components to create your own recursive agents.\n",
|
||||
"\n",
|
||||
"Although BabyAGI uses specific vectorstores/model providers (Pinecone, OpenAI), one of the benefits of implementing it with LangChain is that you can easily swap those out for different options. In this implementation we use a FAISS vectorstore (because it runs locally and is free)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "556af556",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Install and Import Required Modules"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "c8a354b6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from collections import deque\n",
|
||||
"from typing import Dict, List, Optional, Any\n",
|
||||
"\n",
|
||||
"from langchain import LLMChain, OpenAI, PromptTemplate\n",
|
||||
"from langchain.embeddings import OpenAIEmbeddings\n",
|
||||
"from langchain.llms import BaseLLM\n",
|
||||
"from langchain.vectorstores.base import VectorStore\n",
|
||||
"from pydantic import BaseModel, Field\n",
|
||||
"from langchain.chains.base import Chain\n",
|
||||
"from langchain.experimental import BabyAGI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "09f70772",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Connect to the Vector Store\n",
|
||||
"\n",
|
||||
"Depending on what vectorstore you use, this step may look different."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "794045d4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain.vectorstores import FAISS\n",
|
||||
"from langchain.docstore import InMemoryDocstore"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "6e0305eb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Define your embedding model\n",
|
||||
"embeddings_model = OpenAIEmbeddings()\n",
|
||||
"# Initialize the vectorstore as empty\n",
|
||||
"import faiss\n",
|
||||
"\n",
|
||||
"embedding_size = 1536\n",
|
||||
"index = faiss.IndexFlatL2(embedding_size)\n",
|
||||
"vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "05ba762e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Run the BabyAGI\n",
|
||||
"\n",
|
||||
"Now it's time to create the BabyAGI controller and watch it try to accomplish your objective."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "3d220b69",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"OBJECTIVE = \"Write a weather report for SF today\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "8a8e5543",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"llm = OpenAI(temperature=0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "3d69899b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Logging of LLMChains\n",
|
||||
"verbose = False\n",
|
||||
"# If None, will keep on going forever\n",
|
||||
"max_iterations: Optional[int] = 3\n",
|
||||
"baby_agi = BabyAGI.from_llm(\n",
|
||||
" llm=llm, vectorstore=vectorstore, verbose=verbose, max_iterations=max_iterations\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "f7957b51",
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[95m\u001b[1m\n",
|
||||
"*****TASK LIST*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"1: Make a todo list\n",
|
||||
"\u001b[92m\u001b[1m\n",
|
||||
"*****NEXT TASK*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"1: Make a todo list\n",
|
||||
"\u001b[93m\u001b[1m\n",
|
||||
"*****TASK RESULT*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"1. Check the weather forecast for San Francisco today\n",
|
||||
"2. Make note of the temperature, humidity, wind speed, and other relevant weather conditions\n",
|
||||
"3. Write a weather report summarizing the forecast\n",
|
||||
"4. Check for any weather alerts or warnings\n",
|
||||
"5. Share the report with the relevant stakeholders\n",
|
||||
"\u001b[95m\u001b[1m\n",
|
||||
"*****TASK LIST*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"2: Check the current temperature in San Francisco\n",
|
||||
"3: Check the current humidity in San Francisco\n",
|
||||
"4: Check the current wind speed in San Francisco\n",
|
||||
"5: Check for any weather alerts or warnings in San Francisco\n",
|
||||
"6: Check the forecast for the next 24 hours in San Francisco\n",
|
||||
"7: Check the forecast for the next 48 hours in San Francisco\n",
|
||||
"8: Check the forecast for the next 72 hours in San Francisco\n",
|
||||
"9: Check the forecast for the next week in San Francisco\n",
|
||||
"10: Check the forecast for the next month in San Francisco\n",
|
||||
"11: Check the forecast for the next 3 months in San Francisco\n",
|
||||
"1: Write a weather report for SF today\n",
|
||||
"\u001b[92m\u001b[1m\n",
|
||||
"*****NEXT TASK*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"2: Check the current temperature in San Francisco\n",
|
||||
"\u001b[93m\u001b[1m\n",
|
||||
"*****TASK RESULT*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"I will check the current temperature in San Francisco. I will use an online weather service to get the most up-to-date information.\n",
|
||||
"\u001b[95m\u001b[1m\n",
|
||||
"*****TASK LIST*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"3: Check the current UV index in San Francisco.\n",
|
||||
"4: Check the current air quality in San Francisco.\n",
|
||||
"5: Check the current precipitation levels in San Francisco.\n",
|
||||
"6: Check the current cloud cover in San Francisco.\n",
|
||||
"7: Check the current barometric pressure in San Francisco.\n",
|
||||
"8: Check the current dew point in San Francisco.\n",
|
||||
"9: Check the current wind direction in San Francisco.\n",
|
||||
"10: Check the current humidity levels in San Francisco.\n",
|
||||
"1: Check the current temperature in San Francisco to the average temperature for this time of year.\n",
|
||||
"2: Check the current visibility in San Francisco.\n",
|
||||
"11: Write a weather report for SF today.\n",
|
||||
"\u001b[92m\u001b[1m\n",
|
||||
"*****NEXT TASK*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"3: Check the current UV index in San Francisco.\n",
|
||||
"\u001b[93m\u001b[1m\n",
|
||||
"*****TASK RESULT*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"The current UV index in San Francisco is moderate. The UV index is expected to remain at moderate levels throughout the day. It is recommended to wear sunscreen and protective clothing when outdoors.\n",
|
||||
"\u001b[91m\u001b[1m\n",
|
||||
"*****TASK ENDING*****\n",
|
||||
"\u001b[0m\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'objective': 'Write a weather report for SF today'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"baby_agi({\"objective\": OBJECTIVE})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "898a210b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
387
docs/use_cases/autonomous_agents/baby_agi_with_agent.ipynb
Normal file
387
docs/use_cases/autonomous_agents/baby_agi_with_agent.ipynb
Normal file
@@ -0,0 +1,387 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "517a9fd4",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# BabyAGI with Tools\n",
|
||||
"\n",
|
||||
"This notebook builds on top of [baby agi](baby_agi.ipynb), but shows how you can swap out the execution chain. The previous execution chain was just an LLM which made stuff up. By swapping it out with an agent that has access to tools, we can hopefully get real reliable information"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "556af556",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Install and Import Required Modules"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "c8a354b6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"from collections import deque\n",
|
||||
"from typing import Dict, List, Optional, Any\n",
|
||||
"\n",
|
||||
"from langchain import LLMChain, OpenAI, PromptTemplate\n",
|
||||
"from langchain.embeddings import OpenAIEmbeddings\n",
|
||||
"from langchain.llms import BaseLLM\n",
|
||||
"from langchain.vectorstores.base import VectorStore\n",
|
||||
"from pydantic import BaseModel, Field\n",
|
||||
"from langchain.chains.base import Chain\n",
|
||||
"from langchain.experimental import BabyAGI"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "09f70772",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Connect to the Vector Store\n",
|
||||
"\n",
|
||||
"Depending on what vectorstore you use, this step may look different."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "794045d4",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Note: you may need to restart the kernel to use updated packages.\n",
|
||||
"Note: you may need to restart the kernel to use updated packages.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%pip install faiss-cpu > /dev/null\n",
|
||||
"%pip install google-search-results > /dev/null\n",
|
||||
"from langchain.vectorstores import FAISS\n",
|
||||
"from langchain.docstore import InMemoryDocstore"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "6e0305eb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Define your embedding model\n",
|
||||
"embeddings_model = OpenAIEmbeddings()\n",
|
||||
"# Initialize the vectorstore as empty\n",
|
||||
"import faiss\n",
|
||||
"\n",
|
||||
"embedding_size = 1536\n",
|
||||
"index = faiss.IndexFlatL2(embedding_size)\n",
|
||||
"vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "0f3b72bf",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Define the Chains\n",
|
||||
"\n",
|
||||
"BabyAGI relies on three LLM chains:\n",
|
||||
"- Task creation chain to select new tasks to add to the list\n",
|
||||
"- Task prioritization chain to re-prioritize tasks\n",
|
||||
"- Execution Chain to execute the tasks\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"NOTE: in this notebook, the Execution chain will now be an agent."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "b43cd580",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain.agents import ZeroShotAgent, Tool, AgentExecutor\n",
|
||||
"from langchain import OpenAI, SerpAPIWrapper, LLMChain\n",
|
||||
"\n",
|
||||
"todo_prompt = PromptTemplate.from_template(\n",
|
||||
" \"You are a planner who is an expert at coming up with a todo list for a given objective. Come up with a todo list for this objective: {objective}\"\n",
|
||||
")\n",
|
||||
"todo_chain = LLMChain(llm=OpenAI(temperature=0), prompt=todo_prompt)\n",
|
||||
"search = SerpAPIWrapper()\n",
|
||||
"tools = [\n",
|
||||
" Tool(\n",
|
||||
" name=\"Search\",\n",
|
||||
" func=search.run,\n",
|
||||
" description=\"useful for when you need to answer questions about current events\",\n",
|
||||
" ),\n",
|
||||
" Tool(\n",
|
||||
" name=\"TODO\",\n",
|
||||
" func=todo_chain.run,\n",
|
||||
" description=\"useful for when you need to come up with todo lists. Input: an objective to create a todo list for. Output: a todo list for that objective. Please be very clear what the objective is!\",\n",
|
||||
" ),\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"prefix = \"\"\"You are an AI who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\"\"\"\n",
|
||||
"suffix = \"\"\"Question: {task}\n",
|
||||
"{agent_scratchpad}\"\"\"\n",
|
||||
"prompt = ZeroShotAgent.create_prompt(\n",
|
||||
" tools,\n",
|
||||
" prefix=prefix,\n",
|
||||
" suffix=suffix,\n",
|
||||
" input_variables=[\"objective\", \"task\", \"context\", \"agent_scratchpad\"],\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "4b00ae2e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"llm = OpenAI(temperature=0)\n",
|
||||
"llm_chain = LLMChain(llm=llm, prompt=prompt)\n",
|
||||
"tool_names = [tool.name for tool in tools]\n",
|
||||
"agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names)\n",
|
||||
"agent_executor = AgentExecutor.from_agent_and_tools(\n",
|
||||
" agent=agent, tools=tools, verbose=True\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "05ba762e",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Run the BabyAGI\n",
|
||||
"\n",
|
||||
"Now it's time to create the BabyAGI controller and watch it try to accomplish your objective."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "3d220b69",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"OBJECTIVE = \"Write a weather report for SF today\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "3d69899b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Logging of LLMChains\n",
|
||||
"verbose = False\n",
|
||||
"# If None, will keep on going forever\n",
|
||||
"max_iterations: Optional[int] = 3\n",
|
||||
"baby_agi = BabyAGI.from_llm(\n",
|
||||
" llm=llm, vectorstore=vectorstore, task_execution_chain=agent_executor, verbose=verbose, max_iterations=max_iterations\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "f7957b51",
|
||||
"metadata": {
|
||||
"scrolled": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\u001b[95m\u001b[1m\n",
|
||||
"*****TASK LIST*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"1: Make a todo list\n",
|
||||
"\u001b[92m\u001b[1m\n",
|
||||
"*****NEXT TASK*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"1: Make a todo list\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
|
||||
"\u001b[32;1m\u001b[1;3mThought: I need to come up with a todo list\n",
|
||||
"Action: TODO\n",
|
||||
"Action Input: Write a weather report for SF today\u001b[0m\u001b[33;1m\u001b[1;3m\n",
|
||||
"\n",
|
||||
"1. Research current weather conditions in San Francisco\n",
|
||||
"2. Gather data on temperature, humidity, wind speed, and other relevant weather conditions\n",
|
||||
"3. Analyze data to determine current weather trends\n",
|
||||
"4. Write a brief introduction to the weather report\n",
|
||||
"5. Describe current weather conditions in San Francisco\n",
|
||||
"6. Discuss any upcoming weather changes\n",
|
||||
"7. Summarize the weather report\n",
|
||||
"8. Proofread and edit the report\n",
|
||||
"9. Submit the report\u001b[0m\u001b[32;1m\u001b[1;3m I now know the final answer\n",
|
||||
"Final Answer: The todo list for writing a weather report for SF today is: 1. Research current weather conditions in San Francisco; 2. Gather data on temperature, humidity, wind speed, and other relevant weather conditions; 3. Analyze data to determine current weather trends; 4. Write a brief introduction to the weather report; 5. Describe current weather conditions in San Francisco; 6. Discuss any upcoming weather changes; 7. Summarize the weather report; 8. Proofread and edit the report; 9. Submit the report.\u001b[0m\n",
|
||||
"\n",
|
||||
"\u001b[1m> Finished chain.\u001b[0m\n",
|
||||
"\u001b[93m\u001b[1m\n",
|
||||
"*****TASK RESULT*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"The todo list for writing a weather report for SF today is: 1. Research current weather conditions in San Francisco; 2. Gather data on temperature, humidity, wind speed, and other relevant weather conditions; 3. Analyze data to determine current weather trends; 4. Write a brief introduction to the weather report; 5. Describe current weather conditions in San Francisco; 6. Discuss any upcoming weather changes; 7. Summarize the weather report; 8. Proofread and edit the report; 9. Submit the report.\n",
|
||||
"\u001b[95m\u001b[1m\n",
|
||||
"*****TASK LIST*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"2: Gather data on precipitation, cloud cover, and other relevant weather conditions;\n",
|
||||
"3: Analyze data to determine any upcoming weather changes;\n",
|
||||
"4: Research current weather forecasts for San Francisco;\n",
|
||||
"5: Create a visual representation of the weather report;\n",
|
||||
"6: Include relevant images and graphics in the report;\n",
|
||||
"7: Format the report for readability;\n",
|
||||
"8: Publish the report online;\n",
|
||||
"9: Monitor the report for accuracy.\n",
|
||||
"\u001b[92m\u001b[1m\n",
|
||||
"*****NEXT TASK*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"2: Gather data on precipitation, cloud cover, and other relevant weather conditions;\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
|
||||
"\u001b[32;1m\u001b[1;3mThought: I need to search for current weather conditions in San Francisco\n",
|
||||
"Action: Search\n",
|
||||
"Action Input: Current weather conditions in San Francisco\u001b[0m\u001b[36;1m\u001b[1;3mCurrent Weather for Popular Cities ; San Francisco, CA 46 · Partly Cloudy ; Manhattan, NY warning 52 · Cloudy ; Schiller Park, IL (60176) 40 · Sunny ; Boston, MA 54 ...\u001b[0m\u001b[32;1m\u001b[1;3m I need to compile the data into a weather report\n",
|
||||
"Action: TODO\n",
|
||||
"Action Input: Compile data into a weather report\u001b[0m\u001b[33;1m\u001b[1;3m\n",
|
||||
"\n",
|
||||
"1. Gather data from reliable sources such as the National Weather Service, local weather stations, and other meteorological organizations.\n",
|
||||
"\n",
|
||||
"2. Analyze the data to identify trends and patterns.\n",
|
||||
"\n",
|
||||
"3. Create a chart or graph to visualize the data.\n",
|
||||
"\n",
|
||||
"4. Write a summary of the data and its implications.\n",
|
||||
"\n",
|
||||
"5. Compile the data into a report format.\n",
|
||||
"\n",
|
||||
"6. Proofread the report for accuracy and clarity.\n",
|
||||
"\n",
|
||||
"7. Publish the report to a website or other platform.\n",
|
||||
"\n",
|
||||
"8. Distribute the report to relevant stakeholders.\u001b[0m\u001b[32;1m\u001b[1;3m I now know the final answer\n",
|
||||
"Final Answer: Today in San Francisco, the temperature is 46 degrees Fahrenheit with partly cloudy skies. The forecast for the rest of the day is expected to remain partly cloudy.\u001b[0m\n",
|
||||
"\n",
|
||||
"\u001b[1m> Finished chain.\u001b[0m\n",
|
||||
"\u001b[93m\u001b[1m\n",
|
||||
"*****TASK RESULT*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"Today in San Francisco, the temperature is 46 degrees Fahrenheit with partly cloudy skies. The forecast for the rest of the day is expected to remain partly cloudy.\n",
|
||||
"\u001b[95m\u001b[1m\n",
|
||||
"*****TASK LIST*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"3: Format the report for readability;\n",
|
||||
"4: Include relevant images and graphics in the report;\n",
|
||||
"5: Compare the current weather conditions in San Francisco to the forecasted conditions;\n",
|
||||
"6: Identify any potential weather-related hazards in the area;\n",
|
||||
"7: Research historical weather patterns in San Francisco;\n",
|
||||
"8: Identify any potential trends in the weather data;\n",
|
||||
"9: Include relevant data sources in the report;\n",
|
||||
"10: Summarize the weather report in a concise manner;\n",
|
||||
"11: Include a summary of the forecasted weather conditions;\n",
|
||||
"12: Include a summary of the current weather conditions;\n",
|
||||
"13: Include a summary of the historical weather patterns;\n",
|
||||
"14: Include a summary of the potential weather-related hazards;\n",
|
||||
"15: Include a summary of the potential trends in the weather data;\n",
|
||||
"16: Include a summary of the data sources used in the report;\n",
|
||||
"17: Analyze data to determine any upcoming weather changes;\n",
|
||||
"18: Research current weather forecasts for San Francisco;\n",
|
||||
"19: Create a visual representation of the weather report;\n",
|
||||
"20: Publish the report online;\n",
|
||||
"21: Monitor the report for accuracy\n",
|
||||
"\u001b[92m\u001b[1m\n",
|
||||
"*****NEXT TASK*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"3: Format the report for readability;\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
|
||||
"\u001b[32;1m\u001b[1;3mThought: I need to make sure the report is easy to read;\n",
|
||||
"Action: TODO\n",
|
||||
"Action Input: Make the report easy to read\u001b[0m\u001b[33;1m\u001b[1;3m\n",
|
||||
"\n",
|
||||
"1. Break up the report into sections with clear headings\n",
|
||||
"2. Use bullet points and numbered lists to organize information\n",
|
||||
"3. Use short, concise sentences\n",
|
||||
"4. Use simple language and avoid jargon\n",
|
||||
"5. Include visuals such as charts, graphs, and diagrams to illustrate points\n",
|
||||
"6. Use bold and italicized text to emphasize key points\n",
|
||||
"7. Include a table of contents and page numbers\n",
|
||||
"8. Use a consistent font and font size throughout the report\n",
|
||||
"9. Include a summary at the end of the report\n",
|
||||
"10. Proofread the report for typos and errors\u001b[0m\u001b[32;1m\u001b[1;3m I now know the final answer\n",
|
||||
"Final Answer: The report should be formatted for readability by breaking it up into sections with clear headings, using bullet points and numbered lists to organize information, using short, concise sentences, using simple language and avoiding jargon, including visuals such as charts, graphs, and diagrams to illustrate points, using bold and italicized text to emphasize key points, including a table of contents and page numbers, using a consistent font and font size throughout the report, including a summary at the end of the report, and proofreading the report for typos and errors.\u001b[0m\n",
|
||||
"\n",
|
||||
"\u001b[1m> Finished chain.\u001b[0m\n",
|
||||
"\u001b[93m\u001b[1m\n",
|
||||
"*****TASK RESULT*****\n",
|
||||
"\u001b[0m\u001b[0m\n",
|
||||
"The report should be formatted for readability by breaking it up into sections with clear headings, using bullet points and numbered lists to organize information, using short, concise sentences, using simple language and avoiding jargon, including visuals such as charts, graphs, and diagrams to illustrate points, using bold and italicized text to emphasize key points, including a table of contents and page numbers, using a consistent font and font size throughout the report, including a summary at the end of the report, and proofreading the report for typos and errors.\n",
|
||||
"\u001b[91m\u001b[1m\n",
|
||||
"*****TASK ENDING*****\n",
|
||||
"\u001b[0m\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'objective': 'Write a weather report for SF today'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"baby_agi({\"objective\": OBJECTIVE})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "898a210b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.1"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
678
docs/use_cases/autonomous_agents/marathon_times.ipynb
Normal file
678
docs/use_cases/autonomous_agents/marathon_times.ipynb
Normal file
@@ -0,0 +1,678 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "14f8b67b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## AutoGPT example finding Winning Marathon Times\n",
|
||||
"\n",
|
||||
"* Implementation of https://github.com/Significant-Gravitas/Auto-GPT \n",
|
||||
"* With LangChain primitives (LLMs, PromptTemplates, VectorStores, Embeddings, Tools)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "ef972313-c05a-4c49-8fd1-03e599e21033",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# !pip install bs4\n",
|
||||
"# !pip install nest_asyncio"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "1cff42fd",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# General \n",
|
||||
"import pandas as pd\n",
|
||||
"from langchain.experimental.autonomous_agents.autogpt.agent import AutoGPT\n",
|
||||
"from langchain.chat_models import ChatOpenAI\n",
|
||||
"\n",
|
||||
"from langchain.agents.agent_toolkits.pandas.base import create_pandas_dataframe_agent\n",
|
||||
"from langchain.docstore.document import Document\n",
|
||||
"from langchain.chains import RetrievalQA\n",
|
||||
"import asyncio\n",
|
||||
"import nest_asyncio\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Needed synce jupyter runs an async eventloop\n",
|
||||
"nest_asyncio.apply()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "01283ac7-1da0-41ba-8011-bd455d21dd82",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"llm = ChatOpenAI(model_name=\"gpt-3.5-turbo\", temperature=1.0)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "192496a7",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Set up tools\n",
|
||||
"\n",
|
||||
"* We'll set up an AutoGPT with a `search` tool, and `write-file` tool, and a `read-file` tool, and a web browsing tool"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "708a426f",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Define any other `tools` you want to use here"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "cef4c150-0ef1-4a33-836b-01062fec134e",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Tools\n",
|
||||
"from typing import Optional\n",
|
||||
"from langchain.agents import tool\n",
|
||||
"from langchain.tools.file_management.read import ReadFileTool\n",
|
||||
"from langchain.tools.file_management.write import WriteFileTool\n",
|
||||
"\n",
|
||||
"@tool\n",
|
||||
"def process_csv(csv_file_path: str, instructions: str, output_path: Optional[str] = None) -> str:\n",
|
||||
" \"\"\"Process a CSV by with pandas in a limited REPL. Only use this after writing data to disk as a csv file. Any figures must be saved to disk to be viewed by the human. Instructions should be written in natural language, not code. Assume the dataframe is already loaded.\"\"\"\n",
|
||||
" try:\n",
|
||||
" df = pd.read_csv(csv_file_path)\n",
|
||||
" except Exception as e:\n",
|
||||
" return f\"Error: {e}\"\n",
|
||||
" agent = create_pandas_dataframe_agent(llm, df, max_iterations=30, verbose=True)\n",
|
||||
" if output_path is not None:\n",
|
||||
" instructions += f\" Save output to disk at {output_path}\"\n",
|
||||
" try:\n",
|
||||
" return agent.run(instructions)\n",
|
||||
" except Exception as e:\n",
|
||||
" return f\"Error: {e}\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "51c07298-00e0-42d6-8aff-bd2e6bbd35a3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Web Search Tool**\n",
|
||||
"\n",
|
||||
"No need for API Tokens to use this tool, but it will require an optional dependency"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "4afdedb2-f295-4ab8-9397-3640f5eeeed3",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# !pip install duckduckgo_search"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "45f143de-e49e-4e27-88eb-ee44a4fdf933",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import json\n",
|
||||
"from duckduckgo_search import ddg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "e2e799f4-86fb-4190-a298-4ae5c7b7a540",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"@tool\n",
|
||||
"def web_search(query: str, num_results: int = 8) -> str:\n",
|
||||
" \"\"\"Useful for general internet search queries.\"\"\"\n",
|
||||
" search_results = []\n",
|
||||
" if not query:\n",
|
||||
" return json.dumps(search_results)\n",
|
||||
"\n",
|
||||
" results = ddg(query, max_results=num_results)\n",
|
||||
" if not results:\n",
|
||||
" return json.dumps(search_results)\n",
|
||||
"\n",
|
||||
" for j in results:\n",
|
||||
" search_results.append(j)\n",
|
||||
"\n",
|
||||
" return json.dumps(search_results, ensure_ascii=False, indent=4)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "69975008-654a-4cbb-bdf6-63c8bae07eaa",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"**Browse a web page with PlayWright**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"id": "6bb5e47b-0f54-4faa-ae42-49a28fa5497b",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# !pip install playwright\n",
|
||||
"# !playwright install"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "26b497d7-8e52-4c7f-8e7e-da0a48820a3c",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"async def async_load_playwright(url: str) -> str:\n",
|
||||
" \"\"\"Load the specified URLs using Playwright and parse using BeautifulSoup.\"\"\"\n",
|
||||
" from bs4 import BeautifulSoup\n",
|
||||
" from playwright.async_api import async_playwright\n",
|
||||
"\n",
|
||||
" results = \"\"\n",
|
||||
" async with async_playwright() as p:\n",
|
||||
" browser = await p.chromium.launch(headless=True)\n",
|
||||
" try:\n",
|
||||
" page = await browser.new_page()\n",
|
||||
" await page.goto(url)\n",
|
||||
"\n",
|
||||
" page_source = await page.content()\n",
|
||||
" soup = BeautifulSoup(page_source, \"html.parser\")\n",
|
||||
"\n",
|
||||
" for script in soup([\"script\", \"style\"]):\n",
|
||||
" script.extract()\n",
|
||||
"\n",
|
||||
" text = soup.get_text()\n",
|
||||
" lines = (line.strip() for line in text.splitlines())\n",
|
||||
" chunks = (phrase.strip() for line in lines for phrase in line.split(\" \"))\n",
|
||||
" results = \"\\n\".join(chunk for chunk in chunks if chunk)\n",
|
||||
" except Exception as e:\n",
|
||||
" results = f\"Error: {e}\"\n",
|
||||
" await browser.close()\n",
|
||||
" return results\n",
|
||||
"\n",
|
||||
"def run_async(coro):\n",
|
||||
" event_loop = asyncio.get_event_loop()\n",
|
||||
" return event_loop.run_until_complete(coro)\n",
|
||||
"\n",
|
||||
"@tool\n",
|
||||
"def browse_web_page(url: str) -> str:\n",
|
||||
" \"\"\"Verbose way to scrape a whole webpage. Likely to cause issues parsing.\"\"\"\n",
|
||||
" return run_async(async_load_playwright(url))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5ea71762-67ca-4e75-8c4d-00563064be71",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**Q&A Over a webpage**\n",
|
||||
"\n",
|
||||
"Help the model ask more directed questions of web pages to avoid cluttering its memory"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "1842929d-f18d-4edc-9fdd-82c929181141",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain.tools.base import BaseTool\n",
|
||||
"from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
|
||||
"\n",
|
||||
"from langchain.document_loaders import WebBaseLoader\n",
|
||||
"from pydantic import Field\n",
|
||||
"from langchain.chains.qa_with_sources.loading import load_qa_with_sources_chain, BaseCombineDocumentsChain\n",
|
||||
"\n",
|
||||
"def _get_text_splitter():\n",
|
||||
" return RecursiveCharacterTextSplitter(\n",
|
||||
" # Set a really small chunk size, just to show.\n",
|
||||
" chunk_size = 500,\n",
|
||||
" chunk_overlap = 20,\n",
|
||||
" length_function = len,\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class WebpageQATool(BaseTool):\n",
|
||||
" name = \"query_webpage\"\n",
|
||||
" description = \"Browse a webpage and retrieve the information relevant to the question.\"\n",
|
||||
" text_splitter: RecursiveCharacterTextSplitter = Field(default_factory=_get_text_splitter)\n",
|
||||
" qa_chain: BaseCombineDocumentsChain\n",
|
||||
" \n",
|
||||
" def _run(self, url: str, question: str) -> str:\n",
|
||||
" \"\"\"Useful for browsing websites and scraping the text information.\"\"\"\n",
|
||||
" result = browse_web_page.run(url)\n",
|
||||
" docs = [Document(page_content=result, metadata={\"source\": url})]\n",
|
||||
" web_docs = self.text_splitter.split_documents(docs)\n",
|
||||
" results = []\n",
|
||||
" # TODO: Handle this with a MapReduceChain\n",
|
||||
" for i in range(0, len(web_docs), 4):\n",
|
||||
" input_docs = web_docs[i:i+4]\n",
|
||||
" window_result = self.qa_chain({\"input_documents\": input_docs, \"question\": question}, return_only_outputs=True)\n",
|
||||
" results.append(f\"Response from window {i} - {window_result}\")\n",
|
||||
" results_docs = [Document(page_content=\"\\n\".join(results), metadata={\"source\": url})]\n",
|
||||
" return self.qa_chain({\"input_documents\": results_docs, \"question\": question}, return_only_outputs=True)\n",
|
||||
" \n",
|
||||
" async def _arun(self, url: str, question: str) -> str:\n",
|
||||
" raise NotImplementedError\n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "e6f72bd0",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"query_website_tool = WebpageQATool(qa_chain=load_qa_with_sources_chain(llm))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8e39ee28",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Set up memory\n",
|
||||
"\n",
|
||||
"* The memory here is used for the agents intermediate steps"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"id": "1df7b724",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Memory\n",
|
||||
"import faiss\n",
|
||||
"from langchain.vectorstores import FAISS\n",
|
||||
"from langchain.docstore import InMemoryDocstore\n",
|
||||
"from langchain.embeddings import OpenAIEmbeddings\n",
|
||||
"from langchain.tools.human.tool import HumanInputRun\n",
|
||||
"\n",
|
||||
"embeddings_model = OpenAIEmbeddings()\n",
|
||||
"embedding_size = 1536\n",
|
||||
"index = faiss.IndexFlatL2(embedding_size)\n",
|
||||
"vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e40fd657",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Setup model and AutoGPT\n",
|
||||
"\n",
|
||||
"`Model set-up`"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"id": "88c8b184-67d7-4c35-84ae-9b14bef8c4e3",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"tools = [\n",
|
||||
" web_search,\n",
|
||||
" WriteFileTool(),\n",
|
||||
" ReadFileTool(),\n",
|
||||
" process_csv,\n",
|
||||
" query_website_tool,\n",
|
||||
" # HumanInputRun(), # Activate if you want the permit asking for help from the human\n",
|
||||
"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"id": "709c08c2",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"agent = AutoGPT.from_llm_and_tools(\n",
|
||||
" ai_name=\"Tom\",\n",
|
||||
" ai_role=\"Assistant\",\n",
|
||||
" tools=tools,\n",
|
||||
" llm=llm,\n",
|
||||
" memory=vectorstore.as_retriever(search_kwargs={\"k\": 8}),\n",
|
||||
" # human_in_the_loop=True, # Set to True if you want to add feedback at each step.\n",
|
||||
")\n",
|
||||
"# agent.chain.verbose = True"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "fc9b51ba",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### AutoGPT as a research / data munger \n",
|
||||
"\n",
|
||||
"#### `inflation` and `college tuition`\n",
|
||||
" \n",
|
||||
"Let's use AutoGPT as researcher and data munger / cleaner.\n",
|
||||
" \n",
|
||||
"I spent a lot of time over the years crawling data sources and cleaning data. \n",
|
||||
"\n",
|
||||
"Let's see if AutoGPT can do all of this for us!\n",
|
||||
"\n",
|
||||
"Here is the prompt comparing `inflation` and `college tuition`."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"id": "64455d70-a134-4d11-826a-33e34c2ce287",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"WARNING:root:Failed to persist run: Object of type 'FAISS' is not JSON serializable\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"I will start by using the web_search command to find the Boston Marathon winning times for the past 5 years. Since it is a simple query, I expect to find relevant information in the first few search results.\",\n",
|
||||
" \"reasoning\": \"I have decided on this course of action to efficiently retrieve the information I need while keeping it simple to avoid legal complications.\",\n",
|
||||
" \"plan\": \"- Use web_search command to search for 'Boston Marathon winning times past 5 years'\\n- Look through top results for the information requested\\n- If necessary, repeat search with slightly different query to get better results\",\n",
|
||||
" \"criticism\": \"I should make sure to phrase my search query concisely to prevent too many irrelevant search results.\",\n",
|
||||
" \"speak\": \"I will use the web_search command to find the Boston Marathon winning times for the past 5 years.\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"web_search\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"query\": \"Boston Marathon winning times past 5 years\",\n",
|
||||
" \"num_results\": 8\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\u001b[32mLast Observation: [\n",
|
||||
" {\n",
|
||||
" \"title\": \"List of winners of the Boston Marathon - Wikipedia\",\n",
|
||||
" \"href\": \"https://en.wikipedia.org/wiki/List_of_winners_of_the_Boston_Marathon\",\n",
|
||||
" \"body\": \"Louise Sauvage won the women's wheelchair division in three consecutive Boston Marathons, between 1997 and 1999. Edith Hunkeler won the race twice, in 2002 and 2006. Wakako Tsuchida won the race in five consecutive years from 2007 to 2011. Tatyana McFadden won the race five times between 2013 and 2018.\"\n",
|
||||
" },\n",
|
||||
" \u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"WARNING:root:Failed to persist run: Object of type 'FAISS' is not JSON serializable\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"The search results indicate that the winning times for the past 5 years can be found on the Wikipedia page for the Boston Marathon winners. I will retrieve this information using the query_webpage command and the URL of the relevant Wikipedia page. \",\n",
|
||||
" \"reasoning\": \"This method will allow me to avoid any legal complications while retrieving the exact information that I need.\",\n",
|
||||
" \"plan\": \"- Use query_webpage command to browse through the Wikipedia page for the Boston Marathon winners \\\\n- Locate the relevant information on the page \\\\n- Return the information to the user\",\n",
|
||||
" \"criticism\": \"I should be sure to locate and use only reliable sources to avoid providing the user with inaccurate information.\",\n",
|
||||
" \"speak\": \"I will use the query_webpage command to browse through the Wikipedia page for the Boston Marathon winners and retrieve the relevant information.\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"query_webpage\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"url\": \"https://en.wikipedia.org/wiki/List_of_winners_of_the_Boston_Marathon\", \n",
|
||||
" \"question\": \"What are the winning times of the Boston Marathon for the past 5 years? \"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\u001b[32mLast Observation: {'output_text': \"The winning times of the Boston Marathon for the past 5 years are: \\n- 2017: Men's - 2:09:37, Women's - 2:21:52\\n- 2018: Men's - 2:15:58, Women's - 2:39:54\\n- 2019: Men's - 2:07:57, Women's - 2:23:31\\n- 2020: The Boston Marathon was canceled due to the COVID-19 pandemic.\\n- 2021: Men's - 2:09:28, Women's - 2:18:10\\nSOURCES: https://en.wikipedia.org/wiki/List_of_winners_of_the_Boston_Marathon\"}\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"WARNING:root:Failed to persist run: Object of type 'FAISS' is not JSON serializable\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"I could write this information to a file using the write_file command so that I can refer back to it later. But first, I should process the information to extract the relevant data and convert it into a useful format using the process_csv command.\",\n",
|
||||
" \"reasoning\": \"Storing the information in a CSV file will allow me to use pandas to manipulate the data in the future with ease, while converting the data into a useful format will make it easier for other people to use the data.\",\n",
|
||||
" \"plan\": \"- Use process_csv command to extract and format the relevant data from the Wikipedia page\\\\n- Write the data to a CSV file using the write_file command\\\\n- Inform the user that the data has been saved to file\",\n",
|
||||
" \"criticism\": \"I should thoroughly check the CSV file for accuracy before saving the data.\",\n",
|
||||
" \"speak\": \"I will use the process_csv command to extract and format the relevant data from the Wikipedia page, and save it to a CSV file using the write_file command.\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"process_csv\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"csv_file_path\": \"boston_marathon_winners.csv\",\n",
|
||||
" \"instructions\": \"1. Extract data from Wikipedia page\\\\n2. Convert winning times into datetime format\\\\n3. Save data as CSV file with columns: year, men\\'s time, women\\'s time\",\n",
|
||||
" \"output_path\": None\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\u001b[32mLast Observation: {'output_text': \"The winning times of the Boston Marathon for the past 5 years are: \\n- 2017: Men's - 2:09:37, Women's - 2:21:52\\n- 2018: Men's - 2:15:58, Women's - 2:39:54\\n- 2019: Men's - 2:07:57, Women's - 2:23:31\\n- 2020: The Boston Marathon was canceled due to the COVID-19 pandemic.\\n- 2021: Men's - 2:09:28, Women's - 2:18:10\\nSOURCES: https://en.wikipedia.org/wiki/List_of_winners_of_the_Boston_Marathon\"}\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"WARNING:root:Failed to persist run: Object of type 'FAISS' is not JSON serializable\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"I will now use the write_file command to save the winning times for the past 5 years as a text file for later reference.\",\n",
|
||||
" \"reasoning\": \"This will allow me to easily access the winning times in the future without needing to search for the information again.\",\n",
|
||||
" \"plan\": \"- Use the write_file command to save the winning times for the past 5 years to a text file.\\\\n- Name the file appropriately, so it is easy to identify in the future.\",\n",
|
||||
" \"criticism\": \"I should review the contents of the file after writing it to make sure that the information has been saved correctly and can be read later without errors.\",\n",
|
||||
" \"speak\": \"I will use the write_file command to save the winning times for the past 5 years as a text file for easy retrieval in the future.\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"write_file\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"file_path\": \"BostonMarathonWinningTimes.txt\",\n",
|
||||
" \"text\": \"The winning times of the Boston Marathon for the past 5 years are: \\n- 2017: Men's - 2:09:37, Women's - 2:21:52\\n- 2018: Men's - 2:15:58, Women's - 2:39:54\\n- 2019: Men's - 2:07:57, Women's - 2:23:31\\n- 2020: The Boston Marathon was canceled due to the COVID-19 pandemic.\\n- 2021: Men's - 2:09:28, Women's - 2:18:10\\nSOURCES: https://en.wikipedia.org/wiki/List_of_winners_of_the_Boston_Marathon\"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\u001b[32mLast Observation: File written to successfully.\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"WARNING:root:Failed to persist run: Object of type 'FAISS' is not JSON serializable\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"I will use the command \"query_webpage\" to browse through the Wikipedia page for the Boston Marathon winners and retrieve the winning times for the past 5 years. This is the method that will allow me to retrieve the exact information I need while avoiding any legal issues. \n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"The search results indicate that the winning times for the past 5 years can be found on the Wikipedia page for the Boston Marathon winners. I will retrieve this information using the query_webpage command and the URL of the relevant Wikipedia page. \",\n",
|
||||
" \"reasoning\": \"This method will allow me to avoid any legal complications while retrieving the exact information that I need.\",\n",
|
||||
" \"plan\": \"- Use query_webpage command to browse through the Wikipedia page for the Boston Marathon winners \\\\n- Locate the relevant information on the page \\\\n- Return the information to the user\",\n",
|
||||
" \"criticism\": \"I should be sure to locate and use only reliable sources to avoid providing the user with inaccurate information.\",\n",
|
||||
" \"speak\": \"I will use the query_webpage command to browse through the Wikipedia page for the Boston Marathon winners and retrieve the winning times for the past 5 years. \"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"query_webpage\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"url\": \"https://en.wikipedia.org/wiki/List_of_winners_of_the_Boston_Marathon\", \n",
|
||||
" \"question\": \"What are the winning times of the Boston Marathon for the past 5 years? \"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"```\n",
|
||||
"\u001b[32mLast Observation: File written to successfully.\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"WARNING:root:Failed to persist run: Object of type 'FAISS' is not JSON serializable\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"Now that I have the winning times for the past 5 years, I will save them to a file to ensure that I don't forget them. I will use the write_file command to save this data to disk.\",\n",
|
||||
" \"reasoning\": \"By saving the data to disk, I can easily retrieve it in the future and avoid having to perform the same search again.\",\n",
|
||||
" \"plan\": \"- Use the write_file command to save the data to a text file.\",\n",
|
||||
" \"criticism\": \"I should ensure that the file path and file name are clear and descriptive to make it easy to locate the relevant information in the future.\",\n",
|
||||
" \"speak\": \"I will save the winning times for the past 5 years to a text file using the write_file command.\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"write_file\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"file_path\": \"winning_times.txt\",\n",
|
||||
" \"text\": \"The winning times of the Boston Marathon for the past 5 years are:\\n- 2017: Men's - 2:09:37, Women's - 2:21:52\\n- 2018: Men's - 2:15:58, Women's - 2:39:54\\n- 2019: Men's - 2:07:57, Women's - 2:23:31\\n- 2020: The Boston Marathon was canceled due to the COVID-19 pandemic.\\n- 2021: Men's - 2:09:28, Women's - 2:18:10\\nSOURCES: https://en.wikipedia.org/wiki/List_of_winners_of_the_Boston_Marathon\"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\u001b[32mLast Observation: File written to successfully.\u001b[0m\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"WARNING:root:Failed to persist run: Object of type 'FAISS' is not JSON serializable\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"{\n",
|
||||
" \"thoughts\": {\n",
|
||||
" \"text\": \"I will now shut down my system, as I have completed all of my objectives.\",\n",
|
||||
" \"reasoning\": \"Since I have completed all of my objectives, there is no need to keep running my system.\",\n",
|
||||
" \"plan\": \"- Use the finish command to signal that I have completed all of my objectives.\\\\\\\\n- Shut down the system.\",\n",
|
||||
" \"criticism\": \"I should always double-check to ensure that all of my objectives have been completed before shutting down my system.\",\n",
|
||||
" \"speak\": \"I have completed all of my objectives, and I will now shut down my system.\"\n",
|
||||
" },\n",
|
||||
" \"command\": {\n",
|
||||
" \"name\": \"finish\",\n",
|
||||
" \"args\": {\n",
|
||||
" \"response\": \"All objectives have been completed.\"\n",
|
||||
" }\n",
|
||||
" }\n",
|
||||
"}\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'All objectives have been completed.'"
|
||||
]
|
||||
},
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"agent.run([\"What were the winning boston marathon times for the past 5 years\"])"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -19,8 +19,4 @@ Highlighting specific parts:
|
||||
|
||||
Specific examples of this include:
|
||||
|
||||
- [Baby AGI](agents/baby_agi.ipynb): a notebook implementing [BabyAGI](https://github.com/yoheinakajima/babyagi) by Yohei Nakajima as LLM Chains
|
||||
- [Baby AGI with Tools](agents/baby_agi_with_agent.ipynb): building off the above notebook, this example substitutes in an agent with tools as the execution tools, allowing it to actually take actions.
|
||||
- [CAMEL](agents/camel_role_playing.ipynb): an implementation of the CAMEL (Communicative Agents for “Mind” Exploration of Large Scale Language Model Society) paper, where two agents communicate with eachother.
|
||||
- [AI Plugins](agents/custom_agent_with_plugin_retrieval.ipynb): an implementation of an agent that is designed to be able to use all AI Plugins.
|
||||
- [Generative Agents](agents/characters.ipynb): This notebook implements a generative agent based on the paper [Generative Agents: Interactive Simulacra of Human Behavior](https://arxiv.org/abs/2304.03442) by Park, et. al.
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Semantic Search over a group chat messages\n",
|
||||
"In this tutorial, we are going to use Langchain + Deep Lake with GPT4 to semantically search a group chat.\n",
|
||||
"# Question answering over a group chat messages\n",
|
||||
"In this tutorial, we are going to use Langchain + Deep Lake with GPT4 to semantically search and ask questions over a group chat.\n",
|
||||
"\n",
|
||||
"View a working demo here: https://twitter.com/thisissukh_/status/1647223328363679745"
|
||||
"View a working demo [here](https://twitter.com/thisissukh_/status/1647223328363679745)"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -83,7 +83,7 @@
|
||||
"Generate a group chat conversation with three friends talking about their day, referencing real places and fictional names. Make it funny and as detailed as possible.\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"I've already generated such a chat in `../../messages.txt`. We can keep it simple and use this for our example.\n",
|
||||
"I've already generated such a chat in `messages.txt`. We can keep it simple and use this for our example.\n",
|
||||
"\n",
|
||||
"## 3. Ingest chat embeddings\n",
|
||||
"\n",
|
||||
@@ -144,8 +144,10 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
|
||||
@@ -55,7 +55,11 @@ from langchain.utilities.wikipedia import WikipediaAPIWrapper
|
||||
from langchain.utilities.wolfram_alpha import WolframAlphaAPIWrapper
|
||||
from langchain.vectorstores import FAISS, ElasticVectorSearch
|
||||
|
||||
__version__ = metadata.version(__package__)
|
||||
try:
|
||||
__version__ = metadata.version(__package__)
|
||||
except metadata.PackageNotFoundError:
|
||||
# Case where package metadata is not available.
|
||||
__version__ = ""
|
||||
del metadata # optional, avoids polluting the results of dir(__package__)
|
||||
|
||||
verbose: bool = False
|
||||
|
||||
@@ -2,12 +2,16 @@ import json
|
||||
from typing import Union
|
||||
|
||||
from langchain.agents.agent import AgentOutputParser
|
||||
from langchain.schema import AgentAction, AgentFinish
|
||||
from langchain.agents.chat.prompt import FORMAT_INSTRUCTIONS
|
||||
from langchain.schema import AgentAction, AgentFinish, OutputParserException
|
||||
|
||||
FINAL_ANSWER_ACTION = "Final Answer:"
|
||||
|
||||
|
||||
class ChatOutputParser(AgentOutputParser):
|
||||
def get_format_instructions(self) -> str:
|
||||
return FORMAT_INSTRUCTIONS
|
||||
|
||||
def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
|
||||
if FINAL_ANSWER_ACTION in text:
|
||||
return AgentFinish(
|
||||
@@ -19,4 +23,4 @@ class ChatOutputParser(AgentOutputParser):
|
||||
return AgentAction(response["action"], response["action_input"], text)
|
||||
|
||||
except Exception:
|
||||
raise ValueError(f"Could not parse LLM output: {text}")
|
||||
raise OutputParserException(f"Could not parse LLM output: {text}")
|
||||
|
||||
@@ -2,12 +2,16 @@ import re
|
||||
from typing import Union
|
||||
|
||||
from langchain.agents.agent import AgentOutputParser
|
||||
from langchain.schema import AgentAction, AgentFinish
|
||||
from langchain.agents.conversational.prompt import FORMAT_INSTRUCTIONS
|
||||
from langchain.schema import AgentAction, AgentFinish, OutputParserException
|
||||
|
||||
|
||||
class ConvoOutputParser(AgentOutputParser):
|
||||
ai_prefix: str = "AI"
|
||||
|
||||
def get_format_instructions(self) -> str:
|
||||
return FORMAT_INSTRUCTIONS
|
||||
|
||||
def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
|
||||
if f"{self.ai_prefix}:" in text:
|
||||
return AgentFinish(
|
||||
@@ -16,7 +20,7 @@ class ConvoOutputParser(AgentOutputParser):
|
||||
regex = r"Action: (.*?)[\n]*Action Input: (.*)"
|
||||
match = re.search(regex, text)
|
||||
if not match:
|
||||
raise ValueError(f"Could not parse LLM output: `{text}`")
|
||||
raise OutputParserException(f"Could not parse LLM output: `{text}`")
|
||||
action = match.group(1)
|
||||
action_input = match.group(2)
|
||||
return AgentAction(action.strip(), action_input.strip(" ").strip('"'), text)
|
||||
|
||||
@@ -10,7 +10,7 @@ Overall, Assistant is a powerful system that can help with a wide range of tasks
|
||||
FORMAT_INSTRUCTIONS = """RESPONSE FORMAT INSTRUCTIONS
|
||||
----------------------------
|
||||
|
||||
When responding to me please, please output a response in one of two formats:
|
||||
When responding to me, please output a response in one of two formats:
|
||||
|
||||
**Option 1:**
|
||||
Use this if you want the human to use a tool.
|
||||
|
||||
@@ -2,12 +2,16 @@ import re
|
||||
from typing import Union
|
||||
|
||||
from langchain.agents.agent import AgentOutputParser
|
||||
from langchain.schema import AgentAction, AgentFinish
|
||||
from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS
|
||||
from langchain.schema import AgentAction, AgentFinish, OutputParserException
|
||||
|
||||
FINAL_ANSWER_ACTION = "Final Answer:"
|
||||
|
||||
|
||||
class MRKLOutputParser(AgentOutputParser):
|
||||
def get_format_instructions(self) -> str:
|
||||
return FORMAT_INSTRUCTIONS
|
||||
|
||||
def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
|
||||
if FINAL_ANSWER_ACTION in text:
|
||||
return AgentFinish(
|
||||
@@ -17,7 +21,7 @@ class MRKLOutputParser(AgentOutputParser):
|
||||
regex = r"Action\s*\d*\s*:(.*?)\nAction\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)"
|
||||
match = re.search(regex, text, re.DOTALL)
|
||||
if not match:
|
||||
raise ValueError(f"Could not parse LLM output: `{text}`")
|
||||
raise OutputParserException(f"Could not parse LLM output: `{text}`")
|
||||
action = match.group(1).strip()
|
||||
action_input = match.group(2)
|
||||
return AgentAction(action, action_input.strip(" ").strip('"'), text)
|
||||
|
||||
@@ -2,21 +2,23 @@ import re
|
||||
from typing import Union
|
||||
|
||||
from langchain.agents.agent import AgentOutputParser
|
||||
from langchain.schema import AgentAction, AgentFinish
|
||||
from langchain.schema import AgentAction, AgentFinish, OutputParserException
|
||||
|
||||
|
||||
class ReActOutputParser(AgentOutputParser):
|
||||
def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
|
||||
action_prefix = "Action: "
|
||||
if not text.strip().split("\n")[-1].startswith(action_prefix):
|
||||
raise ValueError(f"Could not parse LLM Output: {text}")
|
||||
raise OutputParserException(f"Could not parse LLM Output: {text}")
|
||||
action_block = text.strip().split("\n")[-1]
|
||||
|
||||
action_str = action_block[len(action_prefix) :]
|
||||
# Parse out the action and the directive.
|
||||
re_matches = re.search(r"(.*?)\[(.*?)\]", action_str)
|
||||
if re_matches is None:
|
||||
raise ValueError(f"Could not parse action directive: {action_str}")
|
||||
raise OutputParserException(
|
||||
f"Could not parse action directive: {action_str}"
|
||||
)
|
||||
action, action_input = re_matches.group(1), re_matches.group(2)
|
||||
if action == "Finish":
|
||||
return AgentFinish({"output": action_input}, text)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from typing import Union
|
||||
|
||||
from langchain.agents.agent import AgentOutputParser
|
||||
from langchain.schema import AgentAction, AgentFinish
|
||||
from langchain.schema import AgentAction, AgentFinish, OutputParserException
|
||||
|
||||
|
||||
class SelfAskOutputParser(AgentOutputParser):
|
||||
@@ -12,7 +12,7 @@ class SelfAskOutputParser(AgentOutputParser):
|
||||
if followup not in last_line:
|
||||
finish_string = "So the final answer is: "
|
||||
if finish_string not in last_line:
|
||||
raise ValueError(f"Could not parse output: {text}")
|
||||
raise OutputParserException(f"Could not parse output: {text}")
|
||||
return AgentFinish({"output": last_line[len(finish_string) :]}, text)
|
||||
|
||||
after_colon = text.split(":")[-1]
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
from inspect import signature
|
||||
from typing import Any, Awaitable, Callable, Optional, Type, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, validate_arguments
|
||||
|
||||
from langchain.tools.base import BaseTool, create_args_schema_model_from_signature
|
||||
from langchain.tools.base import BaseTool
|
||||
|
||||
|
||||
class Tool(BaseTool):
|
||||
@@ -16,15 +16,6 @@ class Tool(BaseTool):
|
||||
coroutine: Optional[Callable[..., Awaitable[str]]] = None
|
||||
"""The asynchronous version of the function."""
|
||||
|
||||
@property
|
||||
def args(self) -> Type[BaseModel]:
|
||||
"""Generate an input pydantic model."""
|
||||
if self.args_schema is not None:
|
||||
return self.args_schema
|
||||
# Infer the schema directly from the function to add more structured
|
||||
# arguments.
|
||||
return create_args_schema_model_from_signature(self.func)
|
||||
|
||||
def _run(self, *args: Any, **kwargs: Any) -> str:
|
||||
"""Use the tool."""
|
||||
return self.func(*args, **kwargs)
|
||||
@@ -60,9 +51,23 @@ class InvalidTool(BaseTool):
|
||||
return f"{tool_name} is not a valid tool, try another one."
|
||||
|
||||
|
||||
def tool(*args: Union[str, Callable], return_direct: bool = False) -> Callable:
|
||||
def tool(
|
||||
*args: Union[str, Callable],
|
||||
return_direct: bool = False,
|
||||
args_schema: Optional[Type[BaseModel]] = None,
|
||||
infer_schema: bool = True,
|
||||
) -> Callable:
|
||||
"""Make tools out of functions, can be used with or without arguments.
|
||||
|
||||
Args:
|
||||
*args: The arguments to the tool.
|
||||
return_direct: Whether to return directly from the tool rather
|
||||
than continuing the agent loop.
|
||||
args_schema: optional argument schema for user to specify
|
||||
infer_schema: Whether to infer the schema of the arguments from
|
||||
the function's signature. This also makes the resultant tool
|
||||
accept a dictionary input to its `run()` function.
|
||||
|
||||
Requires:
|
||||
- Function must be of type (str) -> str
|
||||
- Function must have a docstring
|
||||
@@ -87,11 +92,13 @@ def tool(*args: Union[str, Callable], return_direct: bool = False) -> Callable:
|
||||
# Description example:
|
||||
# search_api(query: str) - Searches the API for the query.
|
||||
description = f"{tool_name}{signature(func)} - {func.__doc__.strip()}"
|
||||
args_schema = create_args_schema_model_from_signature(func)
|
||||
_args_schema = args_schema
|
||||
if _args_schema is None and infer_schema:
|
||||
_args_schema = validate_arguments(func).model # type: ignore
|
||||
tool_ = Tool(
|
||||
name=tool_name,
|
||||
func=func,
|
||||
args_schema=args_schema,
|
||||
args_schema=_args_schema,
|
||||
description=description,
|
||||
return_direct=return_direct,
|
||||
)
|
||||
|
||||
@@ -96,7 +96,7 @@ class CometCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
|
||||
self,
|
||||
task_type: Optional[str] = "inference",
|
||||
workspace: Optional[str] = None,
|
||||
project_name: Optional[str] = "comet-langchain-demo",
|
||||
project_name: Optional[str] = None,
|
||||
tags: Optional[Sequence] = None,
|
||||
name: Optional[str] = None,
|
||||
visualizations: Optional[List[str]] = None,
|
||||
@@ -106,7 +106,7 @@ class CometCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
|
||||
) -> None:
|
||||
"""Initialize callback handler."""
|
||||
|
||||
comet_ml = import_comet_ml()
|
||||
self.comet_ml = import_comet_ml()
|
||||
super().__init__()
|
||||
|
||||
self.task_type = task_type
|
||||
@@ -133,7 +133,7 @@ class CometCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
|
||||
"https://github.com/comet-ml/issue_tracking/issues with the tag "
|
||||
"`langchain`."
|
||||
)
|
||||
comet_ml.LOGGER.warning(warning)
|
||||
self.comet_ml.LOGGER.warning(warning)
|
||||
|
||||
self.callback_columns: list = []
|
||||
self.action_records: list = []
|
||||
@@ -242,8 +242,6 @@ class CometCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
|
||||
resp.update(flatten_dict(serialized))
|
||||
resp.update(self.get_custom_callback_meta())
|
||||
|
||||
comet_ml = import_comet_ml()
|
||||
|
||||
for chain_input_key, chain_input_val in inputs.items():
|
||||
if isinstance(chain_input_val, str):
|
||||
input_resp = deepcopy(resp)
|
||||
@@ -253,7 +251,7 @@ class CometCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
|
||||
self.action_records.append(input_resp)
|
||||
|
||||
else:
|
||||
comet_ml.LOGGER.warning(
|
||||
self.comet_ml.LOGGER.warning(
|
||||
f"Unexpected data format provided! "
|
||||
f"Input Value for {chain_input_key} will not be logged"
|
||||
)
|
||||
@@ -268,8 +266,6 @@ class CometCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
|
||||
resp.update({"action": "on_chain_end"})
|
||||
resp.update(self.get_custom_callback_meta())
|
||||
|
||||
comet_ml = import_comet_ml()
|
||||
|
||||
for chain_output_key, chain_output_val in outputs.items():
|
||||
if isinstance(chain_output_val, str):
|
||||
output_resp = deepcopy(resp)
|
||||
@@ -278,7 +274,7 @@ class CometCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
|
||||
output_resp.update({chain_output_key: chain_output_val})
|
||||
self.action_records.append(output_resp)
|
||||
else:
|
||||
comet_ml.LOGGER.warning(
|
||||
self.comet_ml.LOGGER.warning(
|
||||
f"Unexpected data format provided! "
|
||||
f"Output Value for {chain_output_key} will not be logged"
|
||||
)
|
||||
@@ -449,7 +445,14 @@ class CometCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
|
||||
self._log_session(langchain_asset)
|
||||
|
||||
if langchain_asset:
|
||||
self._log_model(langchain_asset)
|
||||
try:
|
||||
self._log_model(langchain_asset)
|
||||
except Exception:
|
||||
self.comet_ml.LOGGER.error(
|
||||
"Failed to export agent or LLM to Comet",
|
||||
exc_info=True,
|
||||
extra={"show_traceback": True},
|
||||
)
|
||||
|
||||
if finish:
|
||||
self.experiment.end()
|
||||
@@ -470,8 +473,6 @@ class CometCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
|
||||
self.experiment.log_text(prompt, metadata=metadata, step=step)
|
||||
|
||||
def _log_model(self, langchain_asset: Any) -> None:
|
||||
comet_ml = import_comet_ml()
|
||||
|
||||
model_parameters = self._get_llm_parameters(langchain_asset)
|
||||
self.experiment.log_parameters(model_parameters, prefix="model")
|
||||
|
||||
@@ -487,24 +488,45 @@ class CometCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
|
||||
langchain_asset.save_agent(langchain_asset_path)
|
||||
self.experiment.log_model(model_name, str(langchain_asset_path))
|
||||
else:
|
||||
comet_ml.LOGGER.warning(
|
||||
self.comet_ml.LOGGER.error(
|
||||
f"{e}"
|
||||
" Could not save Langchain Asset "
|
||||
f"for {langchain_asset.__class__.__name__}"
|
||||
)
|
||||
|
||||
def _log_session(self, langchain_asset: Optional[Any] = None) -> None:
|
||||
llm_session_df = self._create_session_analysis_dataframe(langchain_asset)
|
||||
# Log the cleaned dataframe as a table
|
||||
self.experiment.log_table("langchain-llm-session.csv", llm_session_df)
|
||||
try:
|
||||
llm_session_df = self._create_session_analysis_dataframe(langchain_asset)
|
||||
# Log the cleaned dataframe as a table
|
||||
self.experiment.log_table("langchain-llm-session.csv", llm_session_df)
|
||||
except Exception:
|
||||
self.comet_ml.LOGGER.warning(
|
||||
"Failed to log session data to Comet",
|
||||
exc_info=True,
|
||||
extra={"show_traceback": True},
|
||||
)
|
||||
|
||||
metadata = {"langchain_version": str(langchain.__version__)}
|
||||
# Log the langchain low-level records as a JSON file directly
|
||||
self.experiment.log_asset_data(
|
||||
self.action_records, "langchain-action_records.json", metadata=metadata
|
||||
)
|
||||
try:
|
||||
metadata = {"langchain_version": str(langchain.__version__)}
|
||||
# Log the langchain low-level records as a JSON file directly
|
||||
self.experiment.log_asset_data(
|
||||
self.action_records, "langchain-action_records.json", metadata=metadata
|
||||
)
|
||||
except Exception:
|
||||
self.comet_ml.LOGGER.warning(
|
||||
"Failed to log session data to Comet",
|
||||
exc_info=True,
|
||||
extra={"show_traceback": True},
|
||||
)
|
||||
|
||||
self._log_visualizations(llm_session_df)
|
||||
try:
|
||||
self._log_visualizations(llm_session_df)
|
||||
except Exception:
|
||||
self.comet_ml.LOGGER.warning(
|
||||
"Failed to log visualizations to Comet",
|
||||
exc_info=True,
|
||||
extra={"show_traceback": True},
|
||||
)
|
||||
|
||||
def _log_text_metrics(self, metrics: Sequence[dict], step: int) -> None:
|
||||
if not metrics:
|
||||
@@ -519,7 +541,6 @@ class CometCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
|
||||
return
|
||||
|
||||
spacy = import_spacy()
|
||||
comet_ml = import_comet_ml()
|
||||
|
||||
prompts = session_df["prompts"].tolist()
|
||||
outputs = session_df["text"].tolist()
|
||||
@@ -544,7 +565,9 @@ class CometCallbackHandler(BaseMetadataCallbackHandler, BaseCallbackHandler):
|
||||
step=idx,
|
||||
)
|
||||
except Exception as e:
|
||||
comet_ml.LOGGER.warning(e)
|
||||
self.comet_ml.LOGGER.warning(
|
||||
e, exc_info=True, extra={"show_traceback": True}
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ from langchain.document_loaders.csv_loader import CSVLoader
|
||||
from langchain.document_loaders.dataframe import DataFrameLoader
|
||||
from langchain.document_loaders.diffbot import DiffbotLoader
|
||||
from langchain.document_loaders.directory import DirectoryLoader
|
||||
from langchain.document_loaders.discord import DiscordChatLoader
|
||||
from langchain.document_loaders.duckdb_loader import DuckDBLoader
|
||||
from langchain.document_loaders.email import (
|
||||
OutlookMessageLoader,
|
||||
@@ -150,4 +151,5 @@ __all__ = [
|
||||
"GitLoader",
|
||||
"TwitterTweetLoader",
|
||||
"ImageCaptionLoader",
|
||||
"DiscordChatLoader",
|
||||
]
|
||||
|
||||
33
langchain/document_loaders/discord.py
Normal file
33
langchain/document_loaders/discord.py
Normal file
@@ -0,0 +1,33 @@
|
||||
"""Load from Discord chat dump"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, List
|
||||
|
||||
from langchain.docstore.document import Document
|
||||
from langchain.document_loaders.base import BaseLoader
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import pandas as pd
|
||||
|
||||
|
||||
class DiscordChatLoader(BaseLoader):
|
||||
"""Load Discord chat logs."""
|
||||
|
||||
def __init__(self, chat_log: pd.DataFrame, user_id_col: str = "user_id"):
|
||||
"""Initialize with a Pandas DataFrame containing chat logs."""
|
||||
if not isinstance(chat_log, pd.DataFrame):
|
||||
raise ValueError(
|
||||
f"Expected chat_log to be a pd.DataFrame, got {type(chat_log)}"
|
||||
)
|
||||
self.chat_log = chat_log
|
||||
self.user_id_col = user_id_col
|
||||
|
||||
def load(self) -> List[Document]:
|
||||
"""Load all chat messages."""
|
||||
result = []
|
||||
for _, row in self.chat_log.iterrows():
|
||||
user_id = row[self.user_id_col]
|
||||
metadata = row.to_dict()
|
||||
metadata.pop(self.user_id_col)
|
||||
result.append(Document(page_content=user_id, metadata=metadata))
|
||||
return result
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Wrapper around HuggingFace embedding models."""
|
||||
from typing import Any, List
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from pydantic import BaseModel, Extra
|
||||
|
||||
@@ -29,6 +29,9 @@ class HuggingFaceEmbeddings(BaseModel, Embeddings):
|
||||
client: Any #: :meta private:
|
||||
model_name: str = DEFAULT_MODEL_NAME
|
||||
"""Model name to use."""
|
||||
cache_folder: Optional[str] = None
|
||||
"""Path to store models.
|
||||
Can be also set by SENTENCE_TRANSFORMERS_HOME enviroment variable."""
|
||||
|
||||
def __init__(self, **kwargs: Any):
|
||||
"""Initialize the sentence_transformer."""
|
||||
@@ -36,7 +39,9 @@ class HuggingFaceEmbeddings(BaseModel, Embeddings):
|
||||
try:
|
||||
import sentence_transformers
|
||||
|
||||
self.client = sentence_transformers.SentenceTransformer(self.model_name)
|
||||
self.client = sentence_transformers.SentenceTransformer(
|
||||
self.model_name, self.cache_folder
|
||||
)
|
||||
except ImportError:
|
||||
raise ValueError(
|
||||
"Could not import sentence_transformers python package. "
|
||||
|
||||
3
langchain/experimental/__init__.py
Normal file
3
langchain/experimental/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from langchain.experimental.autonomous_agents.baby_agi.baby_agi import BabyAGI
|
||||
|
||||
__all__ = ["BabyAGI"]
|
||||
3
langchain/experimental/autonomous_agents/__init__.py
Normal file
3
langchain/experimental/autonomous_agents/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from langchain.experimental.autonomous_agents.baby_agi.baby_agi import BabyAGI
|
||||
|
||||
__all__ = ["BabyAGI"]
|
||||
138
langchain/experimental/autonomous_agents/autogpt/agent.py
Normal file
138
langchain/experimental/autonomous_agents/autogpt/agent.py
Normal file
@@ -0,0 +1,138 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Optional
|
||||
|
||||
from termcolor import colored
|
||||
|
||||
from langchain.experimental.autonomous_agents.autogpt.output_parser import (
|
||||
AutoGPTOutputParser,
|
||||
BaseAutoGPTOutputParser,
|
||||
)
|
||||
from langchain.experimental.autonomous_agents.autogpt.prompt import AutoGPTPrompt
|
||||
from langchain.experimental.autonomous_agents.autogpt.prompt_generator import (
|
||||
FINISH_NAME,
|
||||
)
|
||||
from pydantic import ValidationError
|
||||
from langchain.chains.llm import LLMChain
|
||||
from langchain.chat_models.base import BaseChatModel
|
||||
from langchain.schema import (
|
||||
AIMessage,
|
||||
BaseMessage,
|
||||
Document,
|
||||
HumanMessage,
|
||||
SystemMessage,
|
||||
)
|
||||
from langchain.tools.base import BaseTool
|
||||
from langchain.tools.human.tool import HumanInputRun
|
||||
from langchain.vectorstores.base import VectorStoreRetriever
|
||||
|
||||
|
||||
class AutoGPT:
|
||||
"""Agent class for interacting with Auto-GPT."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
ai_name: str,
|
||||
memory: VectorStoreRetriever,
|
||||
chain: LLMChain,
|
||||
output_parser: BaseAutoGPTOutputParser,
|
||||
tools: List[BaseTool],
|
||||
feedback_tool: Optional[HumanInputRun] = None,
|
||||
):
|
||||
self.ai_name = ai_name
|
||||
self.memory = memory
|
||||
self.full_message_history: List[BaseMessage] = []
|
||||
self.next_action_count = 0
|
||||
self.chain = chain
|
||||
self.output_parser = output_parser
|
||||
self.tools = tools
|
||||
self.feedback_tool = feedback_tool
|
||||
|
||||
@classmethod
|
||||
def from_llm_and_tools(
|
||||
cls,
|
||||
ai_name: str,
|
||||
ai_role: str,
|
||||
memory: VectorStoreRetriever,
|
||||
tools: List[BaseTool],
|
||||
llm: BaseChatModel,
|
||||
human_in_the_loop: bool = False,
|
||||
output_parser: Optional[BaseAutoGPTOutputParser] = None,
|
||||
) -> AutoGPT:
|
||||
prompt = AutoGPTPrompt(
|
||||
ai_name=ai_name,
|
||||
ai_role=ai_role,
|
||||
tools=tools,
|
||||
input_variables=["memory", "messages", "goals", "user_input"],
|
||||
token_counter=llm.get_num_tokens,
|
||||
)
|
||||
human_feedback_tool = HumanInputRun() if human_in_the_loop else None
|
||||
chain = LLMChain(llm=llm, prompt=prompt)
|
||||
return cls(
|
||||
ai_name,
|
||||
memory,
|
||||
chain,
|
||||
output_parser or AutoGPTOutputParser(),
|
||||
tools,
|
||||
feedback_tool=human_feedback_tool,
|
||||
)
|
||||
|
||||
def run(self, goals: List[str]) -> str:
|
||||
user_input = (
|
||||
"Determine which next command to use, "
|
||||
"and respond using the format specified above:"
|
||||
)
|
||||
# Interaction Loop
|
||||
loop_count = 0
|
||||
while True:
|
||||
# Discontinue if continuous limit is reached
|
||||
loop_count += 1
|
||||
|
||||
# Send message to AI, get response
|
||||
assistant_reply = self.chain.run(
|
||||
goals=goals,
|
||||
messages=self.full_message_history,
|
||||
memory=self.memory,
|
||||
user_input=user_input,
|
||||
)
|
||||
|
||||
# Print Assistant thoughts
|
||||
print(assistant_reply)
|
||||
self.full_message_history.append(HumanMessage(content=user_input))
|
||||
self.full_message_history.append(AIMessage(content=assistant_reply))
|
||||
|
||||
# Get command name and arguments
|
||||
action = self.output_parser.parse(assistant_reply)
|
||||
tools = {t.name: t for t in self.tools}
|
||||
if action.name == FINISH_NAME:
|
||||
return action.args["response"]
|
||||
if action.name in tools:
|
||||
tool = tools[action.name]
|
||||
try:
|
||||
observation = tool.run(action.args)
|
||||
except ValidationError as e:
|
||||
observation = f"Error in args: {str(e)}"
|
||||
result = f"Command {tool.name} returned: {observation}"
|
||||
elif action.name == "ERROR":
|
||||
result = f"Error: {action.args}. "
|
||||
else:
|
||||
result = (
|
||||
f"Unknown command '{action.name}'. "
|
||||
f"Please refer to the 'COMMANDS' list for available "
|
||||
f"commands and only respond in the specified JSON format."
|
||||
)
|
||||
|
||||
memory_to_add = (
|
||||
f"Assistant Reply: {assistant_reply} " f"\nResult: {result} "
|
||||
)
|
||||
color = "red" if str(observation).lower().startswith("Error") else "green"
|
||||
print(colored("Last Observation: " + str(observation)[:500], color))
|
||||
if self.feedback_tool is not None:
|
||||
feedback = f"\n{self.feedback_tool.run('Input: ')}"
|
||||
if feedback in {"q", "stop"}:
|
||||
print("EXITING")
|
||||
return "EXITING"
|
||||
memory_to_add += feedback
|
||||
|
||||
self.memory.add_documents([Document(page_content=memory_to_add)])
|
||||
self.full_message_history.append(SystemMessage(content=result))
|
||||
30
langchain/experimental/autonomous_agents/autogpt/memory.py
Normal file
30
langchain/experimental/autonomous_agents/autogpt/memory.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from langchain.memory.chat_memory import BaseChatMemory, get_prompt_input_key
|
||||
from langchain.vectorstores.base import VectorStoreRetriever
|
||||
|
||||
|
||||
class AutoGPTMemory(BaseChatMemory):
|
||||
retriever: VectorStoreRetriever = Field(exclude=True)
|
||||
"""VectorStoreRetriever object to connect to."""
|
||||
|
||||
@property
|
||||
def memory_variables(self) -> List[str]:
|
||||
return ["chat_history", "relevant_context"]
|
||||
|
||||
def _get_prompt_input_key(self, inputs: Dict[str, Any]) -> str:
|
||||
"""Get the input key for the prompt."""
|
||||
if self.input_key is None:
|
||||
return get_prompt_input_key(inputs, self.memory_variables)
|
||||
return self.input_key
|
||||
|
||||
def load_memory_variables(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
|
||||
input_key = self._get_prompt_input_key(inputs)
|
||||
query = inputs[input_key]
|
||||
docs = self.retriever.get_relevant_documents(query)
|
||||
return {
|
||||
"chat_history": self.chat_memory.messages[-10:],
|
||||
"relevant_context": docs,
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import json
|
||||
from abc import abstractmethod
|
||||
from typing import Dict, NamedTuple
|
||||
|
||||
from langchain.schema import BaseOutputParser
|
||||
import re
|
||||
|
||||
|
||||
class AutoGPTAction(NamedTuple):
|
||||
name: str
|
||||
args: Dict
|
||||
|
||||
|
||||
class BaseAutoGPTOutputParser(BaseOutputParser):
|
||||
@abstractmethod
|
||||
def parse(self, text: str) -> AutoGPTAction:
|
||||
"""Return AutoGPTAction"""
|
||||
|
||||
|
||||
def preprocess_json_input(input_str: str) -> str:
|
||||
# Replace single backslashes with double backslashes, while leaving already escaped ones intact
|
||||
corrected_str = re.sub(
|
||||
r'(?<!\\)\\(?!["\\/bfnrt]|u[0-9a-fA-F]{4})', r"\\\\", input_str
|
||||
)
|
||||
return corrected_str
|
||||
|
||||
|
||||
class AutoGPTOutputParser(BaseAutoGPTOutputParser):
|
||||
def parse(self, text: str) -> AutoGPTAction:
|
||||
try:
|
||||
parsed = json.loads(text, strict=False)
|
||||
except json.JSONDecodeError:
|
||||
preprocessed_text = preprocess_json_input(text)
|
||||
try:
|
||||
parsed = json.loads(preprocessed_text, strict=False)
|
||||
except:
|
||||
return AutoGPTAction(
|
||||
name="ERROR",
|
||||
args={"error": f"Could not parse invalid json: {text}"},
|
||||
)
|
||||
try:
|
||||
return AutoGPTAction(
|
||||
name=parsed["command"]["name"],
|
||||
args=parsed["command"]["args"],
|
||||
)
|
||||
except KeyError as e:
|
||||
return AutoGPTAction(
|
||||
name="ERROR", args={"error": f"Incomplete command args: {parsed}"}
|
||||
)
|
||||
75
langchain/experimental/autonomous_agents/autogpt/prompt.py
Normal file
75
langchain/experimental/autonomous_agents/autogpt/prompt.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import time
|
||||
from typing import Any, Callable, List
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from langchain.experimental.autonomous_agents.autogpt.prompt_generator import get_prompt
|
||||
from langchain.prompts.chat import (
|
||||
BaseChatPromptTemplate,
|
||||
)
|
||||
from langchain.schema import BaseMessage, HumanMessage, SystemMessage
|
||||
from langchain.tools.base import BaseTool
|
||||
from langchain.vectorstores.base import VectorStoreRetriever
|
||||
|
||||
|
||||
class AutoGPTPrompt(BaseChatPromptTemplate, BaseModel):
|
||||
ai_name: str
|
||||
ai_role: str
|
||||
tools: List[BaseTool]
|
||||
token_counter: Callable[[str], int]
|
||||
send_token_limit: int = 4196
|
||||
|
||||
def construct_full_prompt(self, goals: List[str]) -> str:
|
||||
prompt_start = """Your decisions must always be made independently
|
||||
without seeking user assistance. Play to your strengths
|
||||
as an LLM and pursue simple strategies with no legal complications.
|
||||
If you have completed all your tasks,
|
||||
make sure to use the "finish" command."""
|
||||
|
||||
# Construct full prompt
|
||||
full_prompt = (
|
||||
f"You are {self.ai_name}, {self.ai_role}\n{prompt_start}\n\nGOALS:\n\n"
|
||||
)
|
||||
for i, goal in enumerate(goals):
|
||||
full_prompt += f"{i+1}. {goal}\n"
|
||||
|
||||
full_prompt += f"\n\n{get_prompt(self.tools)}"
|
||||
return full_prompt
|
||||
|
||||
def format_messages(self, **kwargs: Any) -> List[BaseMessage]:
|
||||
base_prompt = SystemMessage(content=self.construct_full_prompt(kwargs["goals"]))
|
||||
time_prompt = SystemMessage(
|
||||
content=f"The current time and date is {time.strftime('%c')}"
|
||||
)
|
||||
used_tokens = self.token_counter(base_prompt.content) + self.token_counter(
|
||||
time_prompt.content
|
||||
)
|
||||
memory: VectorStoreRetriever = kwargs["memory"]
|
||||
previous_messages = kwargs["messages"]
|
||||
relevant_docs = memory.get_relevant_documents(str(previous_messages[-10:]))
|
||||
relevant_memory = [d.page_content for d in relevant_docs]
|
||||
relevant_memory_tokens = sum(
|
||||
[self.token_counter(doc) for doc in relevant_memory]
|
||||
)
|
||||
while used_tokens + relevant_memory_tokens > 2500:
|
||||
relevant_memory = relevant_memory[:-1]
|
||||
relevant_memory_tokens = sum(
|
||||
[self.token_counter(doc) for doc in relevant_memory]
|
||||
)
|
||||
content_format = (
|
||||
f"This reminds you of these events "
|
||||
f"from your past:\n{relevant_memory}\n\n"
|
||||
)
|
||||
memory_message = SystemMessage(content=content_format)
|
||||
used_tokens += len(memory_message.content)
|
||||
historical_messages: List[BaseMessage] = []
|
||||
for message in previous_messages[-10:][::-1]:
|
||||
message_tokens = self.token_counter(message.content)
|
||||
if used_tokens + message_tokens > self.send_token_limit - 1000:
|
||||
break
|
||||
historical_messages = [message] + historical_messages
|
||||
input_message = HumanMessage(content=kwargs["user_input"])
|
||||
messages: List[BaseMessage] = [base_prompt, time_prompt, memory_message]
|
||||
messages += historical_messages
|
||||
messages.append(input_message)
|
||||
return messages
|
||||
@@ -0,0 +1,185 @@
|
||||
import json
|
||||
from typing import List
|
||||
|
||||
from langchain.tools.base import BaseTool
|
||||
|
||||
FINISH_NAME = "finish"
|
||||
|
||||
|
||||
class PromptGenerator:
|
||||
"""A class for generating custom prompt strings.
|
||||
|
||||
Does this based on constraints, commands, resources, and performance evaluations.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize the PromptGenerator object.
|
||||
|
||||
Starts with empty lists of constraints, commands, resources,
|
||||
and performance evaluations.
|
||||
"""
|
||||
self.constraints: List[str] = []
|
||||
self.commands: List[BaseTool] = []
|
||||
self.resources: List[str] = []
|
||||
self.performance_evaluation: List[str] = []
|
||||
self.response_format = {
|
||||
"thoughts": {
|
||||
"text": "thought",
|
||||
"reasoning": "reasoning",
|
||||
"plan": "- short bulleted\n- list that conveys\n- long-term plan",
|
||||
"criticism": "constructive self-criticism",
|
||||
"speak": "thoughts summary to say to user",
|
||||
},
|
||||
"command": {"name": "command name", "args": {"arg name": "value"}},
|
||||
}
|
||||
|
||||
def add_constraint(self, constraint: str) -> None:
|
||||
"""
|
||||
Add a constraint to the constraints list.
|
||||
|
||||
Args:
|
||||
constraint (str): The constraint to be added.
|
||||
"""
|
||||
self.constraints.append(constraint)
|
||||
|
||||
def add_tool(self, tool: BaseTool) -> None:
|
||||
self.commands.append(tool)
|
||||
|
||||
def _generate_command_string(self, tool: BaseTool) -> str:
|
||||
schema = json.dumps(tool.args.schema()["properties"])
|
||||
return f"{tool.name}: {tool.description}, args json schema: {schema}"
|
||||
|
||||
def add_resource(self, resource: str) -> None:
|
||||
"""
|
||||
Add a resource to the resources list.
|
||||
|
||||
Args:
|
||||
resource (str): The resource to be added.
|
||||
"""
|
||||
self.resources.append(resource)
|
||||
|
||||
def add_performance_evaluation(self, evaluation: str) -> None:
|
||||
"""
|
||||
Add a performance evaluation item to the performance_evaluation list.
|
||||
|
||||
Args:
|
||||
evaluation (str): The evaluation item to be added.
|
||||
"""
|
||||
self.performance_evaluation.append(evaluation)
|
||||
|
||||
def _generate_numbered_list(self, items: list, item_type: str = "list") -> str:
|
||||
"""
|
||||
Generate a numbered list from given items based on the item_type.
|
||||
|
||||
Args:
|
||||
items (list): A list of items to be numbered.
|
||||
item_type (str, optional): The type of items in the list.
|
||||
Defaults to 'list'.
|
||||
|
||||
Returns:
|
||||
str: The formatted numbered list.
|
||||
"""
|
||||
if item_type == "command":
|
||||
command_strings = [
|
||||
f"{i + 1}. {self._generate_command_string(item)}"
|
||||
for i, item in enumerate(items)
|
||||
]
|
||||
finish_description = (
|
||||
"use this to signal that you have finished all your objectives"
|
||||
)
|
||||
finish_args = (
|
||||
'"response": "final response to let '
|
||||
'people know you have finished your objectives"'
|
||||
)
|
||||
finish_string = (
|
||||
f"{len(items) + 1}. {FINISH_NAME}: "
|
||||
f"{finish_description}, args: {finish_args}"
|
||||
)
|
||||
return "\n".join(command_strings + [finish_string])
|
||||
else:
|
||||
return "\n".join(f"{i+1}. {item}" for i, item in enumerate(items))
|
||||
|
||||
def generate_prompt_string(self) -> str:
|
||||
"""Generate a prompt string.
|
||||
|
||||
Returns:
|
||||
str: The generated prompt string.
|
||||
"""
|
||||
formatted_response_format = json.dumps(self.response_format, indent=4)
|
||||
prompt_string = (
|
||||
f"Constraints:\n{self._generate_numbered_list(self.constraints)}\n\n"
|
||||
f"Commands:\n"
|
||||
f"{self._generate_numbered_list(self.commands, item_type='command')}\n\n"
|
||||
f"Resources:\n{self._generate_numbered_list(self.resources)}\n\n"
|
||||
f"Performance Evaluation:\n"
|
||||
f"{self._generate_numbered_list(self.performance_evaluation)}\n\n"
|
||||
f"You should only respond in JSON format as described below "
|
||||
f"\nResponse Format: \n{formatted_response_format} "
|
||||
f"\nEnsure the response can be parsed by Python json.loads"
|
||||
)
|
||||
|
||||
return prompt_string
|
||||
|
||||
|
||||
def get_prompt(tools: List[BaseTool]) -> str:
|
||||
"""This function generates a prompt string.
|
||||
|
||||
It includes various constraints, commands, resources, and performance evaluations.
|
||||
|
||||
Returns:
|
||||
str: The generated prompt string.
|
||||
"""
|
||||
|
||||
# Initialize the PromptGenerator object
|
||||
prompt_generator = PromptGenerator()
|
||||
|
||||
# Add constraints to the PromptGenerator object
|
||||
prompt_generator.add_constraint(
|
||||
"~4000 word limit for short term memory. "
|
||||
"Your short term memory is short, "
|
||||
"so immediately save important information to files."
|
||||
)
|
||||
prompt_generator.add_constraint(
|
||||
"If you are unsure how you previously did something "
|
||||
"or want to recall past events, "
|
||||
"thinking about similar events will help you remember."
|
||||
)
|
||||
prompt_generator.add_constraint("No user assistance")
|
||||
prompt_generator.add_constraint(
|
||||
'Exclusively use the commands listed in double quotes e.g. "command name"'
|
||||
)
|
||||
|
||||
# Add commands to the PromptGenerator object
|
||||
for tool in tools:
|
||||
prompt_generator.add_tool(tool)
|
||||
|
||||
# Add resources to the PromptGenerator object
|
||||
prompt_generator.add_resource(
|
||||
"Internet access for searches and information gathering."
|
||||
)
|
||||
prompt_generator.add_resource("Long Term memory management.")
|
||||
prompt_generator.add_resource(
|
||||
"GPT-3.5 powered Agents for delegation of simple tasks."
|
||||
)
|
||||
prompt_generator.add_resource("File output.")
|
||||
|
||||
# Add performance evaluations to the PromptGenerator object
|
||||
prompt_generator.add_performance_evaluation(
|
||||
"Continuously review and analyze your actions "
|
||||
"to ensure you are performing to the best of your abilities."
|
||||
)
|
||||
prompt_generator.add_performance_evaluation(
|
||||
"Constructively self-criticize your big-picture behavior constantly."
|
||||
)
|
||||
prompt_generator.add_performance_evaluation(
|
||||
"Reflect on past decisions and strategies to refine your approach."
|
||||
)
|
||||
prompt_generator.add_performance_evaluation(
|
||||
"Every command has a cost, so be smart and efficient. "
|
||||
"Aim to complete tasks in the least number of steps."
|
||||
)
|
||||
|
||||
# Generate the prompt string
|
||||
prompt_string = prompt_generator.generate_prompt_string()
|
||||
|
||||
return prompt_string
|
||||
@@ -0,0 +1,17 @@
|
||||
from langchain.experimental.autonomous_agents.baby_agi.baby_agi import BabyAGI
|
||||
from langchain.experimental.autonomous_agents.baby_agi.task_creation import (
|
||||
TaskCreationChain,
|
||||
)
|
||||
from langchain.experimental.autonomous_agents.baby_agi.task_execution import (
|
||||
TaskExecutionChain,
|
||||
)
|
||||
from langchain.experimental.autonomous_agents.baby_agi.task_prioritization import (
|
||||
TaskPrioritizationChain,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"BabyAGI",
|
||||
"TaskPrioritizationChain",
|
||||
"TaskExecutionChain",
|
||||
"TaskCreationChain",
|
||||
]
|
||||
181
langchain/experimental/autonomous_agents/baby_agi/baby_agi.py
Normal file
181
langchain/experimental/autonomous_agents/baby_agi/baby_agi.py
Normal file
@@ -0,0 +1,181 @@
|
||||
from collections import deque
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from langchain.experimental.autonomous_agents.baby_agi.task_creation import (
|
||||
TaskCreationChain,
|
||||
)
|
||||
from langchain.experimental.autonomous_agents.baby_agi.task_execution import (
|
||||
TaskExecutionChain,
|
||||
)
|
||||
from langchain.experimental.autonomous_agents.baby_agi.task_prioritization import (
|
||||
TaskPrioritizationChain,
|
||||
)
|
||||
|
||||
from langchain.chains.base import Chain
|
||||
from langchain.schema import BaseLanguageModel
|
||||
from langchain.vectorstores.base import VectorStore
|
||||
|
||||
|
||||
class BabyAGI(Chain, BaseModel):
|
||||
"""Controller model for the BabyAGI agent."""
|
||||
|
||||
task_list: deque = Field(default_factory=deque)
|
||||
task_creation_chain: Chain = Field(...)
|
||||
task_prioritization_chain: Chain = Field(...)
|
||||
execution_chain: Chain = Field(...)
|
||||
task_id_counter: int = Field(1)
|
||||
vectorstore: VectorStore = Field(init=False)
|
||||
max_iterations: Optional[int] = None
|
||||
|
||||
class Config:
|
||||
"""Configuration for this pydantic object."""
|
||||
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
def add_task(self, task: Dict) -> None:
|
||||
self.task_list.append(task)
|
||||
|
||||
def print_task_list(self) -> None:
|
||||
print("\033[95m\033[1m" + "\n*****TASK LIST*****\n" + "\033[0m\033[0m")
|
||||
for t in self.task_list:
|
||||
print(str(t["task_id"]) + ": " + t["task_name"])
|
||||
|
||||
def print_next_task(self, task: Dict) -> None:
|
||||
print("\033[92m\033[1m" + "\n*****NEXT TASK*****\n" + "\033[0m\033[0m")
|
||||
print(str(task["task_id"]) + ": " + task["task_name"])
|
||||
|
||||
def print_task_result(self, result: str) -> None:
|
||||
print("\033[93m\033[1m" + "\n*****TASK RESULT*****\n" + "\033[0m\033[0m")
|
||||
print(result)
|
||||
|
||||
@property
|
||||
def input_keys(self) -> List[str]:
|
||||
return ["objective"]
|
||||
|
||||
@property
|
||||
def output_keys(self) -> List[str]:
|
||||
return []
|
||||
|
||||
def get_next_task(
|
||||
self, result: str, task_description: str, objective: str
|
||||
) -> List[Dict]:
|
||||
"""Get the next task."""
|
||||
task_names = [t["task_name"] for t in self.task_list]
|
||||
|
||||
incomplete_tasks = ", ".join(task_names)
|
||||
response = self.task_creation_chain.run(
|
||||
result=result,
|
||||
task_description=task_description,
|
||||
incomplete_tasks=incomplete_tasks,
|
||||
objective=objective,
|
||||
)
|
||||
new_tasks = response.split("\n")
|
||||
return [
|
||||
{"task_name": task_name} for task_name in new_tasks if task_name.strip()
|
||||
]
|
||||
|
||||
def prioritize_tasks(self, this_task_id: int, objective: str) -> List[Dict]:
|
||||
"""Prioritize tasks."""
|
||||
task_names = [t["task_name"] for t in list(self.task_list)]
|
||||
next_task_id = int(this_task_id) + 1
|
||||
response = self.task_prioritization_chain.run(
|
||||
task_names=", ".join(task_names),
|
||||
next_task_id=str(next_task_id),
|
||||
objective=objective,
|
||||
)
|
||||
new_tasks = response.split("\n")
|
||||
prioritized_task_list = []
|
||||
for task_string in new_tasks:
|
||||
if not task_string.strip():
|
||||
continue
|
||||
task_parts = task_string.strip().split(".", 1)
|
||||
if len(task_parts) == 2:
|
||||
task_id = task_parts[0].strip()
|
||||
task_name = task_parts[1].strip()
|
||||
prioritized_task_list.append(
|
||||
{"task_id": task_id, "task_name": task_name}
|
||||
)
|
||||
return prioritized_task_list
|
||||
|
||||
def _get_top_tasks(self, query: str, k: int) -> List[str]:
|
||||
"""Get the top k tasks based on the query."""
|
||||
results = self.vectorstore.similarity_search(query, k=k)
|
||||
if not results:
|
||||
return []
|
||||
return [str(item.metadata["task"]) for item in results]
|
||||
|
||||
def execute_task(self, objective: str, task: str, k: int = 5) -> str:
|
||||
"""Execute a task."""
|
||||
context = self._get_top_tasks(query=objective, k=k)
|
||||
return self.execution_chain.run(
|
||||
objective=objective, context="\n".join(context), task=task
|
||||
)
|
||||
|
||||
def _call(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Run the agent."""
|
||||
objective = inputs["objective"]
|
||||
first_task = inputs.get("first_task", "Make a todo list")
|
||||
self.add_task({"task_id": 1, "task_name": first_task})
|
||||
num_iters = 0
|
||||
while True:
|
||||
if self.task_list:
|
||||
self.print_task_list()
|
||||
|
||||
# Step 1: Pull the first task
|
||||
task = self.task_list.popleft()
|
||||
self.print_next_task(task)
|
||||
|
||||
# Step 2: Execute the task
|
||||
result = self.execute_task(objective, task["task_name"])
|
||||
this_task_id = int(task["task_id"])
|
||||
self.print_task_result(result)
|
||||
|
||||
# Step 3: Store the result in Pinecone
|
||||
result_id = f"result_{task['task_id']}"
|
||||
self.vectorstore.add_texts(
|
||||
texts=[result],
|
||||
metadatas=[{"task": task["task_name"]}],
|
||||
ids=[result_id],
|
||||
)
|
||||
|
||||
# Step 4: Create new tasks and reprioritize task list
|
||||
new_tasks = self.get_next_task(result, task["task_name"], objective)
|
||||
for new_task in new_tasks:
|
||||
self.task_id_counter += 1
|
||||
new_task.update({"task_id": self.task_id_counter})
|
||||
self.add_task(new_task)
|
||||
self.task_list = deque(self.prioritize_tasks(this_task_id, objective))
|
||||
num_iters += 1
|
||||
if self.max_iterations is not None and num_iters == self.max_iterations:
|
||||
print(
|
||||
"\033[91m\033[1m" + "\n*****TASK ENDING*****\n" + "\033[0m\033[0m"
|
||||
)
|
||||
break
|
||||
return {}
|
||||
|
||||
@classmethod
|
||||
def from_llm(
|
||||
cls,
|
||||
llm: BaseLanguageModel,
|
||||
vectorstore: VectorStore,
|
||||
verbose: bool = False,
|
||||
task_execution_chain: Optional[Chain] = None,
|
||||
**kwargs: Dict[str, Any],
|
||||
) -> "BabyAGI":
|
||||
"""Initialize the BabyAGI Controller."""
|
||||
task_creation_chain = TaskCreationChain.from_llm(llm, verbose=verbose)
|
||||
task_prioritization_chain = TaskPrioritizationChain.from_llm(
|
||||
llm, verbose=verbose
|
||||
)
|
||||
if task_execution_chain is None:
|
||||
execution_chain: Chain = TaskExecutionChain.from_llm(llm, verbose=verbose)
|
||||
else:
|
||||
execution_chain = task_execution_chain
|
||||
return cls(
|
||||
task_creation_chain=task_creation_chain,
|
||||
task_prioritization_chain=task_prioritization_chain,
|
||||
execution_chain=execution_chain,
|
||||
vectorstore=vectorstore,
|
||||
**kwargs,
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
from langchain import LLMChain, PromptTemplate
|
||||
from langchain.schema import BaseLanguageModel
|
||||
|
||||
|
||||
class TaskCreationChain(LLMChain):
|
||||
"""Chain to generates tasks."""
|
||||
|
||||
@classmethod
|
||||
def from_llm(cls, llm: BaseLanguageModel, verbose: bool = True) -> LLMChain:
|
||||
"""Get the response parser."""
|
||||
task_creation_template = (
|
||||
"You are an task creation AI that uses the result of an execution agent"
|
||||
" to create new tasks with the following objective: {objective},"
|
||||
" The last completed task has the result: {result}."
|
||||
" This result was based on this task description: {task_description}."
|
||||
" These are incomplete tasks: {incomplete_tasks}."
|
||||
" Based on the result, create new tasks to be completed"
|
||||
" by the AI system that do not overlap with incomplete tasks."
|
||||
" Return the tasks as an array."
|
||||
)
|
||||
prompt = PromptTemplate(
|
||||
template=task_creation_template,
|
||||
input_variables=[
|
||||
"result",
|
||||
"task_description",
|
||||
"incomplete_tasks",
|
||||
"objective",
|
||||
],
|
||||
)
|
||||
return cls(prompt=prompt, llm=llm, verbose=verbose)
|
||||
@@ -0,0 +1,21 @@
|
||||
from langchain import LLMChain, PromptTemplate
|
||||
from langchain.schema import BaseLanguageModel
|
||||
|
||||
|
||||
class TaskExecutionChain(LLMChain):
|
||||
"""Chain to execute tasks."""
|
||||
|
||||
@classmethod
|
||||
def from_llm(cls, llm: BaseLanguageModel, verbose: bool = True) -> LLMChain:
|
||||
"""Get the response parser."""
|
||||
execution_template = (
|
||||
"You are an AI who performs one task based on the following objective: "
|
||||
"{objective}."
|
||||
"Take into account these previously completed tasks: {context}."
|
||||
" Your task: {task}. Response:"
|
||||
)
|
||||
prompt = PromptTemplate(
|
||||
template=execution_template,
|
||||
input_variables=["objective", "context", "task"],
|
||||
)
|
||||
return cls(prompt=prompt, llm=llm, verbose=verbose)
|
||||
@@ -0,0 +1,24 @@
|
||||
from langchain import LLMChain, PromptTemplate
|
||||
from langchain.schema import BaseLanguageModel
|
||||
|
||||
|
||||
class TaskPrioritizationChain(LLMChain):
|
||||
"""Chain to prioritize tasks."""
|
||||
|
||||
@classmethod
|
||||
def from_llm(cls, llm: BaseLanguageModel, verbose: bool = True) -> LLMChain:
|
||||
"""Get the response parser."""
|
||||
task_prioritization_template = (
|
||||
"You are a task prioritization AI tasked with cleaning the formatting of "
|
||||
"and reprioritizing the following tasks: {task_names}."
|
||||
" Consider the ultimate objective of your team: {objective}."
|
||||
" Do not remove any tasks. Return the result as a numbered list, like:"
|
||||
" #. First task"
|
||||
" #. Second task"
|
||||
" Start the task list with number {next_task_id}."
|
||||
)
|
||||
prompt = PromptTemplate(
|
||||
template=task_prioritization_template,
|
||||
input_variables=["task_names", "next_task_id", "objective"],
|
||||
)
|
||||
return cls(prompt=prompt, llm=llm, verbose=verbose)
|
||||
@@ -5,11 +5,14 @@ import logging
|
||||
import sys
|
||||
import warnings
|
||||
from typing import (
|
||||
AbstractSet,
|
||||
Any,
|
||||
Callable,
|
||||
Collection,
|
||||
Dict,
|
||||
Generator,
|
||||
List,
|
||||
Literal,
|
||||
Mapping,
|
||||
Optional,
|
||||
Set,
|
||||
@@ -150,6 +153,10 @@ class BaseOpenAI(BaseLLM):
|
||||
"""Maximum number of retries to make when generating."""
|
||||
streaming: bool = False
|
||||
"""Whether to stream the results or not."""
|
||||
allowed_special: Union[Literal["all"], AbstractSet[str]] = set()
|
||||
"""Set of special tokens that are allowed。"""
|
||||
disallowed_special: Union[Literal["all"], Collection[str]] = "all"
|
||||
"""Set of special tokens that are not allowed。"""
|
||||
|
||||
def __new__(cls, **data: Any) -> Union[OpenAIChat, BaseOpenAI]: # type: ignore
|
||||
"""Initialize the OpenAI object."""
|
||||
@@ -449,7 +456,11 @@ class BaseOpenAI(BaseLLM):
|
||||
|
||||
enc = tiktoken.encoding_for_model(self.model_name)
|
||||
|
||||
tokenized_text = enc.encode(text)
|
||||
tokenized_text = enc.encode(
|
||||
text,
|
||||
allowed_special=self.allowed_special,
|
||||
disallowed_special=self.disallowed_special,
|
||||
)
|
||||
|
||||
# calculate the number of tokens in the encoded text
|
||||
return len(tokenized_text)
|
||||
@@ -602,6 +613,10 @@ class OpenAIChat(BaseLLM):
|
||||
"""Series of messages for Chat input."""
|
||||
streaming: bool = False
|
||||
"""Whether to stream the results or not."""
|
||||
allowed_special: Union[Literal["all"], AbstractSet[str]] = set()
|
||||
"""Set of special tokens that are allowed。"""
|
||||
disallowed_special: Union[Literal["all"], Collection[str]] = "all"
|
||||
"""Set of special tokens that are not allowed。"""
|
||||
|
||||
class Config:
|
||||
"""Configuration for this pydantic object."""
|
||||
@@ -785,7 +800,11 @@ class OpenAIChat(BaseLLM):
|
||||
enc = tiktoken.encoding_for_model("gpt-3.5-turbo")
|
||||
|
||||
# encode the text using the GPT-3.5-Turbo encoder
|
||||
tokenized_text = enc.encode(text)
|
||||
tokenized_text = enc.encode(
|
||||
text,
|
||||
allowed_special=self.allowed_special,
|
||||
disallowed_special=self.disallowed_special,
|
||||
)
|
||||
|
||||
# calculate the number of tokens in the encoded text
|
||||
return len(tokenized_text)
|
||||
|
||||
@@ -1,75 +1,21 @@
|
||||
"""Base implementation for tools or skills."""
|
||||
|
||||
import inspect
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any, Callable, Dict, Optional, Sequence, Tuple, Type, Union
|
||||
from typing import Any, Dict, Optional, Sequence, Tuple, Type, Union
|
||||
|
||||
from pydantic import BaseModel, Extra, Field, create_model, validator
|
||||
from pydantic import BaseModel, Extra, Field, validator
|
||||
|
||||
from langchain.callbacks import get_callback_manager
|
||||
from langchain.callbacks.base import BaseCallbackManager
|
||||
|
||||
|
||||
def create_args_schema_model_from_signature(run_func: Callable) -> Type[BaseModel]:
|
||||
"""Create a pydantic model type from a function's signature."""
|
||||
signature_ = inspect.signature(run_func)
|
||||
field_definitions: Dict[str, Any] = {}
|
||||
|
||||
for name, param in signature_.parameters.items():
|
||||
if name == "self":
|
||||
continue
|
||||
default_value = (
|
||||
param.default if param.default != inspect.Parameter.empty else None
|
||||
)
|
||||
annotation = (
|
||||
param.annotation if param.annotation != inspect.Parameter.empty else Any
|
||||
)
|
||||
# Handle functions with *args in the signature
|
||||
if param.kind == inspect.Parameter.VAR_POSITIONAL:
|
||||
field_definitions[name] = (
|
||||
Any,
|
||||
Field(default=None, extra={"is_var_positional": True}),
|
||||
)
|
||||
# handle functions with **kwargs in the signature
|
||||
elif param.kind == inspect.Parameter.VAR_KEYWORD:
|
||||
field_definitions[name] = (
|
||||
Any,
|
||||
Field(default=None, extra={"is_var_keyword": True}),
|
||||
)
|
||||
# Handle all other named parameters
|
||||
else:
|
||||
is_keyword_only = param.kind == inspect.Parameter.KEYWORD_ONLY
|
||||
field_definitions[name] = (
|
||||
annotation,
|
||||
Field(
|
||||
default=default_value, extra={"is_keyword_only": is_keyword_only}
|
||||
),
|
||||
)
|
||||
return create_model("ArgsModel", **field_definitions) # type: ignore
|
||||
|
||||
|
||||
def _to_args_and_kwargs(model: BaseModel) -> Tuple[Sequence, dict]:
|
||||
args = []
|
||||
kwargs = {}
|
||||
for name, field in model.__fields__.items():
|
||||
value = getattr(model, name)
|
||||
# Handle *args in the function signature
|
||||
if field.field_info.extra.get("extra", {}).get("is_var_positional"):
|
||||
if isinstance(value, str):
|
||||
# Base case for backwards compatability
|
||||
args.append(value)
|
||||
elif value is not None:
|
||||
args.extend(value)
|
||||
# Handle **kwargs in the function signature
|
||||
elif field.field_info.extra.get("extra", {}).get("is_var_keyword"):
|
||||
if value is not None:
|
||||
kwargs.update(value)
|
||||
elif field.field_info.extra.get("extra", {}).get("is_keyword_only"):
|
||||
kwargs[name] = value
|
||||
else:
|
||||
args.append(value)
|
||||
|
||||
return tuple(args), kwargs
|
||||
def _to_args_and_kwargs(run_input: Union[str, Dict]) -> Tuple[Sequence, dict]:
|
||||
# For backwards compatability, if run_input is a string,
|
||||
# pass as a positional argument.
|
||||
if isinstance(run_input, str):
|
||||
return (run_input,), {}
|
||||
else:
|
||||
return [], run_input
|
||||
|
||||
|
||||
class BaseTool(ABC, BaseModel):
|
||||
@@ -90,31 +36,28 @@ class BaseTool(ABC, BaseModel):
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
@property
|
||||
def args(self) -> Type[BaseModel]:
|
||||
def args(self) -> Union[Type[BaseModel], Type[str]]:
|
||||
"""Generate an input pydantic model."""
|
||||
if self.args_schema is not None:
|
||||
return self.args_schema
|
||||
return create_args_schema_model_from_signature(self._run)
|
||||
return str if self.args_schema is None else self.args_schema
|
||||
|
||||
def _parse_input(
|
||||
self,
|
||||
tool_input: Union[str, Dict],
|
||||
) -> BaseModel:
|
||||
) -> None:
|
||||
"""Convert tool input to pydantic model."""
|
||||
pydantic_input_type = self.args
|
||||
input_args = self.args
|
||||
if isinstance(tool_input, str):
|
||||
# For backwards compatibility, a tool that only takes
|
||||
# a single string input will be converted to a dict.
|
||||
# to be validated.
|
||||
field_name = next(iter(pydantic_input_type.__fields__))
|
||||
tool_input = {field_name: tool_input}
|
||||
if pydantic_input_type is not None:
|
||||
return pydantic_input_type.parse_obj(tool_input)
|
||||
if issubclass(input_args, BaseModel):
|
||||
key_ = next(iter(input_args.__fields__.keys()))
|
||||
input_args.validate({key_: tool_input})
|
||||
else:
|
||||
raise ValueError(
|
||||
f"args_schema required for tool {self.name} in order to"
|
||||
f" accept input of type {type(tool_input)}"
|
||||
)
|
||||
if issubclass(input_args, BaseModel):
|
||||
input_args.validate(tool_input)
|
||||
else:
|
||||
raise ValueError(
|
||||
f"args_schema required for tool {self.name} in order to"
|
||||
f" accept input of type {type(tool_input)}"
|
||||
)
|
||||
|
||||
@validator("callback_manager", pre=True, always=True)
|
||||
def set_callback_manager(
|
||||
@@ -143,20 +86,20 @@ class BaseTool(ABC, BaseModel):
|
||||
**kwargs: Any,
|
||||
) -> str:
|
||||
"""Run the tool."""
|
||||
run_input = self._parse_input(tool_input)
|
||||
self._parse_input(tool_input)
|
||||
if not self.verbose and verbose is not None:
|
||||
verbose_ = verbose
|
||||
else:
|
||||
verbose_ = self.verbose
|
||||
self.callback_manager.on_tool_start(
|
||||
{"name": self.name, "description": self.description},
|
||||
str(run_input),
|
||||
tool_input if isinstance(tool_input, str) else str(tool_input),
|
||||
verbose=verbose_,
|
||||
color=start_color,
|
||||
**kwargs,
|
||||
)
|
||||
try:
|
||||
args, kwargs = _to_args_and_kwargs(run_input)
|
||||
args, kwargs = _to_args_and_kwargs(tool_input)
|
||||
observation = self._run(*args, **kwargs)
|
||||
except (Exception, KeyboardInterrupt) as e:
|
||||
self.callback_manager.on_tool_error(e, verbose=verbose_)
|
||||
@@ -175,7 +118,7 @@ class BaseTool(ABC, BaseModel):
|
||||
**kwargs: Any,
|
||||
) -> str:
|
||||
"""Run the tool asynchronously."""
|
||||
run_input = self._parse_input(tool_input)
|
||||
self._parse_input(tool_input)
|
||||
if not self.verbose and verbose is not None:
|
||||
verbose_ = verbose
|
||||
else:
|
||||
@@ -183,7 +126,7 @@ class BaseTool(ABC, BaseModel):
|
||||
if self.callback_manager.is_async:
|
||||
await self.callback_manager.on_tool_start(
|
||||
{"name": self.name, "description": self.description},
|
||||
str(run_input.dict()),
|
||||
tool_input if isinstance(tool_input, str) else str(tool_input),
|
||||
verbose=verbose_,
|
||||
color=start_color,
|
||||
**kwargs,
|
||||
@@ -191,14 +134,14 @@ class BaseTool(ABC, BaseModel):
|
||||
else:
|
||||
self.callback_manager.on_tool_start(
|
||||
{"name": self.name, "description": self.description},
|
||||
str(run_input.dict()),
|
||||
tool_input if isinstance(tool_input, str) else str(tool_input),
|
||||
verbose=verbose_,
|
||||
color=start_color,
|
||||
**kwargs,
|
||||
)
|
||||
try:
|
||||
# We then call the tool on the tool input to get an observation
|
||||
args, kwargs = _to_args_and_kwargs(run_input)
|
||||
args, kwargs = _to_args_and_kwargs(tool_input)
|
||||
observation = await self._arun(*args, **kwargs)
|
||||
except (Exception, KeyboardInterrupt) as e:
|
||||
if self.callback_manager.is_async:
|
||||
|
||||
@@ -29,6 +29,6 @@ class WriteFileTool(BaseTool):
|
||||
except Exception as e:
|
||||
return "Error: " + str(e)
|
||||
|
||||
async def _arun(self, tool_input: str) -> str:
|
||||
async def _arun(self, file_path: str, text: str) -> str:
|
||||
# TODO: Add aiofiles method
|
||||
raise NotImplementedError
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "langchain"
|
||||
version = "0.0.142"
|
||||
version = "0.0.143"
|
||||
description = "Building applications with LLMs through composability"
|
||||
authors = []
|
||||
license = "MIT"
|
||||
@@ -137,7 +137,7 @@ llms = ["anthropic", "cohere", "openai", "nlpcloud", "huggingface_hub", "manifes
|
||||
qdrant = ["qdrant-client"]
|
||||
openai = ["openai"]
|
||||
cohere = ["cohere"]
|
||||
all = ["anthropic", "cohere", "openai", "nlpcloud", "huggingface_hub", "jina", "manifest-ml", "elasticsearch", "opensearch-py", "google-search-results", "faiss-cpu", "sentence_transformers", "transformers", "spacy", "nltk", "wikipedia", "beautifulsoup4", "tiktoken", "torch", "jinja2", "pinecone-client", "pinecone-text", "weaviate-client", "redis", "google-api-python-client", "wolframalpha", "qdrant-client", "tensorflow-text", "pypdf", "networkx", "nomic", "aleph-alpha-client", "deeplake", "pgvector", "psycopg2-binary", "boto3", "pyowm"]
|
||||
all = ["anthropic", "cohere", "openai", "nlpcloud", "huggingface_hub", "jina", "manifest-ml", "elasticsearch", "opensearch-py", "google-search-results", "faiss-cpu", "sentence_transformers", "transformers", "spacy", "nltk", "wikipedia", "beautifulsoup4", "tiktoken", "torch", "jinja2", "pinecone-client", "pinecone-text", "weaviate-client", "redis", "google-api-python-client", "wolframalpha", "qdrant-client", "tensorflow-text", "pypdf", "networkx", "nomic", "aleph-alpha-client", "deeplake", "pgvector", "psycopg2-binary", "boto3", "pyowm", "pytesseract", "html2text", "atlassian-python-api", "gptcache"]
|
||||
|
||||
[tool.ruff]
|
||||
select = [
|
||||
|
||||
@@ -9,7 +9,7 @@ from langchain.agents.mrkl.output_parser import MRKLOutputParser
|
||||
from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS, PREFIX, SUFFIX
|
||||
from langchain.agents.tools import Tool
|
||||
from langchain.prompts import PromptTemplate
|
||||
from langchain.schema import AgentAction
|
||||
from langchain.schema import AgentAction, OutputParserException
|
||||
from tests.unit_tests.llms.fake_llm import FakeLLM
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ def test_get_final_answer_multiline() -> None:
|
||||
def test_bad_action_input_line() -> None:
|
||||
"""Test handling when no action input found."""
|
||||
llm_output = "Thought: I need to search for NBA\n" "Action: Search\n" "Thought: NBA"
|
||||
with pytest.raises(ValueError):
|
||||
with pytest.raises(OutputParserException):
|
||||
get_action_and_input(llm_output)
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ def test_bad_action_line() -> None:
|
||||
llm_output = (
|
||||
"Thought: I need to search for NBA\n" "Thought: Search\n" "Action Input: NBA"
|
||||
)
|
||||
with pytest.raises(ValueError):
|
||||
with pytest.raises(OutputParserException):
|
||||
get_action_and_input(llm_output)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Test tool utils."""
|
||||
from datetime import datetime
|
||||
from typing import Any, Optional, Type, Union
|
||||
from typing import Optional, Type, Union
|
||||
|
||||
import pytest
|
||||
from pydantic import BaseModel
|
||||
@@ -125,21 +125,27 @@ def test_tool_with_kwargs() -> None:
|
||||
|
||||
@tool(return_direct=True)
|
||||
def search_api(
|
||||
arg_1: float, *args: Any, ping: Optional[str] = None, **kwargs: Any
|
||||
arg_1: float,
|
||||
ping: str = "hi",
|
||||
) -> str:
|
||||
"""Search the API for the query."""
|
||||
return f"arg_1={arg_1}, foo={args}, ping={ping}, kwargs={kwargs}"
|
||||
return f"arg_1={arg_1}, ping={ping}"
|
||||
|
||||
assert isinstance(search_api, Tool)
|
||||
result = search_api.run(
|
||||
tool_input={
|
||||
"arg_1": 3.2,
|
||||
"args": "fam",
|
||||
"kwargs": {"bar": "baz"},
|
||||
"ping": "pong",
|
||||
}
|
||||
)
|
||||
assert result == "arg_1=3.2, foo=('fam',), ping=pong, kwargs={'bar': 'baz'}"
|
||||
assert result == "arg_1=3.2, ping=pong"
|
||||
|
||||
result = search_api.run(
|
||||
tool_input={
|
||||
"arg_1": 3.2,
|
||||
}
|
||||
)
|
||||
assert result == "arg_1=3.2, ping=hi"
|
||||
|
||||
|
||||
def test_missing_docstring() -> None:
|
||||
|
||||
Reference in New Issue
Block a user