Upgrade to LangChain 1.x - #195
Merged
Merged
Conversation
The upgrade the retriever rewrite existed to unblock. 69 advisories
down to 44; the whole LangChain family is now clean.
langchain 0.3.30 -> 1.4.0
langchain-core 0.3.86 -> 1.6.2
langchain-openai 0.2.14 -> 1.6.1
langgraph 0.2.76 -> 1.2.11
langgraph-checkpoint 2.1.2 -> 4.2.0
openai 1.109 -> 2.54.0
ragas 0.2.15 -> 0.4.3
Three things did NOT move, each for a reason.
chromadb stays below 1.0, and langchain-chroma at 0.2.x with it.
langchain-chroma 1.x requires chromadb>=1.3.5, and chromadb 1.x opens a
0.5/0.6 bundle by migrating its sqlite sysdb in place (9 -> 10), which
needs write access to the bundle. Installed bundles are root-owned 755,
so running as a normal user gives
InternalError: error returned from database: (code: 8)
attempt to write a readonly database
at startup, before a single question. That is a deliberate operational
step -- chown every bundle on every host -- not something to slip into
a dependency upgrade. The migration itself is sound: chromadb 1.5.9
reads a 0.6-written bundle, and 0.6.3 still reads it afterwards, so a
rollback does not strand the data. langchain-chroma 0.2.3 declares
langchain-core>=0.3.52 with no upper bound and was verified to run
against core 1.6.2 through the full chain.
langchain-community stays at 0.3.31. 0.4 drops
langchain_community.chat_models.vertexai, which ragas 0.4.3 still
imports unconditionally, so 0.4 makes `import ragas` fail and takes
./bin/evaluate with it. ragas declares langchain-community with no
version bound, so the resolver cannot see it; only importing can.
0.3.31 accepts langchain-core <2.0.0.
torch and transformers stay as they were, per the previous upgrade.
Code changes the upgrade forced:
- langchain.chains.* moved to langchain-classic, which is their
supported home rather than a shim. Rewriting the RAG chain as LCEL is
a behaviour change and does not belong here.
- langgraph.utils.runnable.RunnableLike is gone, and langgraph 1.0's
add_node matches nodes structurally on the parameter name `state`.
The node contract is now a Protocol in this repository, and
no_search's parameter is named rather than `_`.
- EnsembleRetriever now validates len(weights) == len(retrievers), so
the empty-ensemble trick used to reach weighted_reciprocal_rank
raises. That trick was removed from the pipeline by the rewrite and
survived only in the test comparing against it -- the upgrade
breaking it is the argument for the rewrite, restated. The vendored
RRF still matches LangChain 1.x exactly, over 2000 random inputs.
- ragas 0.4 types evaluate() as EvaluationResult | Executor; checked
rather than cast, so a future default change says so.
Two bugs found while doing it:
- AgentGraph.__del__ read self.pool, which does not exist when
__init__ raised part way through. A chromadb startup error therefore
surfaced as "AttributeError: 'AgentGraph' object has no attribute
'pool'" while the real cause went unprinted.
- test_the_vector_side_makes_no_llm_call asserted on the literal string
"from langchain.retrievers.self_query". Under 1.x that path is
langchain_classic.retrievers.self_query, so the test would have gone
green while the thing it guards was reintroduced. It now matches
import lines on the module tail.
src/evaluation/test_generator.py is deleted. It targeted the ragas 0.1
API -- from_langchain(generator_llm=, critic_llm=),
generate_with_langchain_docs(test_size=, distributions=) -- none of
which exists in 0.4, its own TODO had said so since 0.2, and nothing
imported it. It had not run for three major versions.
Measured, not assumed: bin/retrieval_baseline before and after over 20
questions x 4 collections x 2 retrievers shows 2/160 results changed,
both adjacent transpositions on the vector side, which is the run-to-run
ANN variance the harness already documents (plain vector is
byte-identical on 78/80 between two identical runs). BM25 is unchanged.
The chainlit app imports and registers its hooks; the chain answers a
real question through both invoke and ainvoke.
CI could not import langchain_classic; locally everything passed. The package was in my virtualenv as a leftover from langchain-community 0.4, which was installed for a few minutes while working out that ragas could not tolerate it. `poetry install` does not prune, so it stayed -- and made code that imports langchain_classic directly look fine against a lock that never contained it. Both packages are imported by name here (rag_chain and the metadata_info modules; RecursiveCharacterTextSplitter in data_generation), so both are now direct dependencies. Declaring what you import is right regardless of how it used to arrive. Verified against a virtualenv synced to the lock with --sync, which removed twelve stale packages, including the two this commit adds back deliberately. Gates, the CI import check and the real chain all pass on that clean tree.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
The upgrade the retriever rewrite existed to unblock. 69 advisories → 44; the whole LangChain family is now clean.
Three things did NOT move
chromadb stays below 1.0 (and
langchain-chromaat 0.2.x with it).langchain-chroma1.x requireschromadb>=1.3.5, and chromadb 1.x opens a 0.5/0.6 bundle by migrating its sqlite in place (sysdb 9 → 10) — which needs write access. Installed bundles are root-owned755, so running as a normal user gives, before a single question:That is a deliberate operational step — chown every bundle on every host — not something to slip into a dependency upgrade. The migration itself is sound: I verified chromadb 1.5.9 reads a 0.6-written bundle, and that 0.6.3 still reads it afterwards, so a rollback does not strand data. Whenever you want it, it is a one-line change plus a chown.
langchain-community stays at 0.3.31. 0.4 drops
langchain_community.chat_models.vertexai, which ragas 0.4.3 still imports unconditionally — so 0.4 makesimport ragasfail and takes./bin/evaluatewith it. ragas declares langchain-community with no version bound, so the resolver cannot see the conflict; only importing can.torch and transformers stay as they were, per #194.
Code the upgrade forced
langchain.chains.*→ langchain-classic, their supported home rather than a shim. Rewriting the RAG chain as LCEL is a behaviour change and does not belong here.langgraph.utils.runnable.RunnableLikeis gone, and langgraph 1.0 matches nodes structurally on the parameter namestate. The node contract is now a Protocol here, andno_search’s parameter is named rather than_.EnsembleRetrievernow validateslen(weights) == len(retrievers), so the empty-ensemble trick used to reachweighted_reciprocal_rankraises. That trick was removed from the pipeline by the rewrite and survived only in the test comparing against it — the upgrade breaking it is the argument for the rewrite, restated. The vendored RRF still matches LangChain 1.x exactly over 2000 random inputs.Two bugs found while doing it
AgentGraph.__del__readself.pool, which does not exist when__init__raised part way through. A chromadb startup error therefore surfaced asAttributeError: 'AgentGraph' object has no attribute 'pool'while the real cause went unprinted.test_the_vector_side_makes_no_llm_callasserted on the literal string"from langchain.retrievers.self_query". Under 1.x that path islangchain_classic.retrievers.self_query— the test would have gone green while the thing it guards was reintroduced.Deleted:
src/evaluation/test_generator.pyIt targeted the ragas 0.1 API —
from_langchain(generator_llm=, critic_llm=),generate_with_langchain_docs(test_size=, distributions=)— none of which exists in 0.4. Its own TODO had said so since 0.2, and nothing imported it. It had not run for three major versions. Recoverable from git; the README says what rebuilding it would be for.Measured, not assumed
bin/retrieval_baselinebefore and after, 20 questions × 4 collections × 2 retrievers:Both are adjacent transpositions on the vector side — the run-to-run ANN variance the harness already documents (plain vector is byte-identical on 78/80 between two identical runs). BM25 is unchanged.
Plus: the chainlit app imports and registers its hooks, and the chain answers a real question through both
invokeandainvoke. 187 tests pass.