LangChain pioneered the idea of composing LLM calls with tools and memory. The price was code: chains, runnables, callbacks, output parsers, prompt templates, and a layer of glue between every step. Digitorn keeps the composition idea but trades the Python plumbing for a declarative YAML file.
Most LangChain teams hit the same wall. The first agent ships in a notebook, then somebody asks for a webhook, a Slack trigger, a cron job, multi-tenant credentials, and a deploy story. Each of those is a separate library or a custom wrapper. Digitorn ships them as runtime modules so the same agent runs from a CLI, a REST endpoint, a Slack mention, or a 9am cron with no extra code.
Concept by concept
Every LangChain primitive maps to a Digitorn equivalent. Where the mapping is not 1-to-1, the notes call out what changed.
Side-by-side code
Real apps in both stacks. The Digitorn version is what you would commit to a repo, no scaffolding hidden offscreen.
Minimal agent that searches the web and answers
1from langchain.agents import AgentExecutor, create_tool_calling_agent2from langchain_anthropic import ChatAnthropic3from langchain_community.tools import TavilySearchResults4from langchain_core.prompts import ChatPromptTemplate56llm = ChatAnthropic(model="claude-haiku-4-5", api_key=API_KEY)7tools = [TavilySearchResults(max_results=4, api_key=TAVILY_KEY)]89prompt = ChatPromptTemplate.from_messages([10 ("system", "Answer concisely. Cite sources."),11 ("placeholder", "{chat_history}"),12 ("human", "{input}"),13 ("placeholder", "{agent_scratchpad}"),14])1516agent = create_tool_calling_agent(llm, tools, prompt)17executor = AgentExecutor(agent=agent, tools=tools, verbose=True)1819result = executor.invoke({"input": "What shipped in Claude 4.7?"})20print(result["output"])1app:2 app_id: web-helper3 name: "Web helper"45execution:6 mode: conversation78modules:9 web: {}1011agents:12 - id: helper13 modules: [{web: [search, fetch]}]14 brain:15 provider: anthropic16 model: claude-haiku-4-517 credential: anthropic_main18 system_prompt: "Answer concisely. Cite sources."The Python file is 18 lines of imports and wiring before the first useful instruction. The YAML is the instruction. Tools come from the web module, history is automatic, the daemon serves the agent over REST and SSE without extra code.
Agent with Slack trigger and a credential
1# requires: slack-bolt, langchain, your own webhook handler2from slack_bolt import App3from langchain.agents import AgentExecutor, create_tool_calling_agent45slack = App(token=SLACK_BOT_TOKEN)6llm = ChatAnthropic(model="claude-haiku-4-5", api_key=API_KEY)78@slack.event("app_mention")9def handle_mention(event, say):10 text = event["text"]11 result = executor.invoke({"input": text})12 say(result["output"], thread_ts=event["ts"])1314slack.start(port=3000)1execution:2 mode: background3 entry_agent: helper45modules:6 channels:7 config:8 slack:9 bot_token: { credential: slack_bot }10 respond_in_thread: true11 web: {}1213agents:14 - id: helper15 modules: [{web: [search]}, {channels: [slack_post]}]16 brain: { model: claude-haiku-4-5, credential: anthropic_main }Slack wiring is a config block, not a process. No app token in the source, no webhook handler to deploy. The credential is referenced by name, the vault holds the token.
What bites people
Subtle differences that look the same on paper and break on first run. Read these before you start porting.
Conversation history is part of the session, not an object you instantiate. Stop reaching for ConversationBufferMemory equivalents, the runtime already has it.
When a LangChain agent uses a Pydantic output parser, in Digitorn you write the equivalent shape as the tool's response schema. The model is forced into it by the function-calling layer, no string parsing needed.
LangChain streaming requires AsyncCallbackHandler plumbing. In Digitorn the SSE channel streams tokens as they arrive, callers can opt out but rarely should.
- Python-native data pipelines that pre-process inputs before the agent sees them
- Quick experiments inside a Jupyter notebook with custom Python tools
- Integrations with libraries that already speak LangChain Runnable
Install Digitorn and port one of your LangChain agents
# 1. install runtime
curl -sSL https://digitorn.ai/install | sh
# 2. copy the YAML above into a file
mkdir -p ~/.digitorn/apps/from-langchain
# paste the YAML into app.yaml
# 3. deploy and chat
digitorn deploy from-langchain
digitorn dev chat from-langchainWhat is an AI agent? A 2026 guide for engineers
Get the next post in your inbox.
Engineering notes from the Digitorn team. No marketing, no launch announcements, no "10 prompts that will change your life". Just the things we write that we'd want to read.