本文为《React Agent:从零开始构建 AI 智能体》专栏系列文章。 专栏地址:https://blog.csdn.net/suiyingy/category_12933485.html。项目地址:https://gitee.com/fgai/react-agent(含完整代码示例与实战源)。完整介绍:https://blog.csdn.net/suiyingy/article/details/146983582。
1 接口参数
大多数大模型提供了 API 接口,用户可以通过发送 HTTP 请求来调用大模型的服务。例如,OpenAI 的 GPT 模型提供了 API 接口,用户可以通过向指定的 URL 发送 JSON 格式的请求,包含输入的提示和相关参数,获取模型生成的输出。对于一些开源的大模型或经过本地化训练的模型,可以将其部署在本地服务器或设备上,通过本地的函数调用或接口来使用模型的功能。这种方式适用于对数据隐私和安全性要求较高的场景,以及网络条件不佳的环境。
OpenAI 模型是大模型领域的早期引领者,后续其他大模型接口几乎都与其兼容。在大模型应用开发中,熟练掌握 OpenAI 对话接口chat completion的参数配置是实现精准交互的关键。该接口不仅是 OpenAI 模型的核心交互入口,更是众多兼容大模型(如 通义千问、火山大模型、腾讯大模型、Anthropic Claude、Google Gemini 等)的通用接口标准,其参数体系覆盖了模型选择、对话构建、生成控制、工具调用等核心功能模块。合理配置这些参数,能够灵活控制输出的风格、长度、创造性,并实现与外部工具的联动,从而满足从精确问答到复杂任务处理的多样化需求。
对话接口请求地址为https://api.openai.com/v1/chat/completions,采用 POST 请求方法,通过请求头 Authorization: Bearer YOUR_API_KEY 提供 API 密钥进行认证;其核心功能是基于对话历史生成回复,支持多轮对话、系统指令(如角色设定)、用户输入和助手历史回复,且兼容大多数遵循 OpenAI 接口规范的大模型。
POST https://api.openai.com/v1/chat/completions
以下为 Python 程序基本调用方式,需要使用 pip install openai 安装库。
import openai
base_url = '<接口地址>'
api_key = '<密钥>'
client = openai.OpenAI(
api_key=api_key,
base_url=base_url,
)
messages = [
{
"role": "user",
"content": "天气?"
}
]
response = client.chat.completions.create(
# 模型名称,使用支持函数调用的版本
model="gpt",
# 对话消息列表
messages=messages,
# 定义可调用的函数列表
# functions=functions,
# 控制函数调用方式,auto 表示让模型自主决定
function_call="auto",
# 生成结果的随机性,0 表示确定性最高,2 表示随机性最高
temperature=0.7,
# 另一种控制随机性的方式,与 temperature 二选一
top_p=0.9,
# 生成的回复数量
n=1,
# 是否使用流式响应
stream=False,
# 停止生成的字符串列表
stop=["###"],
# 生成的最大令牌数
max_tokens=200,
# 惩罚新出现的话题,鼓励讨论新内容
presence_penalty=0.1,
# 惩罚高频出现的令牌,减少重复用词
frequency_penalty=0.1,
# 对特定令牌的生成概率进行偏置
logit_bias={"100257": -100},
# 标识用户身份
user="user_123"
)
print(response.choices[0].message.content)
(1)base_url
base_url 是用于指定 API 服务的基础接口地址,在代码中作为 openai.OpenAI 客户端实例化时的参数之一,用于明确客户端应连接的目标服务器端点(如自定义的 API 服务地址或特定环境的接口路径),确保请求能够正确发送至对应的服务端接口进行处理。通过改变base_url可以连接不同服务商的API接口。
OpenAI 接口:https://api.openai.com/v1
通义千问接口:https://dashscope.aliyuncs.com/compatible-mode/v1
(2)api_key
api_key 是用于验证访问权限的密钥,作为 openai.OpenAI 客户端初始化时的关键认证参数,其作用是证明调用方拥有合法访问 API 服务的权限,避免未授权的请求被处理。该密钥需妥善保管,通常由服务提供商(如 OpenAI)发放,在代码中通过显式赋值的方式传递给客户端,以完成身份验证流程。大部分服务商对新用户都提供免费的 API 调用额度,可直接在各自官网申请 api_key 以获得调用权限。
(3)model
model 参数用于指定调用的模型版本,是接口请求的基础配置,需根据任务需求选择性价比或性能优先的模型,例如默认的 gpt-3.5-turbo适用于大多数场景,而 gpt-4 系列则适合逻辑复杂或需要长上下文的任务,第三方兼容模型需按服务商文档填写特定标识(如千问的qwen-plus)。下面是阿里的可用模型页面。
图1 阿里模型广场
(4)messages
messages参数构建对话历史,通过system(设定助手角色)、user(用户输入)、assistant(历史回复)三类角色的内容数组,实现多轮对话的上下文传递,需注意总令牌数不能超过模型最大限制(字数)(如gpt-3.5-turbo为 4096 tokens)。
以“天气查询”场景为例,展示 3 轮对话的 messages 结构。第 1 轮:system设定助手定位,user首次提问。第 2 轮:assistant存储历史回复,用于后续上下文关联。第 3 轮:用户简化提问,模型根据历史信息推断“查询广州天气”。
[
{
"role": "system",
"content": "你是一个专注于天气查询的助手,回答需简洁准确,仅提供城市名称和天气信息(如:北京,晴,25℃)。"
},
{
"role": "user",
"content": "今天上海的天气如何?"
},
{
"role": "assistant",
"content": "上海,多云,28℃"
},
{
"role": "user",
"content": "那广州呢?" // 用户省略“天气”,模型通过历史对话理解意图
}
]
Token(令牌)是模型处理文本时的最小单位,可理解为 “分词单元”,其拆分方式因语言而异,如英文常按空格或子词(如 unhappiness 拆分为 un 与 happiness),中文多按字或词(如天气通常为 1 个 Token),且空格、标点等特殊符号也会占用 Token。它与字数并非完全对等,中文里 1 个汉字约对应 1 个 Token,英文单词可能拆分为 1-3 个 Token。模型存在最大 Token 数限制(如 gpt-3.5-turbo 为 4096 Tokens),包含system、user、assistant的所有内容(包括标点、空格),超出会导致报错。另一方面,Token 数直接影响 API 调用成本(按 Token 计费),合理管理 Token 使用可避免超限错误并控制费用。
(5)temperature、top_p、n
生成控制类参数中,temperature和top_p共同调节输出的随机性,前者通过浮点值(0-2)控制创造性,0 为完全确定、1 为平衡模式、2 为高度随机,一般设置为 0.7 左右;后者通过核采样机制(0-1)限制令牌选择范围,两者建议二选一以避免效果冲突。n参数支持生成多个独立回复(最多 10 个),适用于需要多样化答案的场景,如创意头脑风暴。
(6)stream
stream 参数启用流式响应,当取值为 true 时逐令牌返回结果,适合实时交互的聊天界面开发。当取值为 false 时,结果将以非流式形式返回,即等待全部内容生成结束之后返回。假设生成结果中包括 2000 个字,每秒生成 20 个字,那么流式输出将类似打字机的方式实时展示。非流式输出则需要等待 100 秒后才会一次性获得全部结果。
(7)stop
stop 参数通过指定字符串(最多 4 个)强制终止生成,常用于客服对话中截断重复内容。该参数通常不需要设置。
(8)max_tokens
max_tokens则限制单次生成的最大令牌数,需结合输入令牌数计算,避免超过模型上下文上限。早期它包括输入和输出令牌总数。现在有许多模型仅包括输出令牌数量,并且输入和输出的限制不同。例如,模型可能输入令牌数限制上限为 32k,而输出令牌数限制上限为 8k。
(9)presence_penalty、frequency_penalty
presence_penalty和frequency_penalty分别对新出现话题和高频词汇进行概率调整,前者鼓励探索新内容(正数)或重复历史(负数),后者减少(正数)或允许(负数)词汇重复,适用于需要控制内容新颖度或避免冗长的场景。二者取值范围均为 -2 ~ 2,且默认取值为0。
(10)logit_bias
logit_bias 通过令牌 ID 的偏置值(-100 到 100)精细调整特定词汇的生成概率,需借助 tokenizer 工具获取目标词汇的 ID,实现对输出内容的精准干预。
(11)user
user 参数用于标识用户身份,辅助服务商进行使用分析和速率限制分组,在多用户系统中区分不同请求来源。一般不需要设置。
(12)functions
在函数工具调用方面,functions(tools) 参数是实现模型与外部工具联动的关键,适用于需要获取实时数据或执行特定计算的场景。工具介绍请参考上一节介绍。该参数为数组结构,每个元素定义工具的 name(工具名称)、parameters(参数)及 description(功能说明)。
function_call(tool_choice)参数则控制模型是否使用工具,可设置为auto(默认,模型自主决定)或显式指定工具名称及参数,当模型需要调用工具时,响应中的finish_reason会标识为function_call,开发者需解析返回的工具调用信息,获取结果后再构造新的对话消息继续交互。例如,用户询问 “北京明天的天气”,模型会通过functions参数调用天气 API,获取数据后再生成回复。
下面分别定义 1 个查询当前日期和 1 个查询天气的工具。
self.tool_definitions = [
{
'type': 'function',
'function': {
'name': 'get_current_date',
'description': '获取当前系统日期',
'parameters': {'type': 'object', 'properties': {}}
}
},
{
'type': 'function',
'function': {
'name': 'get_weather',
'description': '查询指定地点的实时天气',
'parameters': {
'type': 'object',
'properties': {
'location': {
'type': 'string',
'description': '城市名称,如:北京、上海'
}
},
'required': ['location']
}
}
}
]
示例中查询当前时间的函数名称为“get_current_date”,parameters 的properties 为空表明该函数没有参数。如果提示词设置为“今天”,那么将返回如下内容。
直接返回结果:
ChatCompletion(id='chatcmpl-4ea10447-dcda-9d22-8910-1226aa355e3b', choices=[Choice(finish_reason='tool_calls', index=0, logprobs=None, message=ChatCompletionMessage(content='', refusal=None, role='assistant', audio=None, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_4092e6763fc04df7953898', function=Function(arguments='{}', name='get_current_date'), type='function', index=0)]))], created=1745593824, model='qwen-turbo-latest', object='chat.completion', service_tier=None, system_fingerprint=None, usage=CompletionUsage(completion_tokens=13, prompt_tokens=212, total_tokens=225, completion_tokens_details=None, prompt_tokens_details=None))
提取 tool_calls 字段
[ChatCompletionMessageToolCall(id='call_4092e6763fc04df7953898', function=Function(arguments='{}', name='get_current_date'), type='function', index=0)]
返回结果 Function(arguments='{}', name='get_current_date') 包括参数与函数名称。当出现这个结果时,程序可以调用 1 个实际执行工具。
def get_current_date():
return datetime.now().strftime('%Y-%m-%d')
示例中查询天气工具的函数名为 get_weather,包含 1 个表示位置的参数 location。如果提示词设置为“广州的天气怎么样?”,那么将返回如下内容。
直接返回结果:
ChatCompletion(id='chatcmpl-55cd4a44-9291-955c-8caf-b22ad2186cce', choices=[Choice(finish_reason='tool_calls', index=0, logprobs=None, message=ChatCompletionMessage(content='', refusal=None, role='assistant', audio=None, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_c74380e2cc594e1d92bdf8', function=Function(arguments='{"location": "广州"}', name='get_weather'), type='function', index=0)]))], created=1745594182, model='qwen-turbo-latest', object='chat.completion', service_tier=None, system_fingerprint=None, usage=CompletionUsage(completion_tokens=17, prompt_tokens=216, total_tokens=233, completion_tokens_details=None, prompt_tokens_details=None))
提取 tool_calls 字段
[ChatCompletionMessageToolCall(id='call_c74380e2cc594e1d92bdf8', function=Function(arguments='{"location": "广州"}', name='get_weather'), type='function', index=0)]
模型成功提取到了函数名称与地点参数。我们可以根据结果调用天气查 API。下面是一个模拟工具接口。
def get_weather(location):
'''天气查询工具实现'''
# 模拟数据
weather_infos = {
'北京': 25,
'上海': 26,
'广州': 27,
'default': 20
}
return {'temp': weather_infos[location]}
完整示例程序如下所示。
import os
import json
import openai
from datetime import datetime, timedelta
from typing import Dict, Optional, List
def text_reply(content, syst='FGAI智能助手'):
model = 'qwen-turbo-latest' # 'gpt-4o-mini'
api_key = '<用户的 API Key>'
base_url = 'xxxx'
client = openai.OpenAI(
api_key=api_key,
base_url=base_url,
)
response = client.chat.completions.create(
model=model,
messages=[
{'role': 'system', 'content': syst},
{'role': 'user', 'content': content}
],
temperature=0.7
)
print(response.choices[0].message.content)
return response.choices
class WeatherAgent:
def __init__(self):
self.tool_definitions = [
{
'type': 'function',
'function': {
'name': 'get_current_date',
'description': '获取当前系统日期',
'parameters': {'type': 'object', 'properties': {}}
}
},
{
'type': 'function',
'function': {
'name': 'get_weather',
'description': '查询指定地点的实时天气',
'parameters': {
'type': 'object',
'properties': {
'location': {
'type': 'string',
'description': '城市名称,如:北京、上海'
}
},
'required': ['location']
}
}
}
]
def _call_tool(self, tool_name, parameters):
'''工具执行分发'''
if tool_name == 'get_current_date':
return datetime.now().strftime('%Y-%m-%d')
elif tool_name == 'get_weather':
return self._get_weather(parameters.get('location', 'default'))
return None
def _get_weather(self, location):
'''天气查询工具实现'''
# 模拟数据
weather_infos = {
'北京': 25,
'上海': 26,
'广州': 27,
'default': 20
}
return {'temp': weather_infos[location]}
def process_query(self, user_input):
'''完整的处理流程'''
# 第一步:调用大模型进行工具选择
api_key = '<用户的 API Key>'
base_url = 'https://dashscope.aliyuncs.com/compatible-mode/v1'
client = openai.OpenAI(
api_key=api_key,
base_url=base_url,
)
response = client.chat.completions.create(
model='qwen-turbo-latest',
messages=[{'role': 'user', 'content': user_input}],
tools=self.tool_definitions,
tool_choice='auto'
)
print('response: ', response)
tool_calls = response.choices[0].message.tool_calls # None
print('意图工具列表:', tool_calls)
if not tool_calls:
return '抱歉,我暂时无法处理这个请求'
results = []
for tool_call in tool_calls:
tool_name = tool_call.function.name
parameters = json.loads(tool_call.function.arguments)
print('工具名称与参数:', tool_name, parameters)
result = self._call_tool(tool_name, parameters)
results.append({
'tool_name': tool_name,
'content': result
})
return results
# 测试多轮对话
if __name__ == '__main__':
agent = WeatherAgent()
query = '广州的天气怎么样?'
# query = '今天'
response = agent.process_query(query)
print(f'返回结果:{response}')
运行结果如下:
意图工具列表: [ChatCompletionMessageToolCall(id='call_d12ee5d6cf8e4bc0ad4654', function=Function(arguments='{"location": "广州"}', name='get_weather'), type='function', index=0)]
工具名称与参数: get_weather {'location': '广州'}
返回结果:[{'tool_name': 'get_weather', 'content': {'temp': 27}}]
2 大模型输出
大模型基本输出如下所示,不包含函数工具调用。
{
"id": "chatcmpl-123",
"object": "chat.completion",
"created": 1677652288,
"model": "gpt-3.5-turbo-0613",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "回复内容"
},
"finish_reason": "stop" // 结束原因:stop(遇到stop参数)、length(达到max_tokens)、function_call(函数调用)
}
],
"usage": {
"prompt_tokens": 100, // 输入tokens数
"completion_tokens": 50, // 输出tokens数
"total_tokens": 150 // 总tokens数(用于计费)
}
}
直接使用 http 方式的普通请求(非流式,单回复)如下,也可使用上文介绍的 openai 库。
import requests
url = "https://api.openai.com/v1/chat/completions"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY"
}
data = {
"model": "gpt-3.5-turbo",
"messages": [
{"role": "user", "content": "请介绍FGAI React Agent."}
],
"temperature": 0.8,
"max_tokens": 200
}
response = requests.post(url, headers=headers, json=data)
print(response.json()["choices"][0]["message"]["content"])
流式响应(实时输出)获取程序如下所示。
response = requests.post(url, headers=headers, json=data, stream=True)
for chunk in response.iter_lines():
if chunk:
chunk_data = chunk.decode().split("data: ")[1]
if chunk_data == "[DONE]":
break
json_data = json.loads(chunk_data)
print(json_data["choices"][0]["delta"].get("content", ""), end="", flush=True)
立即关注获取最新动态
点击订阅《React Agent 开发专栏》,每周获取智能体开发深度教程。项目代码持续更新至React Agent 开源仓库,欢迎 Star 获取实时更新通知!FGAI 人工智能平台:FGAI 人工智能平台 https://www.botaigc.cn/