use init_chat_model To initialize any chat model, use create_agent Build an Agent and use streaming output to display responses in real time.
LangChain’s Module 1 starts with the most basic capabilities:How to call a large language model (LLM)? How to build an Agent that can remember conversations and call tools?
This section (1.1_foundational_models) focuses on the three most basic things:
init_chat_modelUnify model interfaces from different vendorscreate_agentPackage the model into an intelligent agent that can continue to dialogueagent.stream()Let LLM's responses be displayed verbatim like a typewriter, rather than waiting until all are generated before displaying themThis course usesDeepSeekAs primary LLM (also supports Gemini, etc.). DeepSeek provides an interface compatible with the OpenAI API format, so it is used in LangChainmodel_provider="openai"Plus customizationbase_urlYou can access it. This "compatibility layer" design allows you to use the same set of LangChain code to switch models from different manufacturers.
Provided by LangChaininit_chat_modelFunction that unifies the initialization methods of different LLM providers. You just need to pass in the model name, provider identifier, and API key, and you'll get a standard chat model object.
The simplest usage is to directly use the model class officially integrated by LangChain:
from langchain_google_genai import ChatGoogleGenerativeAI
# 直接初始化 Gemini 模型
model = ChatGoogleGenerativeAI(model="gemini-2.5-flash-lite")
# 直接调用:注意这是 model.invoke,不是 agent.invoke
response = model.invoke("What's the capital of the Moon?")
print(response.content)
model.invoke()Call the original model directly and returnAIMessageobject, through.contentGet the text content. andagent.invoke()Returns a dictionary containing the complete message history{"messages": [...]}. The interfaces of the two are different.
One is defined in the notebookdeepseek_model()Factory function encapsulates all DeepSeek related initialization details:
from dotenv import load_dotenv
load_dotenv() # 从 .env 文件加载 DEEPSEEK_API_KEY 等环境变量
import os
from langchain.chat_models import init_chat_model
DEEPSEEK_MODEL = "deepseek-v4-flash"
DEEPSEEK_BASE_URL = "https://api.deepseek.com"
def deepseek_model(model: str = DEEPSEEK_MODEL, max_tokens=200, **kwargs):
return init_chat_model(
model=model,
model_provider="deepseek", # 或 "openai"(DeepSeek 兼容 OpenAI 格式)
max_tokens=max_tokens,
base_url=DEEPSEEK_BASE_URL,
api_key=os.environ["DEEPSEEK_API_KEY"],
**kwargs
)
Initialize the model using a factory function:
model = deepseek_model(temperature=1)
print(model) # 打印模型对象,确认配置
# 直接调用模型(不经过 Agent)
response = model.invoke("what is 1+1?")
print(response.content) # → "The answer is 2."
| parameter | illustrate | Example value |
|---|---|---|
model |
Model ID string | "deepseek-v4-flash" |
model_provider |
LangChain routes to which provider's adapter | "deepseek" / "openai" / "google-genai" |
max_tokens |
Maximum number of output tokens | 200 / 1000 |
temperature |
Output randomness (0=deterministic, 1=most random) | 0 / 1 |
base_url |
Custom API endpoint (for DeepSeek/local models) | "https://api.deepseek.com" |
create_agentIt is a high-level API provided by LangChain, which packages a chat model into a completeLangGraph Agent(The bottom layer is a StateGraph with a checkpointer).
What does Agent have compared to the original model?
messagesList, supporting multiple rounds of dialoguefrom langchain.agents import create_agent
# 最基础的用法:只传入模型
agent = create_agent(model=deepseek_model())
create_agentBuilt a LangGraph under the hoodStateGraph, contains amodelnode (calling LLM) and atoolsNode (which performs tool calls). They are connected by conditional edges: the model output goes to the tools node when a tool is called, otherwise it ends. This is the implementation of the ReAct (Reasoning + Acting) pattern.
Used to call Agentagent.invoke({"messages": [...]}), the input is a containingmessagesA dictionary of keys, messages can be usedHumanMessagePass in object or dictionary format.
from langchain.messages import HumanMessage
agent = create_agent(deepseek_model())
messages = [
{"role": "user", "content": "what is 1+1?"},
{"role": "assistant", "content": "2"},
{"role": "user", "content": "how about times 5?"}
]
response = agent.invoke({"messages": messages})
print(response['messages'][-1].content)
The Agent's response is a dictionary, and the core keys aremessages, which is a message list containing the complete conversation history:
print(len(response['messages'])) # → 4(3 条输入 + 1 条 AI 响应)
for msg in response['messages']:
print(msg.content)
Usually only the last AI message is needed:response['messages'][-1].content. This is the most common value pattern - take the last item in the message list, and then take.contentProperty gets the text content.
use agent.invoke()You need to wait until all models are generated before you can see the results.agent.stream()Then let the model push it immediately every time it generates a token to achieve the "typewriter effect" - which is a much better experience in UI interaction and long response scenarios.
messages = [{"role": "user", "content": "Tell me all about Luna City, the capital of the Moon"}]
for token, metadata in agent.stream(
{"messages": messages},
stream_mode="messages" # 关键:按消息/token 流式推送
):
if token.content: # 过滤空 token(工具调用消息没有 content)
print(token.content, end="", flush=True) # 不换行,实时打印
| stream_mode | Push timing | Suitable for the scene |
|---|---|---|
"messages" |
Push every time a token/message fragment is generated | UI typewriter effect, real-time response display |
"values" |
Push the complete State every time a LangGraph node is completed | Monitor Agent internal step status |
"updates" |
Push the State changes of each node after completion | Debug node output |
In a streaming loop,agent.stream()Return at the same timetoken(message content) andmetadata(execution metadata).metadataContains LangGraph internal runtime information, useful for debugging and tracing.
for token, metadata in agent.stream(
{"messages": messages},
stream_mode="messages"
):
# 第一个 token 时打印 metadata
print(metadata)
break
| Field | meaning |
|---|---|
langgraph_step |
The current step of LangGraph execution (starting from 1) |
langgraph_node |
The name of the currently executing node (e.g.'model'or'tools') |
langgraph_triggers |
The source that triggered the execution of the current node (edge/event name) |
ls_provider |
Actual LLM providers used |
ls_model_name |
The actual model ID used |
In a production environment, metadata is commonly used for: ① logging and monitoring (tracking which model is used for each call); ② debugging (checking which node the Agent executes to have problems); ③ billing analysis (throughls_model_nameStatistics of usage of each model).
from dotenv import load_dotenv
load_dotenv()
import os
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
from langchain.messages import HumanMessage
# 1. 初始化模型
def deepseek_model(**kwargs):
return init_chat_model(
model="deepseek-v4-flash",
model_provider="deepseek",
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com",
max_tokens=500,
**kwargs
)
# 2. 构建 Agent
agent = create_agent(deepseek_model())
# 3. 同步调用
response = agent.invoke({"messages": [HumanMessage(content="Hello!")]})
print(response['messages'][-1].content)
# 4. 流式调用
for token, _ in agent.stream(
{"messages": [{"role": "user", "content": "Tell me a joke"}]},
stream_mode="messages"
):
if token.content:
print(token.content, end="", flush=True)
model_providerSpecify adapterinvoke: Wait for a complete response and return the message liststream: Push token by token, typewriter effecttoken.contentFilter empty messagesresponse['messages']: Complete message historyresponse['messages'][-1].content:AI latest reply