VisvoAI Docs

Migrating from LangChain

Incremental adoption — nothing to rewrite on day one

visvoai-core sits directly on LangGraph/LangChain primitives rather than replacing them, so adopting it from an existing LangChain/LangGraph codebase is incremental by construction.

What passes through unchanged

  • Your @tool functions and StructuredTools. as_tool recognizes any isinstance(obj, BaseTool) and returns it untouched — see Defining tools. Drop your existing tool list straight into core_tools=[...].
  • Any BaseChatModel you already construct. build_graph's model argument is typed to BaseChatModel — a ChatOpenAI(), ChatAnthropic(), or anything else you built by hand works exactly as it did in a raw LangGraph app. visvoai-ai is optional, not a requirement.
  • The compiled graph itself. build_graph returns a standard LangGraph CompiledStateGraph.invoke, .ainvoke, .stream, .astream_events(version="v2") all behave exactly as LangGraph documents. Any code you've written against astream_events output shapes keeps working.
  • Any checkpointer. checkpointer= accepts any BaseCheckpointSaverMemorySaver, a Postgres/SQLite checkpointer, whatever you already use.

What you get by switching the loop

Migrate the loop first, keep your tools as-is:

# before: your own StateGraph wiring an agent node + a ToolNode
# after:
from visvoai.core.runtime import AgentRuntime

graph = AgentRuntime().build_graph(
    model=your_existing_model,
    core_tools=your_existing_tools,          # unchanged
    system_prompt=your_existing_prompt,
    checkpointer=your_existing_checkpointer, # unchanged
)

This alone buys you the soft step cap (no more GraphRecursionError crashing a user-facing turn) without touching a single tool definition.

Then, at your own pace: simplify tools

Once the loop is migrated, tools written as verbose StructuredTool boilerplate can be simplified to plain functions — type hints become the schema, the docstring becomes the description, no LangChain imports in the file at all (see Defining tools). Or move a tool that wants config/persistence to BaseAgentTool if it needs the lifecycle hooks. Nothing forces this; both StructuredTool and plain functions coexist forever in the same core_tools list.

What doesn't carry over

Anything from the LangChain "batteries" ecosystem that isn't a BaseChatModel or a BaseTool — document loaders, retrievers, chains, memory abstractions beyond a BaseCheckpointSaver — is out of scope for visvoai-core entirely; it's a loop, not a framework. Keep using LangChain directly for those and hand the results to your tools as plain Python. See When not to use this if that describes most of what you need.

Next: When not to use this.

On this page