记录下学习agent应用开发的第七天( Function Calling机制、description) 各位访问大哥能否留一些宝贵建议给小弟没人的话就当个人日常blog今天对RAG的学习暂时告一段落开始学习 Function Calling。RAG主要是向量检索一般搭配知识库使用根据用户提问输出的回答都会基于知识库的内容而Function Calling可以让ai调用外部函数根据用户语义自己决定要调哪个函数然后把函数返回的结果和会话内容加入prompt一起发给模型思考后再输出符合当前语境的回答。为了方便理解我依旧让opencode写了一个demo day7: Function Calling 演示 — 让 AI 决定调用你的 Python 函数 import json import os from pathlib import Path from openai import OpenAI from dotenv import load_dotenv root Path(__file__).parent.parent load_dotenv(root / .env) client OpenAI( api_keyos.getenv(DEEPSEEK_API_KEY), base_urlos.getenv(DEEPSEEK_BASE_URL), ) # # 你写的 Python 函数 — AI 可以调用它们 # def get_weather(city: str) - str: 模拟查天气实际应该调天气 API weather_data { 北京: 晴天25°C, 上海: 多云28°C, 深圳: 雷阵雨30°C, } return weather_data.get(city, f未找到 {city} 的天气数据) def calculator_add(a: float, b: float) - float: return a b def calculator_multiply(a: float, b: float) - float: return a * b # # 工具描述 — 告诉 AI 你可以用哪些函数 # TOOLS [ { type: function, function: { name: get_weather, description: 查询指定城市的天气, parameters: { type: object, properties: { city: { type: string, description: 城市名称例如北京、上海、深圳 } }, required: [city] } } }, { type: function, function: { name: calculator_add, description: 计算两个数字的和, parameters: { type: object, properties: { a: {type: number, description: 第一个数字}, b: {type: number, description: 第二个数字} }, required: [a, b] } } }, { type: function, function: { name: calculator_multiply, description: 计算两个数字的乘积, parameters: { type: object, properties: { a: {type: number, description: 第一个数字}, b: {type: number, description: 第二个数字} }, required: [a, b] } } } ] # # 主程序 # SYSTEM_PROMPT 你是一个有用的助手可以查天气和做计算。用中文回答。 messages [{role: system, content: SYSTEM_PROMPT}] print( * 50) print( Function Calling 演示 (quit 退出)) print( 比如北京天气怎么样 / 3加5等于多少 / 35后再乘以2) print( * 50) while True: user_input input(\n你: ).strip() if not user_input: continue if user_input.lower() in (quit, exit, q): break messages.append({role: user, content: user_input}) # 第一次调用AI 决定要不要调函数 response client.chat.completions.create( modeldeepseek-v3.2, messagesmessages, toolsTOOLS, # ← 告诉 AI 有哪些工具可用 tool_choiceauto, # ← AI 自己决定用不用、用哪个 ) msg response.choices[0].message # 检查 AI 是不是想调函数 if msg.tool_calls: print(f\n[AI 决定调用函数], end) # 处理每个函数调用 for tool_call in msg.tool_calls: func_name tool_call.function.name func_args json.loads(tool_call.function.arguments) print(f\n → {func_name}({func_args})) # 执行对应的 Python 函数 if func_name get_weather: result get_weather(**func_args) elif func_name calculator_add: result calculator_add(**func_args) elif func_name calculator_multiply: result calculator_multiply(**func_args) else: result f未知函数: {func_name} print(f ← 返回结果: {result}) # 把函数调用和结果告诉 AI messages.append({ role: assistant, content: None, tool_calls: [tool_call] }) messages.append({ role: tool, tool_call_id: tool_call.id, content: str(result) }) # 第二次调用AI 根据函数结果生成最终回答 final_response client.chat.completions.create( modeldeepseek-v3.2, messagesmessages, ) print(f\n小码: {final_response.choices[0].message.content}) else: # AI 不需要调函数直接回答 print(f\n小码: {msg.content}) messages.append({role: assistant, content: msg.content or })运行测试结果可以很清楚地看到用户询问时ai会根据问题语义判断是否要调用外部函数。当我询问城市天气、两个数的加法和乘法时ai都会调用对应的函数而不是直接思考从打印信息[AI 决定调用函数]及其它内容可以看出ai确认在调用函数。当询问跟函数无关的问题比如我提问“java的创始人是谁”时 ai根据语义判断找不到代码中的相关函数 就回归正常聊天模式自己思考后回答。TOOLS部分的代码作用是告诉ai在什么情况下调用哪种函数比如要查询天气就会调用“get_weather”函数计算加法就调用“calculator_add”算乘法就调用“calculator_multiply”。一开始我认为ai能精准地调用函数是因为“name”函数名但是我修改函数名后ai仍能正确调用函数name: calculator_add, description: 查询指定城市的天气,name: get_weather, description: 计算两个数字的和,由结果可知改变TOOLS中调用的函数名对ai选取函数进行调用没有影响。在查询相关资料后我才知道影响ai判断的不是函数名name而是下一行的 description描述。在ai的Function Calling机制中description 通常指的是函数/工具的说明文本告诉ai在什么情况下要调用这个函数/工具。但是我把TOOLS中调用的两个函数的函数名调换后其描述就会匹配不上description告诉ai要查天气就调用““calculator_add”函数要算加法就调用“get_weather”函数理论上得到的结果是错误的可ai仍能正确调用函数。在进一步学习后我发现不光函数名下面有 description其传入的参数也有对应的 description如下所示。虽然前面的描述和函数名不匹配但ai根据用户语义和参数 description综合判断出真正要调用的函数是什么。接着把调用后的结果和会话内容作为prompt进行思考根据会话语境输出正常的回答。city: { type: string, description: 城市名称例如北京、上海、深圳 }a: {type: number, description: 第一个数字}, b: {type: number, description: 第二个数字}总结今天入门学习Function Calling它是ai实现动态交互的核心机制。创建的demo中通过让ai自己判断和调用自定义函数来模拟ai从决策到执行的过程。在学习中我发现description描述对ai的判断有很大作用不仅函数名有description参数名也有对应的descriptionai在判断时会综合所有description进行考量来决定要不要调用函数和调用哪个函数不会只看某个单一的description。通过学习今天的内容我对agent应用有了新的理解RAG和Function Calling都可作为实用的组件为agent提供高效便捷的服务。第七天就到这吧。