Building a Local-File Code Agent with LangChain JS and DeepSeek
Cursor, CodeGeeX, and similar tools all run on the same function-calling primitive. Seeing the bare two-invoke loop and the tool_call_id handshake demystifies what those products do under the hood and gives a developer the pattern to wire up any local or remote capability—file writes, shell commands, database queries—without a framework's magic.
A hand-rolled LangChain JS agent uses DeepSeek's V4 Flash model to read local files and produce code explanations. The implementation skips high-level Agent executors and instead walks through the raw two-invoke cycle: the model first decides to call a read_file tool, the tool executes against the local filesystem, and a second model call turns the returned content into a line-by-line analysis.
The code binds a Zod-validated tool to a ChatOpenAI instance pointed at DeepSeek's OpenAI-compatible endpoint. A message array of System, Human, AI, and Tool messages maintains the stateless model's context across the tool-call handoff. The core lesson is that tool_calls arrive as structured JSON with a unique id that must be echoed back in the ToolMessage, or the model loses track of which result belongs to which call.
Common failure modes get direct fixes: a non-zero temperature causes fabricated file contents, a missing tool_call_id breaks context linkage, and serial tool execution can be replaced with Promise.all for parallel speed-ups when multiple tools are invoked at once.
The tutorial's decision to avoid LangChain's AgentExecutor and manually loop through tool_calls exposes the exact JSON contract that every 'magic' coding assistant relies on—a structured instruction with a call id that must round-trip correctly.
DeepSeek's full OpenAI compatibility means the entire LangChain ecosystem of tools, parsers, and callbacks works without a custom adapter, which lowers the switching cost between Chinese and Western model providers to two config lines.
The emphasis on temperature=0 for tool calling is underappreciated in many agent tutorials; a single hallucinated file path or parameter name breaks the whole chain, and the fix is deterministic output, not a better prompt.