简介一份以 Grab 风控场景为背景的实践分享 PPT面向风控算法、数据分析和 AI 应用从业者探讨如何用大模型与智能体破解复杂场景数据分析中的效率瓶颈、数据孤岛和知识依赖难题。包体为单个 PPT 文件容量 7.81MB目前已有 59 人学习。内容涵盖大模型与 Agent 的能力边界、RAG 知识注入与 SOP 流程注入思路并展开智能体驱动的增强分析平台架构包括混合检索引擎、树形结构 SOP 设计、上下文管理与容错机制等关键技术。同时结合 Analytics Copilot 和 RiskOps Autopilot 两个落地案例展示从自然语言查数到风险运营自动化的完整路径为类似风控数据体系建设提供可参考的工程范式。1. 大模型与智能体在Grab风控中的数据分析实践这份PPT的价值和边界“大模型”、“智能体”、“数据分析”这几个词放在同一份材料里很容易被当成概念拼盘。我拆完这份 Grab 风控场景的实践 PPT 后发现它讲的是完整链路在复杂风控场景里如何让大模型智能体做数据分析并把结果反哺到风控决策。所谓“复杂”指的是跨账户、跨时间段、多行为串联的异常交易规则引擎只能给出打断点模型只能给分数智能体负责把上下文拼起来生成结论。这份材料适合三类人风控算法想了解大模型落到业务上的真实姿势数据分析师想理解智能体如何自动取数分析做智能体应用开发的同行想找一个可参照的案例。整份 PPT 的核心不是某个提示词模板而是一条“规划—调用工具—观察—生成结论”的循环链路。下面我按自己的复现经验把它拆成可以操作的技术方案。2. 从规则引擎到大模型智能体Grab 场景里复杂分析到底复杂在哪2.1 规则引擎和传统 ML 模型的局限为什么光靠特征不够Grab 的业务覆盖叫车、外卖、支付风险场景很杂司机刷单、新用户注册后盗刷、支付渠道异常、账户身份冒用。传统风控的做法是先把行为打成特征设备指纹、IP 归属地、GPS 偏移、下单间隔、历史金额分布然后交给规则引擎或 GBDT/XGBoost 打分。规则引擎的硬伤是只认单点、不认上下文。一条规则“凌晨 1 点到 5 点下单”可能命中很多正常用户“修改手机号后立刻交易”又是另一条规则但当这两件事发生在同一个账户的十分钟内规则引擎看不出这是一个可疑链路只能分头产生两条告警。GBDT 模型能捕捉非线性特征组合但输出是一个风险分风控运营拿到 80 分之后还要去翻日志才能搞清楚“这个用户为什么被打高分”。反直觉的结论在这里数据量多并不等于信息全复杂场景分析缺的是上下文推理能力。大模型智能体补的正是这一层它可以把数据库查询结果、规则命中列表、历史工单结论统一收集起来再生成带证据链的分析报告。我一般把这种能力定义成“给风险分补解释”而不是替代规则和模型。2.2 智能体架构如何切入规划、调用工具、观察、生成结论PPT 里演示的智能体不是一个聊天对话框而是一个任务循环。受理一条可疑交易之后智能体先做规划先看用户基本信息再查最近事件序列再对照规则命中情况。这对应到工程上就是典型的 ReAct 风格循环Reasoning 和 Action 交替进行每调用一次工具都把结果写回上下文让模型判断是继续深挖还是输出结论。整体架构一般拆成四个模块也是我在复现时最先搭出来的骨架模块职责典型工具/数据输出规划模块把“分析这个用户”拆成子任务决定下一步动作LLM 决策配合 Pydantic 约束下一步动作 参数工具模块执行数据查询和规则检索SQL、规则引擎快照、风控知识库结构化查询结果记忆模块记录已经查到的中间结果避免重复查询内存里的 dict 或 messages 列表追加后的上下文结论模块汇总中间结果生成风险结论和建议LLM JSON schema风险分、风险等级、证据链模块之间最容易踩的坑是“假循环”工具只调用一次后面所有轮次都不再更新上下文。我在复现时会给循环一个硬性上限默认 5 轮每一轮把新查询结果追加到上下文然后让模型决定是继续还是收尾。这样既保证深度又不会让 API 调用失控。还有一个选型层面的认知不是所有风控告警都值得上智能体。交易量大的常规告警直接用规则处理只有规则和模型都给不出确定判断的中尾场景才需要进智能体分析。Grab 这类业务每天会产生大量中低危事件如果全部交给大模型延迟和成本都扛不住目标应该是用智能体处理那些“需要人工看上下文”的案子把人的时间省下来。场景传统规则/模型做的事智能体介入位置凌晨高频下单规则命中生成告警把同一用户的改绑手机号、换设备串联起来支付金额异常模型给出高风险分解释分数来源短时间内持续加小费后大额消费新账户批量注册设备指纹识别出群控对比同一个 IP 段下其他账户的行为模式上表是我还原 PPT 场景时整理的对应关系。核心经验是智能体不要替代第一道防线而要定位在“解释与研判”这一层否则边界守不住后面评估也会乱。3. 复现一个风控研判智能体环境、代码、结构化输出3.1 环境配置与依赖选择复现时我先搭一个最小可运行的环境Python 3.10 以上核心依赖写在 requirements.txt 里。不需要一开始就上重型智能体框架先用 OpenAI SDK 或任意兼容接口把链路跑通再考虑要不要引入编排框架。# requirements.txt # agentic_risk 项目运行环境Python 3.10 langchain0.1.16 openai1.12.0 pydantic2.6.4 pandas2.2.1 SQLAlchemy2.0.27 tenacity8.2.3这里每个包都有明确用途openai负责大模型 API 调用langchain用来做工具分发和链式调用pydantic负责约束输出结构tenacity处理重试逻辑。如果你不想用 LangChain也可以自己写一个 while 循环后面我会给出编排代码。安装完成后先验证模型接口能通。无论你接的是云端大模型 API 还是本地部署的模型服务统一封装成一个call_llm函数会比较省事后面切换供应商只改这一个函数。3.2 核心编排代码从原始告警到分析报告下面这段代码我复现时写在risk_agent.py里。工具函数只做数据层的事查事件、查规则、调大模型。编排层是一个简单循环每次把新信息追加到消息列表里让大模型决定下一步动作。# risk_agent.py from typing import Dict, List import json # 模拟查询用户最近事件序列真实项目里替换成SQL def query_user_history(user_id: str, hours: int 24) - List[Dict]: sql SELECT event_type, amount, currency, created_at FROM risk_events WHERE user_id :uid AND created_at now() - interval :hours hour ORDER BY created_at # 这里假设已执行SQL并返回结果 return [ {event_type: order, amount: 500, currency: THB, created_at: 2025-01-03 01:12:00}, {event_type: change_phone, amount: 0, currency: THB, created_at: 2025-01-03 01:15:00}, ] # 获取用户命中的规则 def retrieve_rule_hits(user_id: str) - List[Dict]: return [ {rule_id: R101, desc: 凌晨高频下单}, {rule_id: R204, desc: 修改手机号后立即交易}, ] # 统一LLM调用入口方便替换模型 def call_llm(system_prompt: str, user_prompt: str, temperature: float 0.2) - str: from openai import OpenAI client OpenAI() resp client.chat.completions.create( modeldeepseek-chat, # 按实际部署模型名替换 messages[ {role: system, content: system_prompt}, {role: user, content: user_prompt} ], temperaturetemperature, ) return resp.choices[0].message.content这段代码的逻辑是先通过query_user_history拉取用户最近 24 小时的行为再靠retrieve_rule_hits拿到规则命中情况两者一起拼成给大模型的上下文。temperature0.2是故意压低随机性风控场景宁可保守输出不要天马行空的措辞。hours24是时间窗口参数实际场景可以放宽到 72 小时因为一些欺诈链条会跨几天。窗口越大上下文越长后面必须处理 token 预算问题。循环部分是这样的def run_agent(user_id: str, max_steps: int 5): # 拼接初始上下文 events query_user_history(user_id) rules retrieve_rule_hits(user_id) context build_context(events, rules) for step in range(max_steps): system_prompt 你是风控研判助手依据给定上下文输出结论。 user_prompt f用户ID: {user_id}\n上下文:\n{context}\n\n请分析。 result call_llm(system_prompt, user_prompt) # 如果模型输出包含ACTION则执行工具并追加到上下文 if ACTION: in result: tool_name parse_tool_name(result) if tool_name query_user_history: context \n json.dumps(query_user_history(user_id), ensure_asciiFalse) continue else: return result return 达到最大轮次强制结束这里的关键设计是max_steps5。没有这个上限模型在遇到边界情况时会反复调用工具把调用费打到失控。另一个细节是continue之前必须把工具返回结果追加进context否则第二轮循环拿的还是旧数据智能体就退化成单轮问答了。3.3 把输出锁成 JSON风控工单需要稳定 schema大模型直接输出自然语言下游工单系统很难处理。我复现时用 Pydantic 定义一个风险结论的 schema所有智能体输出最终都要过这一层校验。# risk_schema.py from pydantic import BaseModel, Field from typing import List, Optional class RiskConclusion(BaseModel): risk_score: float Field(ge0, le1, description最终风险分用于排序) risk_level: str Field(pattern^(low|medium|high)$, description风险等级) conclusion: str Field(description一句话核心结论) evidence: List[str] Field(description证据链必须来源于工具返回值) suggestion: str Field(description建议动作例如冻结或人工复核)字段参数是最需要关注的risk_score限制在 0 到 1 之间和传统模型的分数对齐方便对比risk_level用正则限制成三档避免模型输出“Medium High”这类不标准值evidence必须是字符串列表每一条都要来自工具返回这是防幻觉的第一个闸门。拿到模型输出后用RiskConclusion.model_validate(json.loads(text))做解析解析失败就重试一次。如果连续两次失败自动降级为人工队列而不是让流程死掉。这套兜底逻辑比任何提示词都可靠。4. 提示词工程与上下文工程让大模型按风控语言说话4.1 系统提示词模板角色、边界、引用规则风控场景的提示词不适合写得太自由。我参考 PPT 里的演示话术后稳定下来的系统提示词大概是下面这样你是一名Grab东南亚区域风控分析师。请基于工具返回的上下文判断风险。 规则 1. 只能引用上下文中出现的事件ID、时间和金额禁止编造。 2. 如果证据不足明确写“暂无直接证据”不要强行下结论。 3. 先分析时间、设备、金额是否符合用户历史习惯再给最终判断。 4. 多个异常在短时间内同时发生时按高危处理。 5. 建议动作只能从放行、人工复核、冻结中选择。这里最有价值的是第 2 条和第 5 条。第 2 条明确允许模型说“不知道”能显著降低幻觉第 5 条把建议动作约束成三类下游系统才能直接接流程。很多初版提示词忽略这个边界模型会给出“建议联系客户确认”这种无法执行的建议工单系统直接傻掉。我在实际测试中发现角色设定里的“东南亚区域”也是有意义的。Grab 的业务横跨多个国家行为习惯差异很大。比如凌晨下单在印尼雅加达可能是夜市刚收摊后的正常行为在新加坡则更可疑。提示词里点明区域相当于给模型一个先验约束。4.2 动态上下文组装与 Token 预算提示词定好后最影响效果的其实是上下文怎么拼。我在代码里单独抽了一个build_context函数把工具返回结果转换成可读文本。def build_context(events: List[Dict], rules: List[Dict]) - str: lines [事件序列:] for e in events: lines.append( f- {e[created_at]} | {e[event_type]} | f{e[amount]} {e[currency]} ) lines.append(命中规则:) for r in rules: lines.append(f- {r[rule_id]} {r[desc]}) text \n.join(lines) # 防止上下文过长按字符截断保留最近部分 max_chars 2000 if len(text) max_chars: text text[-max_chars:] return text这个函数最容易被忽视的是截断策略。我选择保留最后 2000 字因为风控分析中最近的事件权重最高created_at是完整时间戳不能只保留日期否则模型分不清事件先后顺序。如果工具返回的字段很多建议提前在 SQL 层做字段裁剪只取event_type、amount、currency、created_at这几个核心字段不要一股脑把全部日志塞进提示词。与截断同样重要的是 token 预算分配。我会给一段长上下文预留总 token 的 60%给模型输出预留 30%剩下的作为系统提示词和冗余。如果一个模型的上下文窗口是 8000 token那么动态查询结果最多能占 4800 token 左右超过就截断或分页。这一步不做模型会在长上下文后段“忘记”前面的关键信息表现为回答了跟风险结论无关的废话。4.3 工具描述与调用格式让模型知道该用哪个工具智能体循环里模型要自己决定调哪个工具因此每个工具的 description 都要写清楚触发条件。我复现时会为每个工具维护一个描述字段比如query_user_history查询用户最近事件序列。当上下文中缺少行为数据时调用。 retrieve_rule_hits查询用户命中的风控规则。当需要了解规则命中情况时调用。描述字符串里要包含“什么时候调用”和“能解决什么问题”而不是只写“查询用户”。模型本质上是靠这个描述做动作选择描述写得模糊模型就会乱选。调用格式我统一用ACTION: tool_name | param1value1 | param2value2这种纯文本格式避免嵌套 JSON 导致解析出错。5. 避坑清单复现大模型风控智能体时踩过的五个实际问题5.1 现象模型幻觉出不存在的交易记录复现初期模型会在分析里写出“该用户曾在 12 月 30 日有一笔 3000 THB 的异常交易”但我检查工具返回时根本没有这条记录。原因是大模型在自由生成时习惯了“补全”语义上下文里没有它就自己编这是生成式模型的天性。解决方法是双管齐下一方面在提示词里强制“只能引用工具返回值否则写暂无直接证据”另一方面把工具返回结果做成带索引的列表并告诉模型引用时只能写索引号。后来我把输出中的evidence字段直接改成从工具返回里提取的字符串而不是让模型自己生成幻觉基本消失了。5.2 现象工具调用超时智能体陷入死循环有一次线上压测某个 SQL 查询因为数据库锁超时工具返回异常。智能体没有感知到失败又发起同样查询连续三轮超时后 API 费用涨了一大截。原因是我没有为工具调用设置超时和失败重试策略。解决在call_llm外层套一个tenacity重试装饰器限制 2 次重试间隔 1 秒同时把工具执行包在try/except里返回结构化错误信息给模型例如ERROR: query timeout请尝试缩小时间范围或检查用户ID。这样模型才知道换一种方式处理而不是机械重试。5.3 现象时区和货币问题导致误判Grab 覆盖泰国、印尼、新加坡等多个国家初版上下文直接拼原始时间结果泰国凌晨 2 点的事件和新加坡凌晨 2 点出现在同一份上下文里模型按同一时区理解把正常境外订单判成高危。原因是我没有统一时区也没有在上下文中标注国家。解决所有入库事件统一转成 UTC 存储上下文输出时保留 UTC 并额外标注本地时区推断例如created_at_utc2025-01-02T18:12:00Z。金额字段同时给币种和折算后的统一单位我一般统一折算成 USD避免模型直接比较 THB 和 IDR 的数值大小。5.4 现象本地部署模型推理延迟太高无法满足告警窗口如果把 7B、13B 模型直接部署在 CPU 上单次推理可能要 5 到 10 秒智能体循环 5 轮就是几十秒超过告警处置窗口。原因是模型参数量大又没有做量化或裁剪。解决对延迟敏感的场景优先选 7B 以下的量化模型比如 Q4 量化版本配合 vLLM 这类推理框架更稳妥的做法是分层处理简单告警用快速规则只有需要深挖的案例才进大模型链路。PPT 里展示的探索方向是对的但生产环境一定要给“模型不可用”留降级通道否则告警就断了一条腿。5.5 现象JSON 输出格式不稳定下游解析频繁失败模型生成的 JSON 偶尔会带注释、Markdown 代码块包裹或者字段顺序混乱。原因是大模型对格式的遵循能力不够稳定加上提示词里没有给出强约束。解决优先用模型的工具调用能力输出结构化结果而不是让模型直接生成 JSON 文本同时增加一次格式校验解析失败就自动追加一条错误信息重新请求。我在 Pydantic 解析失败时会把错误喂给模型“You produced invalid JSONerror: xxx请重新输出”第二次成功率能到 95% 以上。6. 进阶给智能体加自校验和离线评估护栏6.1 自校验让模型先给理由再给结论风控场景里结论的可解释性和结论本身一样重要。我把智能体输出流程改成两段第一段只输出“证据整理和推理过程”第二段基于这段推理生成风险等级和建议动作。这样即使最终结论错了回溯时也能定位到是哪步推理出问题而不是看到一个莫名其妙的“high”。def run_with_reasoning(user_id: str) - RiskConclusion: context build_context(query_user_history(user_id), retrieve_rule_hits(user_id)) reasoning call_llm( system_prompt只输出推理过程不要给建议。, user_promptf用户ID: {user_id}\n上下文:\n{context}\n\n先整理证据链。, temperature0.1 ) conclusion call_llm( system_prompt依据推理过程生成结构化结论严格符合JSON Schema。, user_promptf推理过程:\n{reasoning}, temperature0.1 ) return RiskConclusion.model_validate(json.loads(conclusion))这里temperature0.1是我调过多次后定下的值。推理阶段需要稳定结论阶段更不能随机。split 成两步之后token 消耗变多但每次上线试点时业务方可以直接阅读推理过程认可度明显提升。6.2 离线评估在历史风险样本上跑分我在部署任何一版智能体前都会先找一个带标注的历史样本集大概 200 到 500 条告警包含正常、可疑、高危三类人工标注好最终结论。然后跑三组指标风险等级准确率、高危召回率、证据链正确率。指标计算方式我设置的及格线风险等级准确率模型结论与人工标注一致的比例大于 70%高危召回率人工标注高危案件被模型识别为高危的比例大于 85%证据链正确率evidence 中可对到工具返回的比例大于 95%评估不用等到上线后做线下脚本就能完成。我会把每次评估中模型答错案例记录下来归因是提示词问题、上下文缺失还是模型能力边界再针对性调整。这套流程后来成了我的固定习惯无论是换底座模型还是改提示词结构都要用同一份标注样本复测避免“调好一个case、打崩一片case”的尴尬。从那以后我每次做智能体风控项目都强制走一遍先定义场景边界搭工具循环锁结构输出最后用标注样本评估。走到这里这份 PPT 里演示的实践才算真正落地也希望这篇文章能帮你在自己的业务场景里少走几步弯路。本文还有配套的精品资源点击获取