MaartenGr / MaartenGr/BERTopic
Update LangChain Support
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 7.8k
- Forks
- 920
- Avg merge
- 22h 24m
- Merged PRs (30d)
- 5
Description
### Feature request
The provided examples that leverage LangChain to create a representation all make use of `langchain.chains.question_answering.load_qa_chain` and the implementation is not very transparent to the user, leading to inconsistencies and difficulties to understand how to provide custom chains.
### Motivation
### Some of the issues in detail
- `langchain.chains.question_answering.load_qa_chain` is [now depricated](https://api.python.langchain.com/en/latest/chains/langchain.chains.question_answering.chain.load_qa_chain.html) and will be removed at some point.
- The current LangChain integration is not very clear because
- a `prompt` can be specified in the constructor of the `LangChain` class. However this is not a prompt but rather a custom instruction that is passed to the provided chain through the `question` key.
- in the case of `langchain.chains.question_answering.load_qa_chain` (which is the provided example), this `question` key is added as part of a larger, hard-coded (and not transparent to a casual user) [prompt](https://github.com/langchain-ai/langchain/blob/master/libs/langchain/langchain/chains/question_answering/stuff_prompt.py).
- if a user wants to fully customize the instructions to create the representation, it would be best not to use the `langchain.chains.question_answering.load_qa_chain` chain to avoid this hard-coded prompt (this is currently not very clearly documented). In addition, if that specific chain is not used, the use of a `question` key can be confusing.
- the approach to add keywords in the prompt (by adding `"[KEYWORDS]"` in `self.prompt` and then performing some string manipulation) is confusing.
- Some imports to LangChain are outdated (e.g. Documents, OpenAI).
### Example of workarounds in current implementation
With the current implementation, a user wanting to use a custom LangChain prompt in a custom LCEL chain and add keywords to that prompt would have to do something like (ignoring that documents are passed as Document objects and not formatted into a str).
```python
from bertopic.representation import LangChain
from langchain_core.prompts import ChatPromptTemplate
custom_prompt = ChatPromptTemplate.from_messages(
[
("system", "Custom instructions."),
("human", "Documents: {input_documents}, Keywords: {question}"),
]
)
chain = some_custom_chain_with_above_prompt
representation_model = LangChain(chain, prompt="[KEYWORDS]")
```
### Related issues:
- The approach I propose to fix this would include an example to specify a system prompt https://github.com/MaartenGr/BERTopic/issues/2146
### Your contribution
I propose several changes, which I have started working on in a branch (made a PR to make the diff easy to see).
- Update the examples so that `langchain.chains.question_answering.load_qa_chain` is replaced by `langchain.chains.combine_documents.stuff.create_stuff_documents_chain` as recommended in the [migration guide](https://python.langchain.com/docs/versions/migrating_chains/stuff_docs_chain/).
- This new approach still takes care of formatting the Document objects into the prompt, but the prompt must now be specified explicitly (instead of the implicit, hard-coded prompt of `langchain.chains.question_answering.load_qa_chain`).
- Remove the ability to provide a prompt in the constructor of `LangChain` as the prompt must now be explicitly created with the chain object.
- Rename the keys for consistency to `documents`, `keywords`, and `representation` (note that `langchain.chains.combine_documents.stuff.create_stuff_documents_chain` does not have a `output_text` output key and the `representation` key must thus be added).
- Make it so that the `keywords` key is always provided to the chain (but it's up to the user to include a placeholder for it in their prompt).
Questions:
- Should we provide a new example prompt to replace `DEFAULT_PROMPT`? For example
```python
EXAMPLE_PROMPT = "What are these documents about? {documents}. Here are some keywords about them {keywords} Please give a single label."
```
however it could only be used directly in `langchain.chains.combine_documents.stuff.create_stuff_documents_chain` which takes care of formatting the documents.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at `bertopic.representation.LangChain` and the existing LangChain examples, then compare their chain construction with LangChain's migration guidance. Update the examples and integration around explicit prompts, `documents`, `keywords`, and `representation` keys; done means deprecated imports and chain usage are replaced consistently and the documented customization path is clear.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- machine-learning
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100