-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #183 from assafelovic/feature/permchain
Feature/permchain
- Loading branch information
Showing
16 changed files
with
405 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Permchain x Researcher | ||
Sample use of Langchain's Autonomous agent framework Permchain with GPT Researcher. | ||
|
||
## Use case | ||
Permchain is a framework for building autonomous agents that can be used to automate tasks and communication between agents to complete complex tasks. This example uses Permchain to automate the process of finding and summarizing research reports on any given topic. | ||
|
||
## The Agent Team | ||
The research team is made up of 3 agents: | ||
- Researcher agent (gpt-researcher) - This agent is in charge of finding and summarizing relevant research papers. | ||
- Editor agent - This agent is in charge of validating the correctness of the report given a set of criteria. | ||
- Reviser agent - This agent is in charge of revising the report until it is satisfactory. | ||
|
||
## How it works | ||
The research agent (gpt-researcher) is in charge of finding and summarizing relevant research papers. It does this by using the following process: | ||
- Search for relevant research papers using a search engine | ||
- Extract the relevant information from the research papers | ||
- Summarize the information into a report | ||
- Send the report to the editor agent for validation | ||
- Send the report to the reviser agent for revision | ||
- Repeat until the report is satisfactory | ||
|
||
## How to run | ||
1. Install required packages: | ||
```bash | ||
pip install -r requirements.txt | ||
``` | ||
2. Run the application: | ||
```bash | ||
python test.py | ||
``` | ||
|
||
## Usage | ||
To change the research topic, edit the `query` variable in `test.py` to the desired topic. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
from langchain.chat_models import ChatOpenAI | ||
from langchain.prompts import SystemMessagePromptTemplate | ||
from config import Config | ||
|
||
CFG = Config() | ||
|
||
EDIT_TEMPLATE = """You are an editor. \ | ||
You have been tasked with editing the following draft, which was written by a non-expert. \ | ||
Please accept the draft if it is good enough to publish, or send it for revision, along with your notes to guide the revision. \ | ||
Things you should be checking for: | ||
- This draft MUST fully answer the original question | ||
- This draft MUST be written in apa format | ||
If not all of the above criteria are met, you should send appropriate revision notes. | ||
""" | ||
|
||
|
||
class EditorActor: | ||
def __init__(self): | ||
self.model = ChatOpenAI(model=CFG.smart_llm_model) | ||
self.prompt = SystemMessagePromptTemplate.from_template(EDIT_TEMPLATE) + "Draft:\n\n{draft}" | ||
self.functions = [ | ||
{ | ||
"name": "revise", | ||
"description": "Sends the draft for revision", | ||
"parameters": { | ||
"type": "object", | ||
"properties": { | ||
"notes": { | ||
"type": "string", | ||
"description": "The editor's notes to guide the revision.", | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ | ||
"name": "accept", | ||
"description": "Accepts the draft", | ||
"parameters": { | ||
"type": "object", | ||
"properties": {"ready": {"const": True}}, | ||
}, | ||
}, | ||
] | ||
|
||
@property | ||
def runnable(self): | ||
return ( | ||
self.prompt | self.model.bind(functions=self.functions) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
from operator import itemgetter | ||
from langchain.runnables.openai_functions import OpenAIFunctionsRouter | ||
|
||
from permchain.connection_inmemory import InMemoryPubSubConnection | ||
from permchain.pubsub import PubSub | ||
from permchain.topic import Topic | ||
|
||
''' | ||
This is the research team. | ||
It is a group of autonomous agents that work together to answer a given question | ||
using a comprehensive research process that includes: | ||
- Searching for relevant information across multiple sources | ||
- Extracting relevant information | ||
- Writing a well structured report | ||
- Validating the report | ||
- Revising the report | ||
- Repeat until the report is satisfactory | ||
''' | ||
class ResearchTeam: | ||
def __init__(self, research_actor, editor_actor, reviser_actor): | ||
self.research_actor_instance = research_actor | ||
self.editor_actor_instance = editor_actor | ||
self.revise_actor_instance = reviser_actor | ||
|
||
def run(self, query): | ||
# create topics | ||
editor_inbox = Topic("editor_inbox") | ||
reviser_inbox = Topic("reviser_inbox") | ||
|
||
research_chain = ( | ||
# Listed in inputs | ||
Topic.IN.subscribe() | ||
| {"draft": lambda x: self.research_actor_instance.run(x["question"])} | ||
# The draft always goes to the editor inbox | ||
| editor_inbox.publish() | ||
) | ||
|
||
editor_chain = ( | ||
# Listen for events in the editor_inbox | ||
editor_inbox.subscribe() | ||
| self.editor_actor_instance.runnable | ||
# Depending on the output, different things should happen | ||
| OpenAIFunctionsRouter({ | ||
# If revise is chosen, we send a push to the critique_inbox | ||
"revise": ( | ||
{ | ||
"notes": itemgetter("notes"), | ||
"draft": editor_inbox.current() | itemgetter("draft"), | ||
"question": Topic.IN.current() | itemgetter("question"), | ||
} | ||
| reviser_inbox.publish() | ||
), | ||
# If accepted, then we return | ||
"accept": editor_inbox.current() | Topic.OUT.publish(), | ||
}) | ||
) | ||
|
||
reviser_chain = ( | ||
# Listen for events in the reviser's inbox | ||
reviser_inbox.subscribe() | ||
| self.revise_actor_instance.runnable | ||
# Publish to the editor inbox | ||
| editor_inbox.publish() | ||
) | ||
|
||
web_researcher = PubSub( | ||
processes=(research_chain, editor_chain, reviser_chain), | ||
connection=InMemoryPubSubConnection(), | ||
) | ||
|
||
res = web_researcher.invoke({"question": query}) | ||
print(res) | ||
return res[0]["draft"] |
Oops, something went wrong.