DeepSeek V4 Function Calling: Structured Output Without the Pain
Function calling is how LLMs stop chatting and start working — parsing input, calling tools, returning structured JSON. And with DeepSeek V4, it's also cheap enough to run at scale.
Here's how to build reliable tool-use flows with DeepSeek V4, with real code.
Why Function Calling Matters
Raw chat output is a string. Production systems need structure. Function calling gives you:
- Structured JSON — no regex parsing of prose
- Tool orchestration — the model decides what to call
- Agent loops — multi-step workflows with state
DeepSeek V4 supports the OpenAI tool-calling format, so everything below works with the standard openai SDK — just point base_url at https://tokenpapa.ai/v1.
Step 1 — Define Your Tools
from openai import OpenAI
client = OpenAI(base_url="https://tokenpapa.ai/v1", api_key="your-key")
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
}
}]
Step 2 — Call and Handle the Tool
resp = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[{"role": "user", "content": "What's the weather in Shanghai?"}],
tools=tools,
tool_choice="auto",
)
msg = resp.choices[0].message
if msg.tool_calls: # model wants to call a tool
call = msg.tool_calls[0].function
print("calling:", call.name, call.arguments) # arguments = valid JSON
result = get_weather(**json.loads(call.arguments))
# feed result back and continue
resp2 = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[
{"role": "user", "content": "What's the weather in Shanghai?"},
msg,
{"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)},
],
tools=tools,
)
print(resp2.choices[0].message.content)
else:
print(msg.content)
Step 3 — Reliable JSON Without Tools (JSON Mode)
For simple structured output you can also force JSON with a prompt contract:
resp = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[
{"role": "system", "content": "Output ONLY valid JSON with keys: title, summary, tags."},
{"role": "user", "content": "Summarize this article."},
],
response_format={"type": "json_object"}, # OpenAI-compatible
)
data = json.loads(resp.choices[0].message.content)
Cost Control for Agent Loops
| Cost lever | How much it saves |
|---|---|
| DeepSeek V4 Flash base price | $0.14/1M in — already 100x cheaper than frontier |
| Context caching | Repeat tool definitions cached — up to ~90% off repeat input |
| Shorten tool descriptions | Trim schema docs; fewer tokens every loop |
Cap max_tokens |
A runaway tool response costs 20x a normal one |
| Batch tool calls | Ask for multiple calls in one turn where possible |
A typical 5-turn agent session on DeepSeek V4 Flash costs well under $0.01 — cheap enough for interactive products.
Common Pitfalls
-
Forgetting the tool result round-trip — the model needs the
role: "tool"message or it loses context. - Huge tool schemas — every token in the schema is paid on every call. Keep descriptions tight.
-
No fallback for parse failures — wrap
json.loadsin try/except; retry with a clearer prompt. - Ignoring cache hits — repeated identical tool definitions are cached automatically; don't vary them per request.
FAQ
Q: Does DeepSeek V4 support function calling?
A: Yes — OpenAI-style tool calling, reliable structured JSON for agents.
Q: How do I get structured JSON from DeepSeek V4?
A: Use the tools parameter or response_format: {"type": "json_object"} — OpenAI-compatible, works via TokenPAPA's endpoint.
Q: Is function calling expensive?
A: No — $0.14/1M in, $0.42/1M out. Even multi-turn agent loops stay under $0.01.
Q: Can I build agents with DeepSeek V4?
A: Yes — 82.7 on Terminal Bench 2.1 makes it a strong budget agent backbone.
Get Started
- Sign up at tokenpapa.ai — get $1 free credit
- Create your API key — OpenAI-compatible
- Build your first tool call — code above, live
from openai import OpenAI
client = OpenAI(base_url="https://tokenpapa.ai/v1", api_key="your-key")
resp = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[{"role": "user", "content": "Extract the city from: I live in Beijing."}],
tools=tools,
)
print(resp.choices[0].message.tool_calls[0].function.arguments)
Originally published at https://doc.tokenpapa.ai/en/docs/blog/deepseek-v4-function-calling.
Top comments (0)