Skip to content

Commit b686595

Browse files
sufubaoshihaobaigemini-code-assist[bot]
authored
add function call and reasoning docs (#1160)
Co-authored-by: shihaobai <[email protected]> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent 59931b0 commit b686595

File tree

6 files changed

+1188
-0
lines changed

6 files changed

+1188
-0
lines changed

docs/CN/source/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ Lightllm 整合了众多的开源方案的优点,包括但不限于 FasterTran
5353
多模态部署 <tutorial/multimodal>
5454
奖励模型部署 <tutorial/reward_model>
5555
OpenAI 接口使用 <tutorial/openai>
56+
工具调用(Function Calling) <tutorial/function_calling>
57+
思考解析(Reasoning Parser) <tutorial/reasoning_parser>
5658
APIServer 参数详解 <tutorial/api_server_args_zh>
5759
lightllm api介绍 <tutorial/api_param>
5860

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
.. _function_calling:
2+
3+
工具调用(Function Calling)
4+
============================
5+
6+
LightLLM 支持多种主流模型的工具调用功能,提供 OpenAI 兼容的 API。
7+
8+
支持的模型
9+
----------
10+
11+
Qwen2.5/Qwen3
12+
~~~~~~~~~~~~~
13+
14+
**解析器**: ``qwen25``
15+
16+
**格式**:
17+
18+
.. code-block:: xml
19+
20+
<tool_call>
21+
{"name": "function_name", "arguments": {"param": "value"}}
22+
</tool_call>
23+
24+
**启动**:
25+
26+
.. code-block:: bash
27+
28+
python -m lightllm.server.api_server \
29+
--model_dir /path/to/qwen2.5 \
30+
--tool_call_parser qwen25 \
31+
--tp 1
32+
33+
Llama 3.2
34+
~~~~~~~~~
35+
36+
**解析器**: ``llama3``
37+
38+
**格式**: ``<|python_tag|>{"name": "func", "arguments": {...}}``
39+
40+
**启动**:
41+
42+
.. code-block:: bash
43+
44+
python -m lightllm.server.api_server \
45+
--model_dir /path/to/llama-3.2 \
46+
--tool_call_parser llama3 \
47+
--tp 1
48+
49+
Mistral
50+
~~~~~~~
51+
52+
**解析器**: ``mistral``
53+
54+
**格式**: ``[TOOL_CALLS] [{"name": "func", "arguments": {...}}, ...]``
55+
56+
DeepSeek-V3
57+
~~~~~~~~~~~
58+
59+
**解析器**: ``deepseekv3``
60+
61+
**格式**:
62+
63+
.. code-block:: xml
64+
65+
<|tool▁calls▁begin|>
66+
<|tool▁call▁begin|>function<|tool▁sep|>func_name
67+
```json
68+
{"param": "value"}
69+
```
70+
<|tool▁call▁end|>
71+
<|tool▁calls▁end|>
72+
73+
DeepSeek-V3.1
74+
~~~~~~~~~~~~~
75+
76+
**解析器**: ``deepseekv31``
77+
78+
**格式**: 简化的 V3 格式,参数直接内联,无代码块包围
79+
80+
基本使用
81+
--------
82+
83+
定义工具
84+
~~~~~~~~
85+
86+
.. code-block:: python
87+
88+
tools = [
89+
{
90+
"type": "function",
91+
"function": {
92+
"name": "get_weather",
93+
"description": "获取指定城市的天气信息",
94+
"parameters": {
95+
"type": "object",
96+
"properties": {
97+
"city": {
98+
"type": "string",
99+
"description": "城市名称"
100+
}
101+
},
102+
"required": ["city"]
103+
}
104+
}
105+
}
106+
]
107+
108+
非流式调用
109+
~~~~~~~~~~
110+
111+
.. code-block:: python
112+
113+
import requests
114+
import json
115+
116+
url = "http://localhost:8088/v1/chat/completions"
117+
data = {
118+
"model": "model_name",
119+
"messages": [
120+
{"role": "user", "content": "北京今天天气怎么样?"}
121+
],
122+
"tools": tools,
123+
"tool_choice": "auto" # "auto" | "none" | "required"
124+
}
125+
126+
response = requests.post(url, json=data).json()
127+
message = response["choices"][0]["message"]
128+
129+
if message.get("tool_calls"):
130+
for tc in message["tool_calls"]:
131+
print(f"工具: {tc['function']['name']}")
132+
print(f"参数: {tc['function']['arguments']}")
133+
134+
流式调用
135+
~~~~~~~~
136+
137+
.. code-block:: python
138+
139+
data = {
140+
"model": "model_name",
141+
"messages": [{"role": "user", "content": "查询北京和上海的天气"}],
142+
"tools": tools,
143+
"stream": True
144+
}
145+
146+
response = requests.post(url, json=data, stream=True)
147+
tool_calls = {}
148+
149+
for line in response.iter_lines():
150+
if line and line.startswith(b"data: "):
151+
chunk = json.loads(line[6:])
152+
delta = chunk["choices"][0]["delta"]
153+
154+
if delta.get("tool_calls"):
155+
for tc in delta["tool_calls"]:
156+
idx = tc.get("index", 0)
157+
if idx not in tool_calls:
158+
tool_calls[idx] = {"function": {"name": "", "arguments": ""}}
159+
160+
if tc["function"].get("name"):
161+
tool_calls[idx]["function"]["name"] = tc["function"]["name"]
162+
if tc["function"].get("arguments"):
163+
tool_calls[idx]["function"]["arguments"] += tc["function"]["arguments"]
164+
165+
多轮对话
166+
~~~~~~~~
167+
168+
.. code-block:: python
169+
170+
# 1. 用户提问
171+
messages = [{"role": "user", "content": "北京天气如何?"}]
172+
173+
# 2. 模型调用工具
174+
response1 = requests.post(url, json={
175+
"messages": messages,
176+
"tools": tools
177+
}).json()
178+
179+
tool_call = response1["choices"][0]["message"]["tool_calls"][0]
180+
messages.append(response1["choices"][0]["message"])
181+
182+
# 3. 返回工具结果
183+
weather_result = {"temperature": 15, "condition": "晴朗"}
184+
messages.append({
185+
"role": "tool",
186+
"tool_call_id": tool_call["id"],
187+
"name": tool_call["function"]["name"],
188+
"content": json.dumps(weather_result, ensure_ascii=False)
189+
})
190+
191+
# 4. 生成最终回答
192+
response2 = requests.post(url, json={"messages": messages}).json()
193+
print(response2["choices"][0]["message"]["content"])
194+
195+
高级功能
196+
--------
197+
198+
并行工具调用
199+
~~~~~~~~~~~~
200+
201+
.. code-block:: python
202+
203+
data = {
204+
"messages": messages,
205+
"tools": tools,
206+
"parallel_tool_calls": True # 启用并行调用
207+
}
208+
209+
强制调用特定工具
210+
~~~~~~~~~~~~~~~~
211+
212+
.. code-block:: python
213+
214+
data = {
215+
"tools": tools,
216+
"tool_choice": {
217+
"type": "function",
218+
"function": {"name": "get_weather"}
219+
}
220+
}
221+
222+
与推理模型集成
223+
~~~~~~~~~~~~~~
224+
225+
.. code-block:: python
226+
227+
data = {
228+
"model": "deepseek-r1",
229+
"tools": tools,
230+
"chat_template_kwargs": {"enable_thinking": True},
231+
"separate_reasoning": True # 分离推理内容
232+
}
233+
234+
response = requests.post(url, json=data).json()
235+
message = response["choices"][0]["message"]
236+
237+
print("推理:", message.get("reasoning_content"))
238+
print("工具调用:", message.get("tool_calls"))
239+
240+
常见问题
241+
--------
242+
243+
**工具调用未触发**
244+
检查 ``--tool_call_parser`` 参数和工具描述是否清晰
245+
246+
**参数解析错误**
247+
确认使用了正确的解析器,检查模型输出格式
248+
249+
**流式模式不完整**
250+
正确处理所有 chunks,使用 ``index`` 字段组装多个工具调用
251+
252+
**与推理模型集成失败**
253+
确保使用最新版本,正确配置 ``separate_reasoning`` 和 ``chat_template_kwargs``
254+
255+
技术细节
256+
--------
257+
258+
**核心文件**:
259+
- ``lightllm/server/function_call_parser.py`` - 解析器实现
260+
- ``lightllm/server/api_openai.py`` - API 集成
261+
- ``lightllm/server/build_prompt.py`` - 工具注入
262+
- ``test/test_api/test_openai_api.py`` - 测试示例
263+
264+
**相关 PR**:
265+
- PR #1158: 支持推理内容中的函数调用
266+
267+
参考资料
268+
--------
269+
270+
- OpenAI Function Calling: https://platform.openai.com/docs/guides/function-calling
271+
- JSON Schema: https://json-schema.org/
272+
- LightLLM GitHub: https://github.com/ModelTC/lightllm

0 commit comments

Comments
 (0)