尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

AI风控实战:Function Calling如何让LLM从分析到自动执行

AI风控实战:Function Calling如何让LLM从分析到自动执行 1. 项目缘起为什么你的AI风控需要“动手能力”在风控这个行当里干了十几年我见过太多“纸上谈兵”的智能系统。它们能分析、能预警、能生成一份漂亮的报告但一到关键时刻需要它“动”起来——比如自动拦截一笔可疑交易、临时调整一个用户的信用额度、或者给运营同事发一条待处理的工单——就哑火了。最终还是得靠人工去后台点点点效率瓶颈和响应延迟就是这么来的。我们之前聊过如何用大语言模型LLM去理解交易文本、分析用户行为构建一个聪明的“大脑”。但一个只有大脑、没有手脚的助手终究只是个参谋成不了将军。Function Calling就是给这个聪明的“大脑”装上可操控的“手脚”。它让LLM不仅能“想”还能“做”——通过调用我们预先定义好的工具函数去执行具体的业务操作。举个例子你的风控模型判断某笔深夜的高额境外交易风险极高。没有Function Calling流程可能是模型输出风险结论 - 风控员看到告警 - 登录后台系统 - 手动查找该订单 - 执行拦截操作。整个过程可能耗时几分钟骗子早就完成洗钱跑路了。有了Function Calling流程就变成了模型判断风险 - 自动调用“交易拦截”函数 - 系统在毫秒级完成拦截。这中间的效率差和风险控制能力是天壤之别。所以这个Stage 3我们要解决的核心问题就是如何安全、准确、高效地教会AI使用我们给它准备好的“工具”让智能决策能瞬间转化为实际行动。这不是简单的API调用而是一套关于意图理解、权限管控、执行反馈的完整工程体系。2. Function Calling的本质不是调用是“对齐”与“调度”很多人一听到Function Calling第一反应就是“让AI去调我的代码函数”。这个理解对了一半但更关键的一半被忽略了。LLM本身并不能直接执行你的Python或Java函数它运行在远端的云端没有你本地环境的权限。实际上Function Calling是一个精巧的“对齐”过程。它的工作流程更像一个经验丰富的指挥官和一支特种部队指挥官LLM分析战局用户输入它根据当前的对话上下文和用户的问题判断是否需要动用“工具”以及动用哪个“工具”最合适。指挥官下达指令生成结构化调用请求它不会直接说“去调block_transaction函数”而是会按照我们事先约定好的格式生成一个标准的、结构化的调用请求比如{“name”: “blockTransaction”, “arguments”: {“order_id”: “123456”, “reason”: “高风险境外交易”}}。这个格式就是我们定义的“工具描述”。通信兵你的应用代码传递指令你的后端服务收到这个结构化请求。特种部队你的本地函数执行任务你的代码解析这个请求找到对应的本地函数block_transaction(order_id, reason)传入参数并执行它。这个函数拥有访问数据库、调用内部API、发送消息等所有必要的权限。部队回传战报执行结果函数执行完成后将结果成功或失败附带详情再次封装成结构化的文本或数据。指挥官整合战报继续指挥这个结果被送回到LLMLLM结合这个“战报”和之前的对话历史生成最终面向用户的自然语言回复比如“已成功拦截订单123456已记录原因为‘高风险境外交易’。”所以Function Calling的核心是让LLM的理解与我们后端的执行能力“对齐”。我们通过“工具描述”告诉LLM我们有哪些能力、每个能力需要什么信息LLM则负责在复杂的自然语言中精准地识别出需要使用哪个能力并提取出所需的参数。这是一个从非结构化自然语言到结构化函数调用再回到非结构化自然语言回复的闭环。注意安全是这里的生命线。LLM只是“建议”调用某个函数最终是否执行、如何执行、参数是否合法完全由你的后端代码掌控和校验。绝对不能让LLM的建议直接等同于执行。3. 实战第一步设计你的风控“工具包”在写一行代码之前我们必须像设计一套手术器械一样精心设计我们的工具。工具不是越多越好而是越精准、越安全越好。根据常见的风控场景我通常会规划这么几个核心工具3.1 工具清单设计与思考交易操作类blockTransaction: 拦截/挂起一笔交易。这是最核心的“急刹车”功能。adjustUserCredit: 调整用户信用额度或设置交易限额。用于动态风险控制。flagUserForReview: 给用户打上风险标签触发人工审核流程。信息查询类getTransactionDetails: 根据订单号查询交易详情金额、时间、商户、IP等。LLM在做决策前可能需要更详细的数据。getUserBehaviorHistory: 获取用户近期登录、交易、设备变更等行为序列。用于上下文风险分析。queryRiskRules: 查询当前生效的风险规则及其命中情况。让AI了解“系统为什么这么判断”。通知与协同类createRiskCase: 在风控工单系统中创建一个案件并分配给人审。sendAlertNotification: 向风控值班人员的钉钉/飞书群发送一条强提醒消息。设计原则单一职责一个工具只做一件事。blockTransaction就只负责拦截不要在里面又查用户信息又发通知。参数明确每个参数定义清晰的数据类型string, number, boolean和格式如order_id必须是32位字符串。这能极大减少LLM的误解。安全边界在工具描述中可以加入使用说明和警告例如“此工具将直接中断交易流程请仅在确认高风险时使用。”3.2 如何编写“工具描述”以OpenAI格式为例“工具描述”是你和LLM之间的契约。一份好的描述能极大提升调用的准确率。它本质上是一个JSON Schema。{ type: function, function: { name: blockTransaction, description: 拦截一笔指定的支付交易。该操作将立即阻止交易完成并将资金退回到用户账户或原支付渠道。, parameters: { type: object, properties: { order_id: { type: string, description: 需要拦截的支付订单的唯一标识符。 }, reason: { type: string, description: 拦截的原因代码或简短描述。例如suspected_fraud涉嫌欺诈、policy_violation违反策略、high_risk_region高风险地区。, enum: [suspected_fraud, policy_violation, high_risk_region, user_request, system_error] }, comment: { type: string, description: 给运营人员查看的补充说明或备注。 } }, required: [order_id, reason] } } }关键点解析description: 这是最重要的部分要用清晰、无歧义的语言告诉LLM这个工具是干什么的、什么时候用。好的描述能直接让LLM做出正确判断。parameters: 定义每个参数。使用enum枚举来限制reason的取值这是保证输入合规、便于后续统计的关键。required字段指明了哪些参数是LLM必须提供的。不要暴露内部细节描述里不需要写“调用/api/v1/risk/block这个POST接口”那是你后端实现的事。LLM只需要知道业务逻辑。4. 构建执行引擎连接LLM与业务系统的桥梁有了工具描述接下来就要搭建一个可靠的“执行引擎”。这个引擎负责接收LLM的调用请求安全地执行本地函数并管理整个对话状态。4.1 基础架构与流程一个典型的执行引擎包含以下组件对话/状态管理器维护与LLM的对话历史管理多轮对话中工具调用的上下文。工具注册中心一个字典或配置将工具名blockTransaction映射到实际的可调用函数和它的描述。参数解析与验证器对LLM生成的参数进行二次校验类型、范围、业务逻辑这是防止“胡说八道”导致错误操作的关键防线。函数执行器在安全的沙盒或权限上下文中调用实际业务函数。结果格式化器将函数执行结果可能是对象、异常等转换成LLM能理解的自然语言或结构化文本。4.2 核心代码实现Python示例我们以一个简化但完整的过程来展示。假设我们使用OpenAI的ChatCompletion API。import json import openai from typing import Dict, Any, Callable, List # 1. 工具注册中心 class FunctionRegistry: def __init__(self): self._functions: Dict[str, Callable] {} self._descriptions: List[Dict] [] def register(self, func: Callable, description: Dict): 注册一个工具函数及其描述 self._functions[description[function][name]] func self._descriptions.append(description) return func # 方便用作装饰器 def get_function(self, name: str) - Callable: return self._functions.get(name) def get_descriptions(self) - List[Dict]: return self._descriptions # 2. 定义我们的风控工具函数 registry FunctionRegistry() registry.register def block_transaction(order_id: str, reason: str, comment: str ) - Dict[str, Any]: 实际拦截交易的业务函数 # 这里是你的真实业务逻辑例如 # 1. 校验订单状态是否可拦截 # 2. 调用支付系统的拦截接口 # 3. 记录风控操作日志 # 4. 可能触发异步通知 print(f[业务执行] 拦截订单 {order_id}, 原因: {reason}, 备注: {comment}) # 模拟一个成功响应 return { success: True, order_id: order_id, action: blocked, message: f订单已成功拦截。退款流程已启动。 } # 关联上一步我们定义的工具描述 # 假设 tool_description_block 就是前面那个JSON对象 registry._descriptions.append(tool_description_block) # 3. 对话与执行引擎 class RiskControlAssistant: def __init__(self, registry: FunctionRegistry, client): self.registry registry self.client client # OpenAI客户端 self.messages [] # 对话历史 def chat(self, user_input: str) - str: 处理用户输入可能涉及多轮工具调用 self.messages.append({role: user, content: user_input}) while True: # 调用LLM传入工具描述 response self.client.chat.completions.create( modelgpt-4, # 或 gpt-3.5-turbo messagesself.messages, toolsself.registry.get_descriptions(), # 关键告诉LLM可用的工具 tool_choiceauto, # 让LLM自行决定是否调用工具 ) message response.choices[0].message self.messages.append(message) # 将LLM的回复加入历史 # 检查LLM是否想要调用工具 if not message.tool_calls: # 没有工具调用直接返回最终回复 return message.content # 处理一个或多个工具调用 for tool_call in message.tool_calls: function_name tool_call.function.name function_args json.loads(tool_call.function.arguments) # 从注册中心获取实际函数 function_to_call self.registry.get_function(function_name) if not function_to_call: # 处理工具未找到的情况 result {error: fFunction {function_name} not found.} else: # 关键在执行前进行业务参数校验 if not self._validate_arguments(function_name, function_args): result {error: Invalid arguments provided.} else: # 安全地执行函数 try: result function_to_call(**function_args) except Exception as e: result {error: fExecution failed: {str(e)}} # 将工具执行结果作为新的消息反馈给LLM self.messages.append({ role: tool, tool_call_id: tool_call.id, content: json.dumps(result), name: function_name }) # 循环继续LLM会根据工具执行结果生成下一轮回复 def _validate_arguments(self, func_name: str, args: Dict) - bool: 加强版参数校验示例 if func_name blockTransaction: # 检查order_id格式假设是32位字母数字 order_id args.get(order_id, ) if len(order_id) ! 32 or not order_id.isalnum(): return False # 检查reason是否在允许的枚举值内 if args.get(reason) not in [suspected_fraud, policy_violation, high_risk_region, user_request, system_error]: return False return True # 4. 使用示例 if __name__ __main__: client openai.OpenAI(api_keyyour-api-key) assistant RiskControlAssistant(registry, client) # 模拟一个风控指令 user_query “发现订单ID ‘abc123xyz789def456ghi159jkl753mno852’ 存在欺诈特征请立即拦截它原因为涉嫌欺诈。” final_response assistant.chat(user_query) print(助手回复:, final_response)这段代码的实战要点分离关注点FunctionRegistry负责管理工具RiskControlAssistant负责对话流程。结构清晰便于扩展。强制校验_validate_arguments函数是必须的。LLM可能生成格式正确但业务逻辑错误的参数比如一个不存在的order_id。你的业务代码必须在执行前进行最终校验。循环处理while True循环处理了多轮工具调用的可能。LLM可能先调用getTransactionDetails查询详情再根据结果调用blockTransaction。错误处理工具执行可能失败网络、数据库、业务规则冲突必须捕获异常并将结构化的错误信息返回给LLM让它能向用户解释。5. 高级策略与避坑指南让“智能”真正“可靠”基础功能跑通只是第一步要让这个系统在生产环境可靠运行还需要一系列高级策略和防错机制。5.1 权限管控与操作确认绝对不能允许一个普通的客服AI助手拥有拦截所有交易的权限。必须引入权限层级和确认机制。工具权限组将工具分类如信息查询类、轻度操作类如打标签、重度操作类如拦截、调额。为不同的AI助手角色如“风控分析员”、“值班机器人”、“客服助手”绑定不同的权限组。关键操作二次确认对于blockTransaction这类高风险操作可以在执行引擎中增加一个确认环节。当LLM请求调用时引擎先不执行而是生成一条确认消息“即将拦截订单XXX原因YYY请确认”等待人工或另一个高权限系统的确认后再真正执行。这可以通过在对话流中插入一个特殊的“确认”工具来实现。5.2 处理模糊与冲突的指令用户输入是模糊的LLM的理解也可能出现偏差。场景用户说“查一下张三最近的那笔大额交易”。LLM可能需要调用getUserBehaviorHistory但发现用户“张三”有多个且“大额”定义不清。策略这时LLM应该生成一个“澄清”性问题而不是盲目猜测。这需要我们在系统设计时鼓励LLM在参数不足时主动提问。我们可以通过在system提示词中强调“如果你无法从对话中确定执行某个工具所需的全部必要参数请主动向用户提问以澄清。”5.3 工具描述的“咒语”工程工具描述的写法直接影响LLM的调用准确性这本身就是一种“提示词工程”。坏描述“处理订单。”太模糊LLM不知道什么时候用、怎么用好描述“当一笔支付订单被判定为高风险或涉嫌欺诈时使用此工具来立即阻止交易完成并将资金置于冻结或退回状态。需要提供明确的订单标识和符合规定的风险原因代码。”技巧在描述中使用“当...时”、“用于...场景”、“需要提供...”等句式明确工具的触发条件和输入要求。甚至可以加入反面例子“不要用于因用户普通争议而发起的退款。”5.4 链路追踪与可解释性所有通过Function Calling执行的操作都必须留下完整的审计日志。日志内容原始用户请求、LLM生成的工具调用请求含参数、参数校验结果、实际执行函数的输入输出、最终返回给用户的答复。价值当出现误操作时你可以完整回溯是用户的指令模糊还是LLM理解错误或是工具描述不当亦或是业务函数本身的bug。这是后续迭代优化最重要的数据来源。5.5 性能与成本考量工具列表长度每次请求都将所有工具描述发给LLM会消耗Token。如果工具很多比如超过50个可以考虑动态加载根据对话上下文只加载可能相关的工具子集。超时与重试工具执行尤其是调用外部API可能超时。执行引擎需要设置合理的超时时间并设计重试或降级策略例如拦截失败后转为创建加急工单。限流与熔断防止针对AI助手的恶意提问导致工具被高频调用对业务系统造成压力。6. 从Demo到生产必须完成的清单把实验代码变成生产系统还有最后几公里要走这几公里往往坑最多。全面的错误处理与降级网络抖动、LLM服务不可用、工具函数异常、数据库连接失败...每一个环节都要有对应的错误处理逻辑和友好的用户提示。至少要有“降级模式”当Function Calling链路整体不可用时AI助手能优雅地退化为一个只提供分析建议的“顾问”而不是直接崩溃或给出误导信息。输入清洗与防护用户输入可能包含SQL注入、命令注入等恶意内容。虽然LLM本身有一定防护但在将用户输入拼接进提示词或作为参数传递给工具函数前必须进行严格的清洗和转义。版本化管理工具函数和其描述会迭代更新。当你要修改一个工具的参数或行为时如何保证不影响正在进行的对话需要考虑工具描述的版本号以及向后兼容的策略。集成测试必须建立一套完整的集成测试用例模拟各种边界情况模糊指令、参数缺失、参数错误、工具执行失败、多轮复杂交互等。这是保证系统稳定性的基石。监控与告警监控关键指标工具调用成功率、各工具调用频次、平均响应时间、LLM调用消耗的Token数。对调用失败、高频调用异常工具等情况设置告警。走到这里你的AI风控助手才真正具备了“动手”的能力。它不再只是一个被动的分析器而是一个能主动介入风险处理流程的智能体。你会发现整个风控的响应速度和处理范式都会因此改变。当然能力越大责任越大。赋予AI行动力意味着你需要更严谨的工程设计、更严密的安全管控和更细致的运维观察。但这一切的投入在拦截住那笔即将造成重大损失的交易时都会显得无比值得。
返回列表