Files
llm-wiki/scripts/validate-step1.sh
T
2026-07-12 21:26:08 +08:00

145 lines
5.8 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 验证 ingest Step 1 的 JSON 输出格式
# 用法:bash validate-step1.sh <json_file>
# 返回:0 = 格式正确,1 = 格式有问题(触发回退)
SCRIPT_DIR="${BASH_SOURCE[0]%/*}"
[ "$SCRIPT_DIR" = "${BASH_SOURCE[0]}" ] && SCRIPT_DIR="."
SCRIPT_DIR="$(cd "$SCRIPT_DIR" && pwd)"
# shellcheck disable=SC1091
source "$SCRIPT_DIR/shared-config.sh"
JSON_FILE="$1"
# 参数检查
[ -z "$1" ] && { echo "ERROR: usage: validate-step1.sh <json_file>"; exit 1; }
# 检查 jq 是否可用(必需依赖)
command -v jq >/dev/null 2>&1 || {
echo "ERROR: jq is not installed. Install it via:" >&2
print_install_hint jq
exit 1
}
# 检查文件是否存在
[ -f "$JSON_FILE" ] || { echo "ERROR: file not found: $JSON_FILE"; exit 1; }
# 检查是否是有效 JSON
jq empty "$JSON_FILE" 2>/dev/null || { echo "ERROR: invalid JSON format"; exit 1; }
# 检查必需字段存在且类型正确
jq -e '.entities | type == "array"' "$JSON_FILE" >/dev/null 2>&1 || { echo "ERROR: 'entities' must be an array"; exit 1; }
jq -e '.topics | type == "array"' "$JSON_FILE" >/dev/null 2>&1 || { echo "ERROR: 'topics' must be an array"; exit 1; }
jq -e '.connections | type == "array"' "$JSON_FILE" >/dev/null 2>&1 || { echo "ERROR: 'connections' must be an array"; exit 1; }
jq -e '.contradictions | type == "array"' "$JSON_FILE" >/dev/null 2>&1 || { echo "ERROR: 'contradictions' must be an array"; exit 1; }
jq -e '.new_vs_existing | type == "object"' "$JSON_FILE" >/dev/null 2>&1 || { echo "ERROR: 'new_vs_existing' must be an object"; exit 1; }
# 检查每个 entity 的必需子字段
VALID_CONFIDENCE="EXTRACTED|INFERRED|AMBIGUOUS|UNVERIFIED"
ENTITY_COUNT=$(jq '.entities | length' "$JSON_FILE" 2>/dev/null)
if [ "$ENTITY_COUNT" -gt 0 ] 2>/dev/null; then
NON_OBJECT_ENTITY_COUNT=$(jq '[.entities[] | select(type != "object")] | length' "$JSON_FILE" 2>/dev/null)
if [ "$NON_OBJECT_ENTITY_COUNT" -gt 0 ] 2>/dev/null; then
echo "ERROR: $NON_OBJECT_ENTITY_COUNT entity/entities must be objects"
exit 1
fi
# name, type, confidence 必须存在且非空
BAD_ENTITY_COUNT=$(jq '
[.entities[] | select(
(.name // "" | length) == 0 or
(.type // "" | length) == 0 or
(.confidence // "" | length) == 0
)] | length
' "$JSON_FILE" 2>/dev/null)
if [ "$BAD_ENTITY_COUNT" -gt 0 ] 2>/dev/null; then
echo "ERROR: $BAD_ENTITY_COUNT entity/entities missing required fields (name/type/confidence)"
exit 1
fi
# confidence 值必须是四个有效值之一
INVALID=$(jq -r '.entities[]? | (.confidence // "MISSING")' "$JSON_FILE" 2>/dev/null | \
grep -v -E "^($VALID_CONFIDENCE)$" | head -3)
if [ -n "$INVALID" ]; then
echo "ERROR: invalid entity confidence value(s): $INVALID"
echo " Valid values: EXTRACTED | INFERRED | AMBIGUOUS | UNVERIFIED"
exit 1
fi
# EXTRACTED 和 INFERRED 必须提供 evidence 字段
NO_EVIDENCE_COUNT=$(jq '
[.entities[] | select(
(.confidence == "EXTRACTED" or .confidence == "INFERRED") and
((.evidence // "" | length) == 0)
)] | length
' "$JSON_FILE" 2>/dev/null)
if [ "$NO_EVIDENCE_COUNT" -gt 0 ] 2>/dev/null; then
echo "WARN: $NO_EVIDENCE_COUNT entity/entities with EXTRACTED/INFERRED confidence missing 'evidence' field"
fi
fi
# 检查每个 topic 的必需子字段
TOPIC_COUNT=$(jq '.topics | length' "$JSON_FILE" 2>/dev/null)
if [ "$TOPIC_COUNT" -gt 0 ] 2>/dev/null; then
NON_OBJECT_TOPIC_COUNT=$(jq '[.topics[] | select(type != "object")] | length' "$JSON_FILE" 2>/dev/null)
if [ "$NON_OBJECT_TOPIC_COUNT" -gt 0 ] 2>/dev/null; then
echo "ERROR: $NON_OBJECT_TOPIC_COUNT topic(s) must be objects"
exit 1
fi
BAD_TOPIC_COUNT=$(jq '
[.topics[] | select(
(.name // "" | length) == 0
)] | length
' "$JSON_FILE" 2>/dev/null)
if [ "$BAD_TOPIC_COUNT" -gt 0 ] 2>/dev/null; then
echo "ERROR: $BAD_TOPIC_COUNT topic(s) missing required 'name' field"
exit 1
fi
fi
# 检查每个 connection 的必需子字段(from, to, confidence
CONN_COUNT=$(jq '.connections | length' "$JSON_FILE" 2>/dev/null)
if [ "$CONN_COUNT" -gt 0 ] 2>/dev/null; then
NON_OBJECT_CONN_COUNT=$(jq '[.connections[] | select(type != "object")] | length' "$JSON_FILE" 2>/dev/null)
if [ "$NON_OBJECT_CONN_COUNT" -gt 0 ] 2>/dev/null; then
echo "ERROR: $NON_OBJECT_CONN_COUNT connection(s) must be objects"
exit 1
fi
BAD_CONN_COUNT=$(jq '
[.connections[] | select(
(.from // "" | length) == 0 or
(.to // "" | length) == 0 or
(.confidence // "" | length) == 0
)] | length
' "$JSON_FILE" 2>/dev/null)
if [ "$BAD_CONN_COUNT" -gt 0 ] 2>/dev/null; then
echo "ERROR: $BAD_CONN_COUNT connection(s) missing required fields (from/to/confidence)"
exit 1
fi
INVALID_CONN_CONF=$(jq -r '.connections[]? | (.confidence // "MISSING")' "$JSON_FILE" 2>/dev/null | \
grep -v -E "^($VALID_CONFIDENCE)$" | head -3)
if [ -n "$INVALID_CONN_CONF" ]; then
echo "ERROR: invalid connection confidence value(s): $INVALID_CONN_CONF"
echo " Valid values: EXTRACTED | INFERRED | AMBIGUOUS | UNVERIFIED"
exit 1
fi
# EXTRACTED 和 INFERRED connections 必须提供 evidence
NO_CONN_EVIDENCE=$(jq '
[.connections[] | select(
(.confidence == "EXTRACTED" or .confidence == "INFERRED") and
((.evidence // "" | length) == 0)
)] | length
' "$JSON_FILE" 2>/dev/null)
if [ "$NO_CONN_EVIDENCE" -gt 0 ] 2>/dev/null; then
echo "WARN: $NO_CONN_EVIDENCE connection(s) with EXTRACTED/INFERRED confidence missing 'evidence' field"
fi
fi
echo "OK: Step 1 JSON validation passed"
exit 0