Skip to main content
Glama

paeg-lang-style

Python License: MIT Tests PRs Welcome

中文 | English


Qué es esto

paeg-lang-style es un módulo de normas lingüísticas del chino — arquitectura de tres capas (requisito del usuario):

Capa

Capacidad

Archivo principal

Restricción de reglas gramaticales (la más importante)

Reglas léxicas/sintácticas/de puntuación como prompt del sistema, que dirigen al LLM a usar palabras completas, sintaxis completa y complementos circunstanciales suficientes — quien lo use lo ensambla

rule_registry.py + prompts/builder.py

Red de seguridad de palabras prohibidas

Diccionario de palabras prohibidas mantenido dinámicamente (lenguaje artificial de IA/palabras grandilocuentes vacías/falsa empatía/ánimos baratos/lenguaje de internet), como línea de defensa cuando el LLM no obedece

forbidden.py

Script de reescritura

Postprocesado de la salida del LLM: detecta reglas incumplidas → retroalimentación con ID de regla → reescritura Self-Refine en múltiples rondas

refiner.py + gate.py

Originado del agente educativo PAEG (iteraciones v0.12-v0.71), transformado en un plugin independiente sin dependencias del host — cualquier proyecto Python puede integrarlo.

Related MCP server: Chinese Sensitive Words MCP Server

Características principales

  • Conjunto de reglas ampliable: reglas externalizadas en data/rules.json, añadir y se carga en caliente (RuleRegistry)

  • Principios generales que dirigen al LLM: los principios de completitud léxica/completitud sintáctica/complementos circunstanciales suficientes hacen que el LLM generalice, en lugar de memorizar palabra por palabra (evita la estrechez de "solo convertir 倦 en 疲倦")

  • Red de seguridad determinista: reglas de capa explícita ("我在这里听着你。"→"我就在这里听你说说。") evitan que el LLM desobedezca

  • Bucle de retroalimentación con ID de regla: la retroalimentación de reescritura incluye "viola #rule-lx-001", formando un bucle regla-generación-retroalimentación

  • Diccionario dinámico de palabras prohibidas: alta/baja en tiempo de ejecución + carga en caliente desde JSON externo

  • Diseño por inyección: chat_fn se inyecta obligatoriamente — conecta tu propia llamada al LLM, cero acoplamiento con el host

  • Tres perfiles: general / teaching / confessional — ensambla el prompt del sistema según el escenario

  • Detección de sabor IA: 5 señales dimensionales: variación de longitud de frase/densidad de conectores/estructura de tres partes/raya/paralelismo de párrafos

  • 8+ reglas gramaticales: norma de puntuación GB/T 15834 + seis tipos de frases incorrectas + normas del lenguaje docente

  • 75 pruebas en verde + 20 segmentos de consistencia de comportamiento (igualdad de cadenas con la implementación original de PAEG)

Instalación

# 方式 1:pip 安装(推荐)
pip install -e /path/to/paeg-lang-style-plugin

# 方式 2:直接引用(零安装)
# 把 src/ 加入 sys.path 即可
import sys
sys.path.insert(0, "/path/to/paeg-lang-style-plugin/src")

Requiere Python 3.9+. Cero dependencias de terceros en tiempo de ejecución.

Integración como servidor MCP (instala y úsalo directamente, como MCP)

Estándar de accesibilidad (§3.109): cualquier proyecto, tras pip install, puede integrarse declarándolo en la configuración del cliente MCP — cero puente de código, cero dependencias del host.

# 方式 1:console_scripts 入口(pip install 后)
paeg-lang-style-mcp

# 方式 2:python -m 入口(源码运行)
python -m paeg_lang_style.mcp_server

Declaración de configuración del cliente MCP (p. ej. config/mcp_servers.json):

{
  "mcpServers": {
    "paeg-lang-style": {
      "command": "python",
      "args": ["-m", "paeg_lang_style.mcp_server"],
      "cwd": "D:/wbo-workspace/paeg_project/paeg-lang-style-plugin"
    }
  }
}

Herramientas MCP expuestas (7):

Nombre de la herramienta

Función

read/write

normalize_text

Puerta de normas lingüísticas del texto (reglas L0 + reescritura L2)

read

language_policy_check

Detección de sabor IA + informe de palabras prohibidas encontradas

read

forbidden_words

Gestión del diccionario dinámico de palabras prohibidas (alta/baja/consulta)

write

check_grammar

Comprobación gramatical (8 tipos de reglas)

read

check_ai_taste

Señales de sabor IA en 5 dimensiones

read

build_style_prompt

Ensamblaje del prompt del sistema (quien lo use lo ensambla)

read

list_rules

Listado del conjunto de reglas ampliable

read

Inicio rápido

Tres pasos: instalar → ensamblar el prompt → procesar la salida.

from paeg_lang_style import RuleRegistry, make_refiner, gate_content

# Step 1: 语法规则拼进你的系统提示词(谁用都拼)
system_prompt = "你是教育智能体,负责讲解数学概念。"
system_prompt += RuleRegistry().build_prompt("teaching")   # 通则层指挥 LLM

# Step 2: 注入你的 LLM 调用(改写脚本)
def my_llm(system, user, max_tokens=800, **kw):
    return call_my_llm_api(system, user, max_tokens=max_tokens)

refiner = make_refiner(chat_fn=my_llm)

# Step 3: LLM 输出后处理(L0 规则 + L2 重写)
raw_output = "总的来说,让我们一起赋能这个时代!"
clean = gate_content(raw_output, refiner=refiner)
# → "我们把这个时代里的每一个孩子,把他们的潜能一步步唤起。"

Índice

Conceptos principales

Arquitectura de tres capas + modelo de datos del conjunto de reglas — la ampliabilidad atraviesa los tres puntos: definición de reglas/detección/generación de prompts:

graph LR
    A[LLM 生成文本] --> B[gate_content 守门]
    B --> C{L0 规则检测}
    C -->|命中列举层| D[确定性替换<br/>听着你→听你说说]
    C -->|通则触发| E[L2 refiner.refine<br/>chat_fn 注入 LLM]
    E --> F[反馈带规则 ID<br/>违反 #rule-lx-001]
    F --> G[多轮 Self-Refine]
    D --> H[输出]
    G --> H
    H --> I[收口: 规则再跑一遍]

Modelo de datos de reglas (Rule — ampliable mediante JSON externo):

{
  "id": "rule-lx-general-001",
  "type": "general",
  "category": "lexical",
  "pattern": "(倦|乏|沉|累|苦|慌|虚|弱|低|烦|闷|困|急|乱)",
  "replacement": null,
  "message": "存在单字状态词——应扩展为完整双字词形",
  "prompt_block": "### 词法完整通则(指挥 LLM 泛化)...",
  "severity": "high",
  "enabled": true,
  "source": "builtin",
  "profile_tags": ["general", "teaching", "confessional"]
}
  • type: "general" (capa de principios generales): prompt_block se inserta en el prompt del sistema y dirige al LLM a generalizar — "todo adjetivo monosilábico que exprese estado/sensación debe ampliarse a la forma bisilábica completa (倦/乏/沉/累/苦/慌/虚/弱/低/烦/闷/困/急/乱)". El LLM generaliza por sí mismo a palabras no enumeradas, en lugar de corregir solo "倦→疲倦".

  • type: "explicit" (capa explícita): pattern + replacement como red de seguridad determinista — la última línea de defensa cuando el LLM no obedece.

Guía de integración para proyectos externos

Requisito del usuario: cualquier proyecto/agente que quiera usar nuestro módulo de reglas gramaticales, ¿cómo lo hace?

Escenario A: solo quiero usar la "restricción de reglas gramaticales" (prompt del sistema)

from paeg_lang_style import RuleRegistry

# 语法规则拼进自己的系统提示词(谁用都拼)
system = "你是我的客服机器人。"
system += RuleRegistry().build_prompt("general")   # 或 "teaching" / "confessional"

El fragmento de reglas devuelto por build_prompt(profile) (principio general de completitud léxica/principio general de completitud sintáctica/principio general de complementos circunstanciales suficientes/norma de puntuación) se concatena directamente en el system prompt de tu LLM. Esta es la esencia de "dirigir al LLM a usar palabras completas" — no depende de nuestro reescritor.

Escenario B: quiero usar el "script de reescritura" para procesar la salida del LLM

from paeg_lang_style import make_refiner, gate_content

# 注入你自己的 LLM 调用包装(chat_fn 强制注入,零宿主耦合)
def my_chat(system, user, max_tokens=800, **kw):
    return call_your_llm(system, user, max_tokens=max_tokens)

refiner = make_refiner(chat_fn=my_chat)
clean = gate_content(your_llm_output, refiner=refiner)   # L0 规则 + L2 重写
# 纯规则(不调 LLM):
clean = gate_content(your_llm_output)                    # 病句/违禁词确定性修正

Escenario C: quiero usar el "diccionario de palabras prohibidas"

from paeg_lang_style import ForbiddenWords

fb = ForbiddenWords()                     # 内置违禁词(AI 腔/空洞大词/伪共情/网络用语)
fb.load_json("my_words.json")             # 合并你自己的词库(动态扩充)
fb.add("你们公司的禁词")                  # 运行时新增
hits = fb.detect(text)                    # → ["禁词1", "禁词2"]

Escenario D: quiero ampliar las reglas (ampliabilidad)

Edita data/rules.json, añade una regla y se carga en caliente:

{
  "rules": [
    {
      "id": "rule-my-001",
      "type": "explicit",
      "category": "lexical",
      "pattern": "你们行业的黑话",
      "replacement": "规范说法",
      "message": "这是行业黑话,应改规范",
      "severity": "medium",
      "enabled": true,
      "source": "user",
      "profile_tags": ["general"]
    }
  ]
}
reg = RuleRegistry()
reg.load("data/rules.json")    # 合并(追加即生效)
reg.watch("data/rules.json")   # mtime 变更自动热重载
reg.check_reload()             # 每次调用前检查

Escenario E: integración completa (incluido el bucle de retroalimentación con ID de regla)

from paeg_lang_style import RuleRegistry, make_refiner, gate_content, get_style_prompt

# 1. 系统提示词(规则 + 风格)
system = get_style_prompt("all") + "\n" + RuleRegistry().build_prompt("general")

# 2. 改写器(规则检测 → 反馈带 ID → 重写)
refiner = make_refiner(chat_fn=my_chat)

# 3. 守门(L0 规则 + L2 重写 + 收口)
final = gate_content(raw, refiner=refiner)

Ampliabilidad

Punto de ampliación

Forma

Mecanismo

Reglas gramaticales

Editar data/rules.json y añadir una Rule

RuleRegistry.load() fusiona + watch() recarga en caliente + variable de entorno PAEG_RULES_PATH para sobrescribir la ruta

Palabras prohibidas

ForbiddenWords.load_json("custom.json") / add() / remove()

Mantenimiento dinámico en tiempo de ejecución

Corpus

Sustituir data/weil_corpus.json por un corpus neutro

Parámetro corpus_path en el constructor

Perfil

Añadir profile_tags al crear una regla

build_prompt(profile) filtra por escenario

Backend LLM

Inyectar cualquier chat_fn

Inyección obligatoria, cero acoplamiento con el host

Contrato de ID de regla

El id de la regla es estable, la retroalimentación lo referencia

Bucle regla-generación-retroalimentación, apto para telemetría

Mantenibilidad

  • Cero dependencias del host: no importa ningún módulo del proyecto host, comprobable de forma independiente

  • Compatibilidad con API antigua: rules.py/rules_enhanced.py se conservan como envoltorios finos, compatibles hacia atrás

  • 75 pruebas: cobertura completa de carga del conjunto de reglas/recarga en caliente/detección/ensamblaje/ampliación por el usuario/tolerancia a corrupción

  • Consistencia de comportamiento: 20 segmentos de muestra con igualdad de cadenas frente a la implementación original de PAEG (cero deriva)

  • Tolerancia a corrupción: si el JSON se corrompe, se conserva el conjunto de reglas anterior, nunca "se vacía y se ejecuta"

  • Anti-inflación: token_budget controla la longitud del prompt del sistema (por defecto 800)

  • Patrón claro: separación de responsabilidades entre la capa de principios generales (dirige al LLM) y la capa explícita (red de seguridad determinista)

Reglas gramaticales integradas

ID

Tipo

Categoría

Regla

Patrón de activación

Corrección

rule-lx-general-001

Principio general

Léxico

Completitud léxica

Palabras de estado monosilábicas (倦/乏/沉/累/苦/慌/虚/弱/低/烦/闷/困/急/乱)

Ampliar a forma bisilábica completa

rule-sx-general-001

Principio general

Sintaxis

Completitud sintáctica

Sujeto-verbo-objeto/verbo-objeto/preposición/oración compuesta

Componentes completos

rule-sx-general-002

Principio general

Sintaxis

Complementos circunstanciales suficientes

Frases cortas que empiezan por verbo/verbos aislados solos

Añadir complementos de tiempo/lugar/modo/condición/objeto/finalidad

rule-pn-general-001

Principio general

Puntuación

Norma de puntuación (GB/T 15834)

Coma de enumeración vs coma/coma tras "decir"

Puntuación normativa

rule-lx-001

Explícita

Léxico

倦→疲倦

觉得倦了|感到倦|已倦

Sustitución determinista

rule-lx-002

Explícita

Léxico

乏→疲乏

的乏($|[,。;])

Sustitución determinista

rule-lx-003

Explícita

Léxico

道出→说出来

道出

Sustitución determinista

rule-lx-004

Explícita

Léxico

探知→探索并了解

探知

Sustitución determinista

rule-sx-001~004

Explícita

Sintaxis

"听着你" colgante

(我在这里|在这里|我)?听着你 + final de oración

听你说说

rule-sx-005

Explícita

Sintaxis

Objeto colgante

与你探讨$ etc.

Completar el objeto

rule-sx-006

Explícita

Sintaxis

Concordancia verbo-objeto

带着(重量|分量)

有很重的分量

rule-sx-007

Explícita

Sintaxis

Redundancia de traducción

进行(一个)?(分析|讨论|思考)

Decir directamente el verbo

rule-pn-001

Explícita

Puntuación

Coma tras "decir"

说:"

Usar coma en su lugar

Detalle del principio general de complementos circunstanciales suficientes (rule-sx-general-002, añadido por el usuario):

Cada acción/juicio debe explicitarse con complementos circunstanciales suficientes — tiempo, lugar, modo, condición, objeto, finalidad. "复习单词。" → "你可以在每天睡前用十分钟复习单词。" "使用这个软件。" → "你可以在每天固定的时间使用这个软件。"

Diccionario de palabras prohibidas

Categoría

Ejemplos

Frases hechas de IA

总的来说 / 综上所述 / 值得注意的是 / 让我们一起

Palabras grandilocuentes vacías

赋能 / 点亮 / 激活 / 重塑 / 升级 / 全方位

Verbos de falsa empatía

接住(情绪)/ 托住 / 兜住 / 我懂你 / 心疼你

Ánimos baratos

加油 / 你真棒 / 你一定可以

Lenguaje de internet de baja calidad

yyds / 绝绝子 / 栓Q / 破防 / 内卷 / 躺平 / 宝子

Adjetivos de elogio vacíos

深刻 / 全面 / 系统 / 本质

Forma de ampliación: ForbiddenWords().load_json("path.json") — estructura JSON {"extra_forbidden": [...], "ai_tells_extra": [...]}.

Referencia de API

RuleRegistry

Método

Firma

Descripción

all()

() -> list[Rule]

Todas las reglas

by_id(id)

(str) -> Rule|None

Consultar regla por ID

add_rule(rule)

(dict) -> bool

Añadir en tiempo de ejecución (mismo ID sobrescribe la integrada)

remove_rule(id)

(str) -> bool

Eliminar en tiempo de ejecución

load(path)

(str|None) -> int

Fusionar JSON externo (carga en caliente)

watch(path)

(str|None) -> None

Monitorización de mtime

check_reload()

() -> bool

Comprobar y recargar

detect(text, profile)

(str, str|None) -> list[Rule]

Detectar reglas incumplidas

apply_explicit(text, profile)

(str, str|None) -> str

Sustitución determinista

build_prompt(profile, token_budget)

(str, int) -> str

Ensamblar prompt del sistema

LanguageRefiner / make_refiner

Método

Firma

Descripción

make_refiner(chat_fn, llm, corpus_path)

(*, chat_fn, ...) -> LanguageRefiner

Fábrica (chat_fn obligatorio)

refine(text, context, max_rounds)

(str, str, int) -> str

Reescritura Self-Refine en múltiples rondas

check_grammar(text)

(str) -> list

Comprobación gramatical

detect_ai_tells(text)

(str) -> list

Palabras prohibidas encontradas

detect_ai_taste_signals(text)

(str) -> AITasteSignals

Señales de sabor IA

gate_content / gate_short

Función

Firma

Descripción

gate_content(text, context, apply_l2, refiner, polish_fn)

(str, str, bool, refiner|None, fn|None) -> str

Reglas L0 + reescritura L2

gate_short(text, context, refiner, polish_fn)

(str, str, ...) -> str

Ruta rápida para textos cortos (solo L0)

ForbiddenWords

Método

Firma

Descripción

add(word) / remove(word)

(str) -> bool

Alta/baja en tiempo de ejecución

load_json(path)

(str|None) -> int

Fusionar diccionario externo

detect(text)

(str) -> list

Lista de palabras encontradas

detect_count(text)

(str) -> int

Total de coincidencias

get_style_prompt

Parámetro

Descripción

"all"

Prompt completo de estilo lingüístico

"weil" / "lexicon" / "syntax" / "forbidden"

Por secciones

["weil", "syntax"]

Concatenación de varias secciones

Referencia de configuración

Variables de entorno

Variable

Valor por defecto

Descripción

PAEG_RULES_PATH

src/paeg_lang_style/data/rules.json

Sobrescribir la ruta del conjunto de reglas

Archivos data/

Archivo

Uso

Ampliable

data/rules.json

Conjunto de reglas gramaticales

Sí, añadir y se carga en caliente

data/forbidden_words.json

Diccionario de palabras prohibidas

Sí, mantenimiento dinámico

data/weil_corpus.json

Corpus few-shot

Sí, sustituible

Diseño de arquitectura

宿主系统(任何 Python 项目 / 智能体)
  system_prompt += RuleRegistry().build_prompt()    <- 语法规则拼系统提示词(谁用都拼)
  gate_content(output, refiner=make_refiner(chat))  <- 输出后处理
        |
        | 零宿主依赖(不 import 宿主任何模块)
        v
paeg_lang_style(独立插件)
  +------------------+  +-----------------+  +-----------------+
  | rule_registry    |  | forbidden.py    |  | ai_taste.py     |
  | 可扩充规则集      |  | 动态违禁词库     |  | AI 味检测        |
  +--------+---------+  +--------+--------+  +--------+--------+
           |                    |                     |
           v                    v                     v
  +-----------------------------------------------------------+
  | refiner.py(改写脚本:chat_fn 注入 + 规则 ID 闭环)           |
  | gate.py(守门入口:L0+L2 编排)                              |
  +-----------------------------------------------------------+
  data/(rules.json / forbidden_words.json / 语料)

Integración con el proyecto principal PAEG

El agente educativo PAEG se integra mediante la única capa de adaptación infra/lang_plugin_bridge.py (regla de hierro R18/R20 de cero rupturas):

from infra.lang_plugin_bridge import gate_content, get_style_prompt, make_refiner
# 插件挂载 → 走插件;插件未挂载 → 静默回退 PAEG 原实现(旧文件永不删除)

Ver docs/integration_paeg.md.

Pruebas

python -m pytest tests/ -q
# 75 项:规则集加载/热重载/检测/拼装/用户扩充/损坏容错 + 通则 + 充分状语 + 行为一致性

Guía de contribución

¡Las contribuciones son bienvenidas! Consulta CONTRIBUTING.md (pendiente de creación) para saber:

  • Nueva regla de sintaxis: edite data/rules.json para añadir Rule (con pruebas)

  • Nueva palabra prohibida: ForbiddenWords.load_json o envíe directamente un PR al diccionario integrado

  • Estilo de código: siga la estructura de módulos existente + las normas de comentarios

Registro de cambios

Consulte CHANGELOG.md.

Agradecimientos

  • Agente educativo PAEG (iteraciones v0.12-v0.71) — este plugin se extrajo de su módulo de especificaciones lingüísticas

  • LanguageTool — paradigma de motor declarativo de reglas (dev.languagetool.org)

  • textstat — paradigma de medición de legibilidad (github.com/textstat/textstat)

  • GB/T 15834-2011《Uso de los signos de puntuación》 — norma nacional para las reglas de puntuación

  • Estándar Agent Skills — paradigma de divulgación progresiva (agentskills.io)

Licencia

MIT © 2026 PAEG Team — consulte el archivo LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    B
    maintenance
    Local-first toolkit with 16 tools for Chinese web-novel (网文) authors: style baselines, foreshadowing and plot-thread tracking, continuity & OOC audits, keyword and sentence-pattern analysis, and offline semantic search. No API key, no network — everything runs on your machine.
    19
    986 npm
    22
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Provides AI models with tools to proofread and format Chinese text before delivery, covering typos, punctuation, casing, spacing, and platform-specific character limits. It runs as a zero-dependency MCP service so the model checks and fixes its own Chinese writing automatically.
    4
    1
    MIT