企业微信 API 二次开发:AI 智能体与外部群业务流闭环

在企业微信外部群的实际 AI 落地场景中,仅仅让大模型做"文本问答"往往只能解决咨询类需求。如果要实现真正的业务闭环(如:在群里直接查订单进度、发起售后工单、查询库存、帮客户预约时间 ),就需要引入大语言模型的 Function Calling(函数调用) 能力。

通过将 AI 的 Tool Use 能力与企业微信 API 深度结合,AI 智能体不仅能"说话",还能作为"业务员"直接调用后端系统完成实际操作。


一、 Function Calling 交互流设计

与普通的对话不同,Function Calling 允许大模型根据用户的自然语言,自主判断是否需要触发某个业务函数,并解析出正确的参数。

text 复制代码
┌─────────────────┐      1. 用户提问      ┌─────────────────┐      2. 带 Tool 定义调用    ┌─────────────────┐
│ 外部群用户提问  │ ────────────────────> │ 二次开发网关接口 │ ─────────────────────────> │ LLM (支持 Function)│
└─────────────────┘                       └─────────────────┘                            └─────────────────┘
         ▲                                         │                                              │
         │ 6. 主动推送结果                          │ 4. 执行本地函数                              │ 3. 返回结构化参数
         │                                         ▼                                              │ (tool_calls)
┌─────────────────┐      5. 回传 Tool 结果  ┌─────────────────┐                            │
│  消息投递服务   │ <──────────────────── │ 业务系统/数据库  │ <────────────────────────────┘
│ (外部群主动推送) │                       │ (CRM/ERP API)   │
└─────────────────┘                       └─────────────────┘
  1. 意图识别:用户在群里输入:"帮我查一下订单号 OR-20260814 的发货进度"。
  2. 函数匹配 :大模型识别出需要调用 get_order_status 函数,并提取出参数 order_id="OR-20260814"
  3. 本地执行:系统执行对应的 Python 函数查询 ERP 数据库。
  4. 二次生成与投递:将数据库返回的查询结果喂给大模型,生成人情味的回答,最终调用企微 API 投递到外部群。

二、 核心 Python 代码实现

以下展示结合 OpenAI Function Calling 与企业微信外部群主动推送 API 的完整闭环代码:

python 复制代码
import json
import requests
from openai import OpenAI

# 1. 基础配置
llm_client = OpenAI(api_key="your_llm_api_key", base_url="https://api.your-llm-provider.com/v1")

API_GATEWAY_URL = "https://api.your-domain.com/v1/group/send_message"
API_TOKEN = "your_secret_access_token"

# 2. 模拟本地业务系统 API 函数
def get_order_status(order_id: str) -> str:
    """模拟查询订单系统"""
    mock_db = {
        "OR-20260814": {"status": "已发货", "carrier": "顺丰速运", "tracking_num": "SF12345678"},
        "OR-20260815": {"status": "打包中", "carrier": "暂无", "tracking_num": "暂无"}
    }
    info = mock_db.get(order_id)
    if info:
        return json.dumps(info, ensure_ascii=False)
    return json.dumps({"error": "未查找到该订单,请核对订单号。"}, ensure_ascii=False)

# 3. 定义大模型可调用的 Tool 工具列表
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_order_status",
            "description": "根据订单号查询客户订单的发货状态与物流信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "order_id": {
                        "type": "string",
                        "description": "客户的订单编号,例如 OR-20260814"
                    }
                },
                "required": ["order_id"]
            }
        }
    }
]

def handle_agent_workflow(chat_id: str, sender_id: str, user_prompt: str):
    """处理 Agent 函数调用主流程"""
    messages = [
        {"role": "system", "content": "你是一名专业的企微售后助手,遇到用户查询订单时请使用工具处理。"},
        {"role": "user", "content": user_prompt}
    ]
    
    # 第一次调用 LLM,让模型判断是否需要触发 Tool
    response = llm_client.chat.completions.create(
        model="gpt-4o-mini",
        messages=messages,
        tools=tools,
        tool_choice="auto"
    )
    
    response_msg = response.choices[0].message
    
    # 检查模型是否决定调用函数
    if response_msg.tool_calls:
        # 将模型的思考过程装入消息历史
        messages.append(response_msg)
        
        for tool_call in response_msg.tool_calls:
            func_name = tool_call.function.name
            args = json.loads(tool_call.function.arguments)
            
            # 匹配并执行本地函数
            if func_name == "get_order_status":
                tool_result = get_order_status(args.get("order_id"))
                
                # 将函数执行结果拼回上下文
                messages.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "content": tool_result
                })
        
        # 第二次调用 LLM,总结本地函数返回的结果
        second_response = llm_client.chat.completions.create(
            model="gpt-4o-mini",
            messages=messages
        )
        final_text = second_response.choices[0].message.content
    else:
        # 未触发工具,直接输出普通文本回答
        final_text = response_msg.content

    # 调用 API 将最终结果投递至外部群
    send_msg_to_group(chat_id, sender_id, final_text)

def send_msg_to_group(chat_id: str, sender_id: str, text: str):
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {API_TOKEN}"
    }
    payload = {
        "chat_id": chat_id,
        "msg_type": "text",
        "text": {
            "content": text,
            "mentioned_list": [sender_id]
        }
    }
    requests.post(API_GATEWAY_URL, json=payload, headers=headers, timeout=5)

if __name__ == "__main__":
    # 测试运行
    handle_agent_workflow(
        chat_id="external_chat_998877",
        sender_id="user_888",
        user_prompt="帮我查下订单 OR-20260814 发货了吗?"
    )

如果有关于不同消息载荷类型或高级接口调用的配置诉求,可以直接去 企业微信 API 开发文档 查阅详细的技术规范。


三、 生产环境的安全与防错机制

  1. 敏感操作的二次确认机制
    对于"修改订单地址"、"取消订单"等敏感函数,不能让 AI 直接执行。AI 应解析参数后,先生成一条"卡片消息"包含确认按钮,等待管理员或客户手动点击确认后再真正发起变更。
  2. 严格的参数校验 (JSON Schema Validation)
    大模型提取出的参数(如电话号码、日期格式)偶尔会存在偏差,本地函数在执行前必须加入强类型校验与正则过滤,防止恶意 SQL 注入或非法调用。
  3. 超时降级与超时熔断
    两次 LLM 请求加上一次本地 API 调用的总时长容易超出 5 秒。建议开启后台异步队列处理,网关接收到请求后立即响应,待 Agent 流程全部结束后再主动异步推送。
相关推荐
poiu12346571 小时前
客户沟通音视频素材提炼会议纪要,主流AI工具横向实测对比
人工智能
咖啡星人k1 小时前
想私有化部署 AI 开发平台?MonkeyCode 给出的答案是开源 + 离线
人工智能·大模型·ai编程·monkeycode
NineData1 小时前
DTCC 2026 预告|NineData CEO& 创始人叶正盛:面向 AI Agent 的数据库 DevOps 与数据复制实践
数据库·人工智能·数据库开发·devops·ninedata·数据库技术·dtcc
Eloudy1 小时前
LLM agent 分拆任务的能力来源
人工智能·机器学习
circuitsosk1 小时前
跨境电商智能化实战:AI如何赋能客服自动回复、广告智能投放与供应链预测
大数据·人工智能·python·langchain·智能客服
甲维斯1 小时前
美版豆包G3.7Flash,快到飞起,超3分钟算我输!
人工智能
sunneo2 小时前
每周GitCode开源推荐:AI编程助手AtomCode
人工智能
AIDANHANG2 小时前
最小可售:不是最小可炫
人工智能
鲲穹AI种草2 小时前
图片水印处理工具记录:多款 AI 去水印工具能力边界整理
人工智能·图片水印处理工具