Function Calling 实战:让 LLM 学会调用工具

Function Calling(现在 OpenAI 叫 Tool Use)是让 LLM 从"聊天机器人"变成"能干活的 Agent"的关键能力。 核心原理 Function Calling 的本质是:你告诉模型"你可以调用这些函数",模型在需要时会输出一个结构化的"我要调用 X 函数,参数是 Y",然后由你的代码真正去执行这个函数,把结果再传给模型。 模型本身不执行任何代码,它只负责"决策"。 最简示例 from openai import OpenAI import json client = OpenAI() # 定义工具 tools = [ { "type": "function", "function": { "name": "get_weather", "description": "获取指定城市的天气", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,如:北京、上海" } }, "required": ["city"] } } } ] # 实际的工具函数 def get_weather(city: str) -> str: # 这里接真实天气 API return f"{city}今天晴,25°C" messages = [{"role": "user", "content": "北京今天天气怎么样?"}] response = client.chat.completions.create( model="gpt-4o", messages=messages, tools=tools, tool_choice="auto" ) # 判断是否要调用工具 message = response.choices[0].message if message.tool_calls: tool_call = message.tool_calls[0] args = json.loads(tool_call.function.arguments) # 执行工具 result = get_weather(**args) # 把结果传回给模型 messages.append(message) messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": result }) final_response = client.chat.completions.create( model="gpt-4o", messages=messages ) print(final_response.choices[0].message.content) 多工具调度 模型可以在一次回复里调用多个工具(parallel tool calling): ...

2024-02-20 · 1 min · Kada Liao

Embedding 模型选型:OpenAI vs BGE vs 其他开源方案

在做 RAG 系统时,Embedding 模型的选型是个绕不过去的问题。选错了,后面调再多参数也是事倍功半。 什么是 Embedding Embedding 模型把文本转成高维向量,语义相近的文本在向量空间里距离更近。RAG 的检索质量,本质上取决于 Embedding 模型对语义的理解能力。 OpenAI text-embedding 系列 from openai import OpenAI client = OpenAI() response = client.embeddings.create( model="text-embedding-3-small", # 或 text-embedding-3-large input="什么是 RAG 系统?" ) vector = response.data[0].embedding # 1536 维向量 text-embedding-3-small: 维度:1536 价格:$0.02 / 1M tokens 性价比最高,大多数场景足够用 text-embedding-3-large: 维度:3072 价格:$0.13 / 1M tokens 效果更好,但贵 6 倍,仅在对检索质量要求极高时考虑 优点:接口简单,效果稳定,中英文都好。 缺点:按量计费,数据需要发到 OpenAI,有隐私顾虑。 BGE 系列(智源) BGE(BAAI General Embedding)是智源研究院开源的中文 Embedding 模型,中文效果出色: from FlagEmbedding import FlagModel model = FlagModel( "BAAI/bge-large-zh-v1.5", query_instruction_for_retrieval="为这个句子生成表示以用于检索相关文章:", use_fp16=True ) # 对查询加 instruction(重要!BGE 的查询和文档编码方式不同) query_embedding = model.encode_queries(["什么是 RAG?"]) # 文档不需要 instruction doc_embeddings = model.encode(["RAG 是检索增强生成..."]) BGE-large-zh-v1.5: ...

2023-06-12 · 1 min · Kada Liao

OpenAI API 初体验:ChatGPT 背后的接口是什么样的

2022 年 11 月底,ChatGPT 上线,刷屏了所有技术圈的朋友圈。作为工程师,第一反应自然是——这东西能怎么用在项目里? 基础概念 OpenAI 的核心接口是 Chat Completions API,接受一个消息列表,返回模型的回复。 from openai import OpenAI client = OpenAI(api_key="your-api-key") response = client.chat.completions.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": "你是一个 Python 专家"}, {"role": "user", "content": "解释一下 Python 的 GIL"} ] ) print(response.choices[0].message.content) 消息列表里有三种角色: system:给模型设定人格和行为准则 user:用户输入 assistant:模型历史回复(多轮对话时需要带上) Token 是什么 模型按 token 计费,而不是按字符。英文大约 4 个字符 = 1 token,中文大约 1-2 个字符 = 1 token。 # 用 tiktoken 计算 token 数 import tiktoken enc = tiktoken.encoding_for_model("gpt-3.5-turbo") tokens = enc.encode("Hello, world!") print(len(tokens)) # 4 max_tokens 控制回复的最大长度,temperature 控制随机性(0 最确定,2 最随机)。 多轮对话的实现 模型本身是无状态的,多轮对话需要客户端维护历史消息: history = [] def chat(user_input): history.append({"role": "user", "content": user_input}) response = client.chat.completions.create( model="gpt-3.5-turbo", messages=history ) reply = response.choices[0].message.content history.append({"role": "assistant", "content": reply}) return reply 历史越长,消耗的 token 越多,成本越高。实际项目里需要做历史截断或摘要。 ...

2022-12-10 · 1 min · Kada Liao