基于 LangGraph 开发的多 Agent 工作流系统,用于自动审核和调整大学公众号文章。
- 双节点审核流程: 审核节点 + 调整节点,循环迭代直到通过或达到最大次数
- 双重审核机制: LLM 语义审核 + 本地规则校验(敏感词、长度、必含元素等)
- 健壮的输出解析: 自动剥离思维链内容,兼容多种 JSON 输出格式
- 灵活 LLM 支持: 支持 OpenAI、MiniMax、智谱、Anthropic Claude 等多种模型
- 可配置 Prompt: 通过 YAML 文件自定义审核和调整节点的提示词
- 可配置规则: 支持敏感词过滤、格式规范、内容长度等审核规则
- 状态追踪: 完整记录审核状态、迭代次数、拒绝原因等
newsAgent/
├── agent/
│ ├── __init__.py # 模块导出
│ ├── client.py # LLM 客户端(多 provider 支持)
│ ├── nodes.py # LangGraph 节点定义
│ ├── state.py # Agent 状态定义
│ └── workflow.py # 工作流构建
├── config/
│ ├── prompts.yaml # Prompt 模板配置
│ ├── models.yaml # LLM 模型配置
│ └── rules.yaml # 审核规则配置
├── schemas/
│ └── article.py # 数据模型
├── main.py # 命令行入口
├── pyproject.toml # 项目配置
└── requirements.txt # 依赖列表
uv sync
# 或
pip install -r requirements.txt编辑 config/models.yaml,配置您的模型 API:
models:
review:
provider: "openai" # openai | anthropic | claude | minimax | zhipu
model: "gpt-4"
api_base: "https://api.openai.com/v1"
api_key: "${OPENAI_API_KEY}"
temperature: 0.7
adjust:
provider: "openai"
model: "gpt-4"
api_base: "https://api.openai.com/v1"
api_key: "${OPENAI_API_KEY}"
temperature: 0.7| Provider | 说明 | API 类型 |
|---|---|---|
openai |
OpenAI 官方 API | OpenAI Chat Completions |
anthropic |
Anthropic Claude API | Anthropic Messages |
claude |
Anthropic Claude API(anthropic 的别名) |
Anthropic Messages |
minimax |
MiniMax API | OpenAI 兼容 |
zhipu |
智谱 AI | OpenAI 兼容 |
custom |
自定义 OpenAI 兼容接口 | OpenAI Chat Completions |
编辑 config/prompts.yaml 自定义审核和调整行为:
prompts:
review:
system: |
你是一位大学公众号文章审核员...
以下是当前启用的审核规则(Markdown):
{{RULES_MD}}
user_template: |
请审核以下文章:
标题:{title}
内容:
{content}
adjust:
system: |
你是一位大学公众号文章编辑...
user_template: |
原始文章:
{original}
审核反馈:
{feedback}提示:
{{RULES_MD}}是规则占位符,会在调用时替换为格式化的规则内容。如需启用请在review_prompts的system中保留此占位符。
编辑 config/rules.yaml 设置审核规则。审核节点会同时执行 LLM 语义审核和本地规则校验:
rules:
# 敏感词检查
sensitive_words:
- "敏感词1"
- "敏感词2"
# 格式规范
format:
max_title_length: 30 # 标题最大字数
max_paragraph_length: 300 # 段落最大字数
# 内容要求
content:
min_length: 100 # 正文最少字数
max_length: 5000 # 正文最多字数
required_elements: # 必含元素
- "来源"命令行用法:
# 通过参数传入文章
python main.py "文章内容" "文章标题"
# 通过 stdin 传入文章
echo "文章内容" | python main.py - "标题"
# 指定最大迭代次数
python main.py "文章内容" "标题" --max-iterations 3Python API 用法:
from main import ArticleReviewAgent
agent = ArticleReviewAgent()
result = agent.review("文章内容", "标题")
print(f"审核状态: {result['status']}") # approved / rejected / max_iterations
print(f"是否通过: {result['approved']}") # True / False
print(f"迭代次数: {result['iteration']}")
print(f"最终文章: {result['final_article']}")
print(f"审核结果: {result['review_result']}")┌─────────────────────────────────────────────────────────────┐
│ START │
└─────────────────────────┬───────────────────────────────────┘
│
▼
┌───────────────────────────┐
│ REVIEW 节点 │
│ ┌─────────────────────┐ │
│ │ 1. LLM 语义审核 │ │
│ │ (JSON 输出) │ │
│ ├─────────────────────┤ │
│ │ 2. 本地规则校验 │ │
│ │ (敏感词/长度等) │ │
│ └─────────────────────┘ │
└───────────┬───────────────┘
│
┌─────────────┴─────────────┐
│ │
通过 不通过
│ │
▼ ▼
┌─────────┐ ┌─────────────────┐
│ END │ │ ADJUST 节点 │
│ (通过) │ │ (调整 LLM) │
└─────────┘ └────────┬────────┘
│
│ iteration + 1
▼
┌───────────────────────────┐
│ REVIEW 节点 │
│ (再次审核) │
└───────────┬───────────────┘
│
┌─────────┴─────────┐
│ │
通过 不通过
│ │
▼ ┌────────┴────────┐
┌─────────┐ │ iteration >= │
│ END │ │ max_iterations │
│ (通过) │ │ ? │
└─────────┘ └────────┬────────┘
│
YES ───┴─── NO
│ │
▼ ▼
┌─────────┐ ┌─────────┐
│ END │ │ ADJUST │
│ (拒绝) │ │ (继续) │
└─────────┘ └─────────┘
审核节点包含两层校验:
-
LLM 语义审核: 调用 LLM 对文章内容进行语义层面的质量评估
- 强制 JSON 输出格式
- 自动剥离思维链(think/reasoning)内容
- 兼容多种 JSON 解析策略
-
本地规则校验: 基于
rules.yaml配置进行结构化校验- 敏感词检测
- 标题长度限制
- 段落长度限制
- 正文字数限制
- 必含元素检查
两层校验结果会合并,任何一层不通过都会标记为不通过。
{
"status": "approved",
"approved": true,
"iteration": 2,
"final_article": "经过调整后的文章内容...",
"review_result": {
"approved": true,
"reasons": [],
"suggestions": [],
"comment": "文章审核通过,内容质量良好。"
}
}在 agent/client.py 中添加新的客户端类:
class MyClient(LLMClient):
def __init__(self, api_key: str, model: str, api_base: str, **kwargs):
...
def generate(self, prompt: str, **kwargs) -> str:
# 实现 API 调用逻辑
...
# 在 create_llm_client 工厂函数中添加:
elif provider == "myprovider":
return MyClient(...)修改 agent/nodes.py 中的 review_node 和 adjust_node 函数来自定义节点行为。
| 变量名 | 说明 |
|---|---|
OPENAI_API_KEY |
OpenAI API Key |
ANTHROPIC_API_KEY |
Anthropic API Key |
| 其他 | 通过 ${VAR_NAME} 语法在配置文件中引用 |
MIT License