必须接入地理坐标解析与距离计算能力并结构化注入提示词,否则AI Agent仅能返回泛化响应;需准备含门店名称、地址、经纬度(十进制)的CSV,上传时启用向量化并按行分割;配置HTTP工具get_user_location获取IP定位,响应JSON须含严格命名的latitude和longitude字段;再通过Python工具calculate_distance或SQL预计算实现Haversine距离排序。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

要让Dify中的AI Agent能根据用户当前地理位置,实时推荐附近门店,必须先在后端服务中接入地理坐标解析与距离计算能力,再将结果结构化注入提示词上下文,否则Agent只能返回“请提供位置”这类泛化响应。
准备带经纬度的门店数据源
从门店管理系统导出CSV文件,字段必须包含:门店名称、地址、经度(longitude)、纬度(latitude),缺一不可。经度纬度必须为十进制数值格式(如116.4809, 39.9896),不能是“东经116°28′”这类字符串——Dify不支持自动地理编码转换。
将CSV上传至Dify知识库时,勾选【启用向量化】并选择【按行分割】,确保每家门店作为独立chunk被索引。这一步不做,后续检索会把所有门店混成一团,无法做距离排序。
配置自定义工具获取用户实时位置
在Dify工作区→Agent→工具→+添加工具,选择【HTTP请求】类型。
填写工具名称为“get_user_location”,描述写“获取调用方IP对应的城市级地理位置及粗略经纬度”,URL填你已部署的定位接口,例如https://api.yourservice.com/v1/location?ip={ip}。注意:该接口必须支持跨域(CORS),否则前端调用会失败。
参数设置中,将ip设为“从上下文提取”,变量名填user_ip;响应体需返回JSON,且必须含latitude和longitude字段,字段名大小写必须完全匹配——Dify工具解析器严格区分大小写,写成lat或Lng会导致坐标为空。
构建地理距离排序逻辑链
方法一:用Python代码工具封装Haversine计算
新建工具【calculate_distance】,类型选【Python代码】,粘贴以下代码:
import math
def run(user_lat, user_lng, store_lat, store_lng):
R = 6371
dlat = math.radians(float(store_lat) - float(user_lat))
dlng = math.radians(float(store_lng) - float(user_lng))
a = (math.sin(dlat/2)**2 +
math.cos(math.radians(float(user_lat))) * math.cos(math.radians(float(store_lat))) *
math.sin(dlng/2)**2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
return round(R * c, 1)
这个函数必须命名为run,参数顺序不能颠倒,否则Dify调用时报错missing 1 required positional argument。
方法二:用SQL知识库预计算+过滤
在知识库高级设置中启用【SQL查询】,编写查询语句:SELECT name, address, ROUND(6371 * ACOS(COS(RADIANS({{user_lat}})) * COS(RADIANS(latitude)) * COS(RADIANS(longitude) - RADIANS({{user_lng}})) + SIN(RADIANS({{user_lat}})) * SIN(RADIANS(latitude))), 1) AS distance_km FROM stores WHERE distance_km 。注意:{{user_lat}}和{{user_lng}}必须与工具返回字段名一致,且SQL中不能出现中文别名,否则Dify解析失败。
组装Agent提示词与执行流
第一步:在Agent系统提示词顶部插入变量声明:{{user_location = tools.get_user_location()}}。这行必须放在所有业务逻辑之前,否则后续步骤读不到坐标值。
第二步:在知识库检索指令中加入地理约束,写成:“仅检索与user_location.latitude和user_location.longitude直线距离≤3km的门店,按距离升序返回前3家”。Dify的向量检索本身不支持地理过滤,这句话的作用是引导LLM在召回结果中主动筛除远距离门店——这是绕过技术限制的关键软性控制。
第三步:在最终回复模板中嵌入结构化输出指令:“用Markdown表格返回:| 店铺名 | 地址 | 距离(km) | 营业状态 |”,其中“距离(km)”列必须调用tools.calculate_distance(...)计算得出,不能直接用知识库原始字段——原始数据里的“距离”是静态录入值,不是用户实时位置出发的真实距离。
第四步:保存Agent并点击【调试】,在输入框中手动传入测试参数:{"user_ip": "114.247.112.18"}。如果返回结果里距离全为0或报NoneType错误,说明get_user_location工具返回的JSON缺少latitude字段,需立刻检查后端接口响应体。











