Retrievers inheriting from BaseRetriever are incompatible with typing.Protocol
Labels: name: area: vector store, name: auto:bug

### System Info

langchain v0.0.254
python 3.11

### Who can help?

In this commit https://github.com/langchain-ai/langchain/commit/81e5b1ad362e9e6ec955b6a54776322af82050d0#diff-5d00673e4963a0b2c6bf091d22f98c30d267b20fea4d15d9541ba6d1f5d79e4fR20 inheritance from `Serializable` was introduced. This inheritance is the root of the problem. The commit was by @nfcampos. Perhaps you can help?

### Information

- [ ] The official example notebooks/scripts
- [ ] My own modified scripts

### Related Components

- [ ] LLMs/Chat Models
- [ ] Embedding Models
- [ ] Prompts / Prompt Templates / Prompt Selectors
- [ ] Output Parsers
- [ ] Document Loaders
- [X] Vector Stores / Retrievers
- [ ] Memory
- [ ] Agents / Agent Executors
- [ ] Tools / Toolkits
- [ ] Chains
- [ ] Callbacks/Tracing
- [ ] Async

### Reproduction

Simply run this code: 

``` python 
from typing import Protocol
from langchain.schema.retriever import BaseRetriever


class Foo(Protocol):
    bar: int


class IAmAFailure(BaseRetriever):
    foo: Foo
```

You will then see the error: 

```
Traceback (most recent call last):
  File "/home/yolen/Desktop/langchain_bug.py", line 9, in <module>
    class IAmAFailure(Serializable):
  File "pydantic/main.py", line 197, in pydantic.main.ModelMetaclass.__new__
  File "pydantic/fields.py", line 506, in pydantic.fields.ModelField.infer
  File "pydantic/fields.py", line 436, in pydantic.fields.ModelField.__init__
  File "pydantic/fields.py", line 552, in pydantic.fields.ModelField.prepare
  File "pydantic/fields.py", line 639, in pydantic.fields.ModelField._type_analysis
  File "/usr/local/lib/python3.11/typing.py", line 1960, in __instancecheck__
    raise TypeError("Instance and class checks can only be used with"
TypeError: Instance and class checks can only be used with @runtime_checkable protocols
```

Adding the `@runtime_checkable` decorator does not help (just changes the error). To my understanding, this problem is cased by the inheritance of `Serializable` in the new release https://github.com/langchain-ai/langchain/blob/fa30a57034b6359e8de36bbb98766d2214acfcbd/libs/langchain/langchain/schema/retriever.py#L21.  

### Expected behavior

I would expect that I can use Protocols with retrievers. In my use case, I, among others, inject a class that can compute a query embedding. The `QueryEmbedding` class is a protocol e.g.

```python 
class QueryEmbedder(Protocol):
    async def get_embeddings(self, *, text: str) -> list[TextEmbedding]:
        ...

class FooRetriever(BaseRetriever):
    def __init__(self,*, query_embedder:QueryEmbedder)->None:
        self.query_embedder=query_embedder 
        
    async def _aget_relevant_documents(
            self, query: str,
            *, run_manager: AsyncCallbackManagerForRetrieverRun) -> list[Document]:
        query_embedding = await self.query_embedder.embed(query=query)
        ...
```

Protocols are very good at reducing the coupling in your code base. Furthermore, I do think that using multiple inheritance will cause problems at some stage. _Composition over inheritance_