-
-
Notifications
You must be signed in to change notification settings - Fork 464
Framework for adding context to LLM prompt #993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 24 commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
8c4380d
context provider
michaelchia 6e79d8b
split base and base command context providers + replacing prompt
michaelchia e9c394b
comment
michaelchia 67cfcf4
only replace prompt if context variable in template
michaelchia 4cde53a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 9746f66
Run mypy on CI, fix or ignore typing issues (#987)
krassowski fb97764
context provider
michaelchia b54d844
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] c382279
mypy
michaelchia 2ee8456
black
michaelchia 2514beb
modify backtick logic
michaelchia 29987e7
allow for spaces in filepath
michaelchia bf5060a
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] b7e7142
refactor
michaelchia 86150a8
fixes
michaelchia c0ae4d9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] d93da8f
fix test
michaelchia 139e37a
refactor autocomplete to remove hardcoded '/' and '@' prefix
michaelchia 83197a7
modify context prompt template
michaelchia 61bab49
refactor
michaelchia f184dd7
docstrings + refactor
michaelchia b4e00c8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] f5a20cf
mypy
michaelchia 758c187
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] 691cec8
add context providers to help
michaelchia 2b29429
remove _examples.py and remove @learned from defaults
michaelchia eb5eeb4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] ea10442
make find_commands unoverridable
michaelchia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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,3 @@ | ||
| from .base import BaseCommandContextProvider, ContextCommand, ContextProviderException | ||
| from .file import FileContextProvider | ||
| from .learned import LearnedContextProvider |
133 changes: 133 additions & 0 deletions
133
packages/jupyter-ai/jupyter_ai/context_providers/_examples.py
This file contains hidden or 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,133 @@ | ||
| # This file is for illustrative purposes | ||
| # It is to be deleted before merging | ||
| from typing import List | ||
|
|
||
| from jupyter_ai.models import HumanChatMessage | ||
| from langchain_community.retrievers import ArxivRetriever, WikipediaRetriever | ||
| from langchain_core.output_parsers import StrOutputParser | ||
| from langchain_core.prompts import ChatPromptTemplate | ||
|
|
||
| from .base import BaseCommandContextProvider, ContextCommand, _BaseContextProvider | ||
|
|
||
| # Examples of the ease of implementing retriever based context providers | ||
| ARXIV_TEMPLATE = """ | ||
| Title: {title} | ||
| Publish Date: {publish_date} | ||
| ''' | ||
| {content} | ||
| ''' | ||
| """.strip() | ||
|
|
||
|
|
||
| class ArxivContextProvider(BaseCommandContextProvider): | ||
| id = "arvix" | ||
| description = "Include papers from Arxiv" | ||
| remove_from_prompt = True | ||
| header = "Following are snippets of research papers:" | ||
|
|
||
| def __init__(self, **kwargs): | ||
| super().__init__(**kwargs) | ||
| self.retriever = ArxivRetriever() | ||
|
|
||
| async def _make_context_prompt( | ||
| self, message: HumanChatMessage, commands: List[ContextCommand] | ||
| ) -> str: | ||
| query = self._clean_prompt(message.body) | ||
| docs = await self.retriever.ainvoke(query) | ||
| context = "\n\n".join( | ||
| [ | ||
| ARXIV_TEMPLATE.format( | ||
| content=d.page_content, | ||
| title=d.metadata["Title"], | ||
| publish_date=d.metadata["Published"], | ||
| ) | ||
| for d in docs | ||
| ] | ||
| ) | ||
| return self.header + "\n" + context | ||
|
|
||
|
|
||
| # Another retriever based context provider with a rewrite step using LLM | ||
| WIKI_TEMPLATE = """ | ||
| Title: {title} | ||
| ''' | ||
| {content} | ||
| ''' | ||
| """.strip() | ||
|
|
||
| REWRITE_TEMPLATE = """Provide a better search query for \ | ||
| web search engine to answer the given question, end \ | ||
| the queries with ’**’. Question: \ | ||
| {x} Answer:""" | ||
|
|
||
|
|
||
| class WikiContextProvider(BaseCommandContextProvider): | ||
| id = "wiki" | ||
| description = "Include knowledge from Wikipedia" | ||
| remove_from_prompt = True | ||
| header = "Following are information from wikipedia:" | ||
|
|
||
| def __init__(self, **kwargs): | ||
| super().__init__(**kwargs) | ||
| self.retriever = WikipediaRetriever() | ||
|
|
||
| async def _make_context_prompt( | ||
| self, message: HumanChatMessage, commands: List[ContextCommand] | ||
| ) -> str: | ||
| prompt = self._clean_prompt(message.body) | ||
| search_query = await self._rewrite_prompt(prompt) | ||
| docs = await self.retriever.ainvoke(search_query) | ||
| context = "\n\n".join( | ||
| [ | ||
| WIKI_TEMPLATE.format( | ||
| content=d.page_content, | ||
| title=d.metadata["title"], | ||
| ) | ||
| for d in docs | ||
| ] | ||
| ) | ||
| return self.header + "\n" + context | ||
|
|
||
| async def _rewrite_prompt(self, prompt: str) -> str: | ||
| return await self.get_llm_chain().ainvoke(prompt) | ||
|
|
||
| def get_llm_chain(self): | ||
| # from https://github.com/langchain-ai/langchain/blob/master/cookbook/rewrite.ipynb | ||
| llm = self.get_llm() | ||
| rewrite_prompt = ChatPromptTemplate.from_template(REWRITE_TEMPLATE) | ||
|
|
||
| def _parse(text): | ||
| return text.strip('"').strip("**") | ||
|
|
||
| return rewrite_prompt | llm | StrOutputParser() | _parse | ||
|
|
||
|
|
||
| # Partial example of non-command context provider for errors. | ||
| # Assuming there is an option in UI to add cell errors to messages, | ||
| # default chat will automatically invoke this context provider to add | ||
| # solutions retrieved from a custom error database or a stackoverflow / google | ||
| # retriever pipeline to find solutions for errors. | ||
| class ErrorContextProvider(_BaseContextProvider): | ||
| id = "error" | ||
| description = "Include custom error context" | ||
| remove_from_prompt = True | ||
| header = "Following are potential solutions for the error:" | ||
| is_command = False # will not show up in autocomplete | ||
|
|
||
| async def make_context_prompt(self, message: HumanChatMessage) -> str: | ||
| # will run for every message with a cell error since it does not | ||
| # use _find_instances to check for the presence of the command in | ||
| # the message. | ||
| if not (message.selection and message.selection.type == "cell-with-error"): | ||
| return "" | ||
| docs = await self.solution_retriever.ainvoke(message.selection) | ||
| if not docs: | ||
| return "" | ||
| context = "\n\n".join([d.page_content for d in docs]) | ||
| return self.header + "\n" + context | ||
|
|
||
| @property | ||
| def solution_retriever(self): | ||
| # retriever that takes an error and returns a solutions from a database | ||
| # of error messages. | ||
| raise NotImplementedError("Error retriever not implemented") |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.