# article_writer_agent **Repository Path**: scedm/article_writer_agent ## Basic Information - **Project Name**: article_writer_agent - **Description**: 基于 OpenAI 兼容 API 的单篇幅中文文章自动写作 CLI 工具。输入主题和参考链接,自动完成资料采集、大纲生成、确认交互、全文写作,最终输出 Markdown 文件。 - **Primary Language**: Python - **License**: AGPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-05-08 - **Last Updated**: 2026-06-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Article Writer Agent 基于 OpenAI 兼容 API 的单篇幅中文文章自动写作 CLI 工具。采用 **Agent + Skills** 插件化架构,Agent 通过 Function Calling API 自主调度 Skill 工具完成文章写作全流程。 ## 功能特性 - **Agent 自主决策** — LLM 通过 Function Calling API 自主选择调用哪个 Skill 工具,动态决策 - **插件化 Skills** — 研究抓取、大纲生成、逐节写作、润色等能力以 Skill 插件形式封装,可扩展 - **多参考链接** — 支持输入多个 URL,自动抓取正文内容作为写作素材 - **网络搜索补充** — 基于主题自动搜索补充背景资料(DuckDuckGo / Tavily / Serper) - **大纲确认 (Checkpoint)** — 大纲生成后暂停,用户可确认、编辑、或重新生成 - **流式写作** — 逐小节流式输出,实时查看写作进度 - **小节连贯性** — 每节写完后生成摘要传入下一节,保持全文连贯 - **可选润色** — 写作完成后可一键调用 LLM 润色优化 - **多模型支持** — 通过 OpenAI 兼容接口接入 GPT、Claude、DeepSeek 等任意后端 ## 工作流程 ``` 用户输入 (主题 + 参考链接 + 风格 + 字数) ↓ Agent 启动 (Function Calling 循环) ↓ 1. 资料收集 (ResearchSkill) ├─ fetch_urls: 抓取参考链接正文 ├─ web_search: 搜索补充资料 └─ synthesize_research: LLM 综合为结构化摘要 ↓ 2. 大纲生成 (OutlineSkill) └─ generate_outline → Checkpoint 暂停 ├─ [A] 确认 → 继续写作 ├─ [E] 编辑器修改 ├─ [I] 交互式编辑 ├─ [R] 重新生成 └─ [Q] 退出 ↓ 3. 逐节写作 (WritingSkill) └─ write_section × N: 逐节流式输出,保持连贯 ↓ 4. 润色优化 (PolishSkill) └─ polish: 全文润色 ↓ 5. 完成 (FinishSkill) └─ finish: 组装文章 + 参考链接 → 保存 Markdown ``` ## 安装 **环境要求**: Python 3.10+ 建议使用虚拟环境隔离依赖: ```bash git clone https://gitee.com/scedm/article_writer_agent.git article_writer_agent cd article_writer_agent # 创建虚拟环境 python3 -m venv venv # 激活虚拟环境 # macOS / Linux: source venv/bin/activate # Windows: # venv\Scripts\activate # 安装依赖 pip install -r requirements.txt ``` ## 快速开始 ### 1. 设置 API Key ```bash export OPENAI_API_KEY="sk-your-api-key" ``` ### 2. 运行 ```bash # 交互式(逐步输入主题、链接、风格、字数) python main.py # 仅用参考链接(不搜索) python main.py -t "Ollama + Gemma4 实现本地大模型安装" -s "技术实战教程" \ -u https://docs.ollama.com/ https://docs.ollama.com/integrations/claude-code # 无链接,自动搜索 python main.py -t "AI Agent 架构设计" -s "深度分析" -l 5000 # 参考链接 + 强制搜索 python main.py -t "AI Agent 架构设计" -u https://example.com/1 --search -s "深度分析" -l 5000 ``` ### 3. 命令行参数 | 参数 | 缩写 | 说明 | | ------------- | ---- | -------------------------------------- | | `--topic` | `-t` | 文章主题 | | `--urls` | `-u` | 参考链接 URL,支持多个(空格分隔) | | `--style` | `-s` | 写作风格,默认"深度分析" | | `--length` | `-l` | 目标字数,默认 4000 | | `--output` | `-o` | 输出文件路径 | | `--config` | `-c` | 自定义配置文件路径 | | `--verbose` | `-v` | 显示详细日志 | | `--no-search` | | 跳过网络搜索,仅使用参考链接 | | `--search` | | 强制启用网络搜索(即使提供了参考链接) | ### 搜索策略 | 场景 | 命令 | 行为 | | ----------------- | ----------------------- | ------------------- | | 提供链接 | `-u url1 url2` | 仅抓取链接,不搜索 | | 提供链接+强制搜索 | `-u url1 url2 --search` | 链接 + 网络搜索补充 | | 无链接 | `-t "主题"` | 网络搜索补充资料 | | 无链接+不搜索 | `-t "主题" --no-search` | 纯 LLM 基于主题生成 | ## 切换 LLM 后端 通过环境变量 `OPENAI_BASE_URL` 和 `OPENAI_MODEL` 切换不同的模型后端: **OpenAI GPT-4o(默认)** ```bash export OPENAI_API_KEY="sk-xxx" python main.py -t "主题" ``` **Claude(通过 OpenRouter)** ```bash export OPENAI_BASE_URL="https://openrouter.ai/api/v1" export OPENAI_API_KEY="or-xxx" export OPENAI_MODEL="anthropic/claude-sonnet-4-20250514" python main.py -t "主题" ``` **本地 Ollama** ```bash export OPENAI_BASE_URL="http://localhost:11434/v1" export OPENAI_API_KEY="ollama" export OPENAI_MODEL="llama3" python main.py -t "主题" ``` **Claude(通过官方代理)** ```bash export OPENAI_BASE_URL="https://your-proxy.com/v1" export OPENAI_API_KEY="your-key" export OPENAI_MODEL="claude-sonnet-4-20250514" python main.py -t "主题" ``` ## 配置说明 配置文件位于 `config/settings.yml`,支持以下配置项: ### Agent 配置 ```yaml agent: max_iterations: 50 # Function Calling 循环最大次数 fallback_to_text_mode: false # Ollama 兼容开关 checkpoint_after: # 触发用户确认的工具 - generate_outline skills_dir: null # 自定义 Skills 目录 ``` ### LLM 配置 ```yaml llm: api_key_env: "OPENAI_API_KEY" base_url_env: "OPENAI_BASE_URL" default_base_url: "https://api.openai.com/v1" model: "gpt-4o" temperature: 0.7 max_tokens: 4096 timeout: 180 max_retries: 3 # 步骤级配置(覆盖默认值) steps: research_synthesis: { temperature: 0.5, max_tokens: 4096 } outline_generation: { temperature: 0.6, max_tokens: 4096 } section_writing: { temperature: 0.7, max_tokens: 8192 } article_polish: { temperature: 0.3, max_tokens: 4096 } ``` ### 搜索配置 ```yaml search: provider: "duckduckgo" max_results: 8 fetch_top_n: 5 language: "zh-CN" ``` ### 文章默认配置 ```yaml article: language: "zh" default_target_length: 4000 min_target_length: 1500 max_target_length: 10000 default_style: "深度分析" ``` ### 上下文截断 ```yaml context: max_research_chars: 60000 max_url_content_chars: 8000 section_context_chars: 2000 ``` ## 环境变量 | 变量 | 必需 | 说明 | | ----------------------- | ---- | ------------------------------- | | `OPENAI_API_KEY` | 是 | LLM API 密钥 | | `OPENAI_BASE_URL` | 否 | 自定义 API 地址(切换模型后端) | | `OPENAI_MODEL` | 否 | 运行时覆盖默认模型 | | `RESEARCH_AGENT_CONFIG` | 否 | 自定义配置文件路径 | | `TAVILY_API_KEY` | 否 | Tavily 搜索 API Key | | `SERPER_API_KEY` | 否 | Serper 搜索 API Key | | `BRAVE_SEARCH_API_KEY` | 否 | Brave 搜索 API Key | ## 项目结构 ``` article_writer_agent/ ├── main.py # CLI 入口 ├── requirements.txt # Python 依赖 ├── CLAUDE.md # Claude Code 项目指引 ├── config/ │ ├── settings.yml # 全局配置 │ └── prompts/ # Prompt 模板 │ ├── agent_system.txt # Agent 系统提示词 │ ├── research_synthesis.txt # 研究资料综合 │ ├── outline_generation.txt # 大纲生成 │ ├── section_writing.txt # 小节写作 │ └── article_polish.txt # 文章润色 ├── src/ │ ├── agent/ # Agent 框架 │ │ ├── core.py # Agent 类(Function Calling 循环) │ │ ├── state.py # AgentState 黑板状态 │ │ ├── skill.py # Skill 基类、ToolDefinition 等 │ │ ├── registry.py # SkillRegistry(注册/发现/调度) │ │ └── checkpoint.py # Checkpoint 处理接口 │ ├── skills/ # 内置 Skills │ │ ├── __init__.py # 自动注册 │ │ ├── research_skill.py # 研究能力(抓取、搜索、综合) │ │ ├── outline_skill.py # 大纲生成 + checkpoint │ │ ├── writing_skill.py # 逐节写作 + 流式输出 │ │ ├── polish_skill.py # 润色优化 │ │ └── finish_skill.py # 组装完成 │ ├── __init__.py │ ├── config_loader.py # 配置加载(YAML + 环境变量) │ ├── llm_client.py # OpenAI 兼容 LLM 客户端 │ ├── web_fetcher.py # 网页抓取 + 多搜索引擎 │ ├── pipeline.py # 旧流水线(保留兼容) │ ├── outline_parser.py # 大纲 Markdown ↔ 结构化解析 │ └── prompts.py # Prompt 模板管理 ├── cli/ # CLI 交互模块 │ ├── __init__.py │ ├── app.py # 主应用(Agent 模式) │ ├── display.py # rich 终端渲染 │ └── editor.py # 大纲编辑器 ├── docs/ │ ├── specs/ # 旧设计文档 │ └── superpowers/ │ ├── specs/ # 设计规格 │ │ └── 2026-05-08-agent-skills-design.md │ └── plans/ # 实现计划 └── output/ # 文章输出目录 ``` ## 自定义 Prompt 模板 所有 Prompt 模板位于 `config/prompts/` 目录,可直接编辑: - `agent_system.txt` — Agent 系统提示词(定义角色和工作原则) - `research_synthesis.txt` — 研究资料综合提示词 - `outline_generation.txt` — 大纲生成提示词 - `section_writing.txt` — 小节写作提示词 - `article_polish.txt` — 文章润色提示词 ## 扩展 Skills 新增 Skill 只需 3 步: 1. 在 `src/skills/` 下创建新文件,定义继承 `Skill` 的类 2. 实现 `get_tools()` 和 `execute_tool()` 方法 3. 在 `src/skills/__init__.py` 的 `create_registry()` 中注册 第三方插件可通过以下方式注册: - `pyproject.toml` 的 `[project.entry-points."article_agent.skills"]` - 放置 `.py` 文件到 `~/.article_agent/skills/` 目录 ## 多 Agent 编排器(Orchestrator) `orchestrator/` 是一个独立的调度 Agent,通过 Function Calling 循环自主决策调用子 Agent,实现「写作 → 发布」等多步任务的自动化编排。详见 [orchestrator/README.md](orchestrator/README.md)。 ### 架构 ``` orchestrator/ ├── main.py # CLI 入口 ├── config.yml # Agent & 发布配置 ├── .env # 环境变量(LLM + 微信凭证) ├── prompts/ │ ├── system.txt # 调度 Agent 系统提示词 │ └── format-template.md # 微信格式化模板 ├── assets/ │ ├── cover.png # 默认封面图 │ └── styles/ │ └── blue.css # 微信主题样式 └── agent/ ├── core.py # Orchestrator — Function Calling 循环 ├── state.py # OrchestratorState — 任务状态 └── tools/ ├── article_writer.py # write_article 子 Agent(subprocess 调用 main.py) └── publisher.py # publish_wechat 子 Agent(格式化 → 发布) ``` ### 工作流程 ``` 用户输入自然语言任务 ↓ 调度 Agent (Orchestrator) ↓ 分析任务 → 自主选择调用子 Agent ↓ ┌─────────────────────────┐ │ write_article │ ← subprocess 调用 article_writer_agent/main.py │ 输入: topic, urls, │ │ style, length │ │ 输出: 文章路径 + 预览 │ └─────────┬───────────────┘ ↓ ┌─────────────────────────┐ │ publish_wechat │ ← 格式化 → 主题 → 预览 → 发布 │ 输入: article_path, │ │ theme, highlight │ │ 输出: 发布结果 │ └─────────────────────────┘ ↓ 汇总结果,向用户报告 ``` ### 使用方式 ```bash cd orchestrator # 仅写作 python main.py "写一篇关于 Rust 异步编程的技术文章" # 写作 + 发布 python main.py "写一篇关于 AI Agent 的文章,然后发布到微信公众号" # 交互式(无参数时提示输入) python main.py ``` Orchestrator 会自动解析自然语言任务,按需调用子 Agent: - 提到「写」「文章」→ 调用 `write_article` - 提到「发布」「公众号」「微信」→ 先写作再调用 `publish_wechat` ### 配置 LLM 和微信凭证通过 `.env` 文件配置(见 `.env.example`),不提交到 git。 `orchestrator/config.yml` 仅保留 Agent 和发布行为配置: ```yaml agent: max_iterations: 20 # 调度循环最大次数 publish: default_theme: "assets/styles/blue.css" highlight: "atom-one-dark" dry_run: false format: use_llm: true max_tokens: 16384 temperature: 0.1 ``` ### 扩展子 Agent 在 `orchestrator/agent/tools/` 下新增工具文件,实现 `get_schema()` 和 `execute()` 两个函数,然后在 `core.py` 的 `_TOOL_SCHEMAS` 和 `_TOOL_EXECUTORS` 中注册即可。 ## 输出示例 生成的 Markdown 文件包含 YAML front matter: ```markdown --- title: "AI Agent 架构设计" date: "2026-05-08" word_count: 4235 sections: 5 model: "gpt-4o" --- # AI Agent 架构设计 ## 引言 ... ``` ### 自动化测试 ``` claude --dangerously-skip-permissions -p "/ralph-loop:ralph-loop '实现画流程图。 需求: - 读取 CLAUDE.md 文件中工作流程 - 风格:dark background, neon accents, monospace font 成功标准: - 所有需求已实现 - 无展示错误 - 文档已更新 完成后输出 COMPLETE。' --max-iterations 30" ``` ## License MIT