当AI开始写警察报告——技术开发者必须知道的三个坑
NBC News的报道里有一条容易被忽略的线索:「New concerns over use of A.I. to draft police reports」。结合近期美国多州试点AI生成警情报告的消息,这件事对技术人的信号非常明确:LLM正在进入高责任场景,而现有的大多数Demo方案根本不能直接上线。
我不是说AI不能写报告,而是说如果直接拿一个ChatGPT wrapper给警官用,轻则报告里出现当事人不存在的动作,重则导致冤假错案。下面我用一个实战级别的Demo来说明,怎么在技术上把风险降到可接受范围。
1. 目标:生成一份「可追责」的结构化报告
我们先定义一个最小可行产品。警官在手机/车载终端输入语音或文字,系统输出一份含时间、地点、当事人、事件经过、处置措施等字段的JSON报告。核心要求:
- 每条事实必须可溯源到原始输入或知识库
- 禁止生成未提及的细节(比如描述“嫌疑人掏出手机”,如果原始记录里没有)
- 输出格式严格统一,方便直接入档

2. 技术选型与核心实现
模型选择
推荐使用GPT-4o或Claude 3.5 Sonnet,原因:对JSON schema的支持好,能设置严格的response_format,并且具备初步的事实一致性能力。如果预算有限,可以用Qwen2.5-72B-Instruct(开源),但在长文本事实校对上需要额外加固。
提示模板:强制结构化 + 禁止幻觉
关键设计:给模型明确的“事实栈”(只有出现在输入中的事实才允许输出)和“负面清单”(禁止添加细节)。同时要求模型输出后的验证步骤。
以下是一个可用的模板结构(Python示例):
SYSTEM_PROMPT = """
你是一位警方报告生成助手。你的任务是根据用户提供的原始记录,生成一份结构化的警情报告。
**规则(违反任何一条都将被拒绝):**
1. 只能基于用户提供的原始记录中的事实进行输出。不得添加任何未在原始记录中出现的时间、地点、人物身份、动作、物品或事件顺序。
2. 如果原始记录中有模糊或缺失的信息,必须在对应字段中填写“未提供”,而不是猜测或推断。
3. 输出必须严格遵守下面的JSON Schema,不得包含任何额外注释或键。
4. 报告中的“事件经过”必须使用中性、客观的叙述,避免主观判断(如“可疑”、“异常”)。
5. 每条事实的组成部分(如动作、对象)必须是原始记录中明确存在的。
JSON Schema:
{
"report_time": "string (ISO 8601,填写当前时间)",
"incident_time": "string (从原始记录中提取,或'未提供')",
"incident_location": "string (从原始记录中提取,或'未提供')",
"involved_parties": [
{
"name": "string (若未提供填'未知')",
"role": "string (如'报警人'、'嫌疑人',若未明确填'相关人员')",
"description": "string (仅限于原始记录中明确提到的特征,如性别、衣着,不要扩展)"
}
],
"event_narrative": "string (客观描述事件经过,只包含原始记录中的信息,每句话最多10个事实点)",
"actions_taken": ["string"],
"additional_evidence": ["string"]
}
原始记录如下:
"""
注意:这里的“只包含原始记录”必须通过后处理来强制保证,因为模型有违抗风险。所以我们要做第二步:事实一致性校验。
后处理校验:用NLI模型怼事实
使用一个简单的自然语言推理(NLI)模型,比如roberta-large-mnli,将模型输出的每句Fact与原始记录对比,标注为“支持/矛盾/无关”。如果出现矛盾或无关,则拒绝该输出并提示警官人工核查。
from transformers import pipeline
nli_pipeline = pipeline("zero-shot-classification", model="roberta-large-mnli")
def verify_fact(fact_sentence: str, original_text: str) -> bool:
result = nli_pipeline(fact_sentence, candidate_labels=["supported", "contradicted"], hyp_only=True)
# 如果模型认为contradicted的概率 > 0.5,则返回False
return result['scores'][0] > 0.5 # 这里简化,实际应该用更严谨的阈值
实际上我见过更可行的做法:用LLM自身做事实核查。一个模型生成,另一个模型(同样系统但不同种子)核查,对比一致性。如果两个模型对事实的描述存在差异,则标记为待审核。
3. 项目结构 & 配置
police_report_ai/
├── app/ # FastAPI服务
│ ├── main.py
│ ├── generate.py # 调用LLM生成报告
│ └── verification.py # 事实校验逻辑
├── prompts/ # 提示模板文件
│ ├── report_generation.txt
│ └── fact_check.txt
├── models/ # 对LLM API的封装
│ ├── llm_client.py
├── config.py # API key, 模型名称等
├── tests/ # 测试用例(必须包含对抗测试)
│ └── test_fact_integrity.py
└── requirements.txt
关键配置(config.py示例):
MODEL_NAME = "gpt-4o-2024-08-06" # 或 claude-sonnet-4
TEMPERATURE = 0.0 # 事实场景必须为0
MAX_TOKENS = 2048
# 要求API返回结构化输出
RESPONSE_FORMAT = {"type": "json_object"}
# 启用事实校验
FACT_CHECK_ENABLED = True
CHECK_MODEL = "gpt-4o-mini" # 用便宜模型做二次校验
4. 上线必须解决的三个坑
坑1:幻觉 — 模型会补细节
即使提示写死了“不要添加”,模型仍然可能写出“嫌疑人驾驶一辆红色轿车”而原始记录只有“一辆轿车”。解法:后处理强制用NLI拦截,同时在前端UI中标注“AI生成的报告包含以下可能不准确的内容”。这不是推卸责任,而是给警官一个审阅入口。
坑2:偏见放大
警方报告对特定人群的描写容易带有偏见。比如原始记录“男子穿黑色衣服”,模型可能会写成“可疑男子”。解法:在提示中加入“禁止使用带有主观色彩或歧视性的词汇”,并在系统层面做脱敏处理(如将种族、国籍等信息标记为敏感字段,需要单独确认)。
坑3:责任归属
如果AI生成错误报告被采信导致错案,谁负责?目前的法律框架下,AI不能作为责任主体。所以必须在系统设计时强制加入“人工审核签名”步骤:任何AI生成的报告必须由警官修改后才能保存,原始AI输出和修改历史都要记录在日志中。代码上实现:使用不可篡改的审计日志(如区块链哈希校验,或者简单的append-only数据库)。
5. 一个小建议
如果你正在做一个类似项目(不一定是警方,也可能是医疗报告、法律文书),先做“对抗测试”:找一群懂业务的人,让他们故意输入模糊或矛盾的信息,看你的系统会生成什么。大多数问题只有在这种测试中才会暴露。
我自己的经验是,一个看起来能跑的通用的AI报告生成器,在真实业务场景里第一版几乎100%需要重写。这不是模型的问题,是我们在设计时忽略了人类语言的隐式信息。
所以,别急着上线。先把校验逻辑跑起来。
(完)