Code
LangChain
LangChain’s ChatOpenAI works with nokeep as it is: give it the base URL, your key and a model id. Python and JavaScript both.
Checked 29 October 2026
Install and connect
pip install langchain-openai
export NOKEEP_API_KEY="sk-nokeep-test" # your own key once it connectsimport os
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="deepseek-v4.1-flash-uncensored",
base_url="https://nokeep.ai/v1",
api_key=os.environ["NOKEEP_API_KEY"],
)
reply = llm.invoke("Name three good names for a tavern.")
print(reply.content)
print(reply.usage_metadata)In JavaScript the base URL goes inside configuration, not at the top level. A top-level baseURL is ignored and the call goes to the default host with your nokeep key.
Stream
import os
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="deepseek-v4.1-flash-uncensored",
base_url="https://nokeep.ai/v1",
api_key=os.environ["NOKEEP_API_KEY"],
stream_usage=True, # ask for the token counts in the last chunk
)
full = None
for chunk in llm.stream("Tell me a story in three lines."):
print(chunk.content, end="", flush=True)
full = chunk if full is None else full + chunk
print("\n", full.usage_metadata)In Python, ChatOpenAI asks for usage on a stream only for its default host. Set stream_usage=True to get token counts with a custom base URL. The JavaScript client asks for them on its own. See Streaming.
Tool calling
from langchain_core.tools import tool
@tool
def get_weather(city: str) -> str:
"""Get the weather in a city."""
return f"18°C and clear in {city}"
message = llm.bind_tools([get_weather]).invoke("What's the weather in Lisbon?")
for call in message.tool_calls:
print(call["name"], call["args"])Both models call tools. LangChain agents built on bind_tools work the same way. with_structured_output sends response_format with a JSON schema, which deepseek-v4.1-flash-uncensored takes and GLM drops. Use DeepSeek for structured output. See Tool calls and JSON output.
Thinking and samplers
import os
from langchain_openai import ChatOpenAI
thinker = ChatOpenAI(
model="deepseek-v4.1-flash-uncensored",
base_url="https://nokeep.ai/v1",
api_key=os.environ["NOKEEP_API_KEY"],
reasoning_effort="high",
max_tokens=4000,
extra_body={"min_p": 0.05}, # fields ChatOpenAI has no argument for
)DeepSeek answers at once unless you ask it to think. Give a thinking call room: thinking counts toward max_tokens.
Gotchas
- `reasoning_effort` takes only the model’s own values.
deepseek-v4.1-flash-uncensoredtakesnone,low,high,max;glm-5.3-flash-uncensoredtakeslow,high. Other apps’minimal,mediumandxhighrun at the model’s nearest level (mediumashigh,xhighasmaxwhere the model has it); any other value gets400 invalid_reasoning_effort. See Thinking. - GLM picks its own tools.
glm-5.3-flash-uncensoredtakestool_choiceautoornoneonly. Forcing a tool (required, or naming a function) gets400 unsupported_tool_choice. Use DeepSeek when you need to force one. - Fields a model can’t take are dropped, not refused. The call still answers, and the
x-nokeep-ignoredresponse header names what was left out. GLM keeps onlytools,tool_choiceandreasoning_effort, so itstemperatureandresponse_formatare dropped. See which fields each model takes. - Content parts are text and pictures only.
image_urlparts work ondeepseek-v4.1-flash-uncensored; GLM reads text alone. Audio and file parts (a PDF) get400 unsupported_input. - `n` must be 1. Ask for several replies with several calls.
- Chat completions only. There is no
/v1/responsesand no/v1/embeddings; a framework that defaults to either needs to be pointed at chat completions, and embeddings need another provider.
ChatOpenAI(use_responses_api=True) and the JavaScript useResponsesApi: true call /v1/responses, which nokeep doesn’t have. Leave them off.
Questions
Do I need a LangChain package for nokeep?
No. langchain-openai in Python and @langchain/openai in JavaScript work with any OpenAI-compatible API. Set the base URL to https://nokeep.ai/v1.
Which model should a LangChain agent use?
deepseek-v4.1-flash-uncensored for most agents: it reads pictures, takes every sampler and can be made to call a tool. glm-5.3-flash-uncensored costs less but picks its own tools.