Skip to main content

structured-writer — AI Agent

Project description

Structured Writer — 结构化写作智能体

基于 LLM 的结构化长文写作系统。子结构驱动、两级 RAG 增强、续写容断、交互式大纲控制。

核心架构

用户输入主题
  → [大纲规划器] LLM 生成结构化 JSON 大纲(节×子结构)
      → [交互式大纲] 用户可调整:勾选/排序/字数/重点/RAG
          → [串行写作器] 逐子结构调用 LLM 写作
              ├─ 节级别 RAG 查询(背景资料)
              ├─ 子结构级别 RAG 查询(针对性资料)
              ├─ 前文上下文注入(保连贯性)
              └─ token 耗尽自动续写
                  → 合并 .md 输出

特性

特性 说明
子结构系统 每节自动分解为 2-4 个子结构,逐子结构串行写作,### 标题分隔
两级 RAG 节级别查背景资料 + 子结构级别查针对性资料,prompt 分两段注入
续写机制 检测 finish_reason="length" 自动续写,最多 5 轮。空内容跳过续写
交互式大纲 勾选/取消节和子结构、阿拉伯数字排序、罗马数字子结构排序、字数编辑、重点标记
大纲双级排序 节:1-N;子结构:i-iv(每节独立)
多模板 通用公文/新闻报道/论文综述/技术报告/自定义,切换即生效
实时进度 写作过程显示进度条 + 状态文本(RAG查询/写作中/完成)
会话恢复 断线重连后恢复大纲和进度
RAG 冷启动 配置页一键启动 rag-assistant 子进程,自动检测在线状态

快速开始

pip install structured-writer-ldxs
structured-writer-ldxs --port 8770

打开 http://localhost:8770

配置

配置 Tab 设置写作者模型(LM Studio / Ollama)、规划者模型、上下文窗口、提示词模板。

模型推荐

角色 推荐模型 注意事项
写作者 Qwen3.5-35b-A3B / 同级别 推理模型 max_tokens 建议 ≥8192
规划者 Qwen3.5-35b-A3B / 同级别 大纲生成需要语义理解能力

RAG 对接

本系统依赖 rag-assistant 的知识库查询能力:

  1. 启动 rag-assistant(或通过配置页一键冷启动)
  2. 配置页填入 rag-assistant 路径,点击冷启动
  3. 大纲中勾选 RAG + 选择知识库
  4. 系统自动做两级 RAG 查询:节背景 + 子结构针对性

高级用法

大纲勾选

取消勾选的节/子结构在生成时完全跳过,不写标题也不占字数。

续写

LLM 输出被 max_tokens 截断时自动追加"请继续写"指令重试。content 为空(推理吃光 token)时放弃续写,不卡死。

PyPI

pip install structured-writer-ldxs

许可证

Apache 2.0 © wUwproject


更新说明

[1.1.0b0] - 2026-07-28

新增

  • 五元组结构化模板系统:模板从纯文本提示词升级为 {name, show_label, desc, source, type} 五元组结构,一份数据结构同时定义元数据(标题/作者/单位等)和内容树(引言/正文/结论/参考文献等),覆盖日常写作/学术论文/正式公文/新闻报道/技术报告全部类型
  • 动态 Planner prompt 生成plan_outline() 根据五元组按 source=user/llm/auto 分类处理,user 字段不碰、llm 字段必生成、auto 字段用户可填留空 LLM 兜底
  • type:leaf 节支持:无子结构的扁平节(标题/关键词/摘要/参考文献等),渲染跳过 ### 标题,直接写内容在 ##
  • meta 块输出:文章全文前插入 > 名称:值 元数据块,按 show_label 控制前缀显隐
  • 结构表格编辑器:配置 tab 新增五列可编辑表格(名称/显示/字段意义/填写者/子结构类型)+ 纯展示"渲染"列(自动推导字段出现在聊天输入框还是大纲节)
  • 字段意义模态框:点击表格行中的"字段意义"预览文字弹出 modal textarea,支持长文本编辑,表格中显示截断预览
  • LLM 对话生成模板:配置 tab "从对话生成" 按钮 → 弹窗输入描述 + 可选模板名称 → LLM 自动生成五元组结构 + 风格提示词 → 保存为自定义模板
  • 动态 meta 输入框:根据模板 source=user/auto 的字段,在聊天气泡下方按 4 列 grid 动态渲染输入框,值自动传给 Planner
  • 模板搜索排序:下拉框按拼音字母排序,"自定义"永远在最后
  • 内置模板元数据字段:学术论文/正式公文等新模板预置作者/单位/文号/关键词等字段
  • 模板选择持久化:切换模板时自动保存 selected_template 到 config.json,重启后恢复
  • ThreadingHTTPServer:从单线程 HTTPServer 升级为多线程,LLM 请求不阻塞其他 API(归档/配置/进度)
  • 删除会话双击确认:归档会话的删除按钮,第一次单击变红显示"确认?",2.5 秒内再点执行删除,替代 confirm() 浏览器弹窗
  • favicon 静默处理:返回 204 No Content,消除控制台 404

变更

  • config.json 模板格式重构:templates{"名": "字符串"} 升级为 {"名": {"structure": [五元组], "style": "字符串"}}
  • planner.py 接口变更:plan_outline() 新增 templateuser_meta 参数,旧字符串调用兼容
  • writer.py 接口变更:generate_article() 新增 template 参数(用于 meta 渲染),默认 None 兼容旧调用
  • web_ui.py 路由表新增 /api/gen-template/favicon.ico
  • config_manager.py 新增旧格式自动迁移 + "自定义"模板硬保护

修复

  • const label 重复声明导致 JS 加载失败 → 删掉重复行
  • 从对话生成模板 max_tokens=4096 导致 JSON 截断 → 改为 None(走配置值)加 3 次重试 + 多级 JSON 容错解析
  • HTTPServer 单线程阻塞 UI → 替换为 ThreadingHTTPServer
  • onTemplateChange() 未持久化 selected_template → 切换时自动保存
  • 模板下拉框排序混乱 → 拼音字母排序 + "自定义"永远最后
  • 旧纯字符串模板格式迁移 → config_manager.py load() 自动检测+转换

新增

  • 每子结构字数可编辑:章节字数改为子结构字数之和(自动实时求和),子结构字数输入框直接可改;取消勾选的子结构不计入章节字数
  • 进度条按过滤后子结构总数计算:取消勾选的子结构不再计入进度分母
  • RAG 离线时复选框禁用:8767 未上线时 RAG 复选框 disabled+title 提示;上线后自动同步 KB 下拉框
  • 子结构辅助知识模态框:每个子结构 "+" 按钮 → 弹窗支持文本输入 + .txt/.md 文件上传(FileReader 前端读取)
  • RAG 与辅助知识 Prompt 分离注入【RAG 参考资料】【辅助知识】 两段独立标注
  • 前文回顾字数可配置:配置页 "写作参数" 新增输入框,context_review_length 写入 config.json
  • 配置项自动合并config_manager.load() 深层合并(嵌套 dict 中新 key 自动补上);update() 支持写入新增键
  • LLM 模型自动检测_build_payload 中 model 为空时自动调 list_models() 取第一个已加载模型
  • 批量自动撰写:输入框写入多行(每行一个主题)→ 后端 /api/batch_auto 逐篇规划+RAG+生成 → 前端轮询批量进度
  • 单篇自动撰写:输入框旁 "自动撰写" 按钮 → 前端 chain plan→generate,全量自动 RAG
  • 事实自检系统:配置页 "事实自检" 开关 → 写作 prompt 末尾内嵌 【事实待核查】 标记 → LLM 在同一 response 中自检 → 解析标记收集 → 文章末尾编号列表汇总。零额外 LLM 调用
  • 无问题时也输出自检段落:即使所有子结构都返回"无",文章末尾也输出 ## 建议人工复审 + 未发现需标记的问题
  • 会话归档/恢复/删除:侧边栏每项 "🗂 归档" 按钮 → data/archives/sessions/ 折叠区 → "↩ 恢复" + "✕ 删除"(confirm() 确认)
  • 自动会话限额max_sessions(默认 20)→ 新建会话超出时自动归档最旧非当前会话
  • 停止生成:聊天区底部 "延时停止"(当前子结构写完停)+ "立即停止"(续写边界停)→ 保留已写内容输出 .md
  • 规划器优先遵循用户指令:约束前加 "优先遵循用户明确指定的结构要求",sections 数量 改为 "如用户未指定"
  • 规划/写作模型温度可配置:配置页新增 "温度" 输入框(0-1,step=0.05),规划默认 0.6、写作默认 0.7,持久化到 config.json
  • LLM 客户端 temperature 参数LLMClient.__init__temperaturechat/chat_detailed/_build_payload 默认值改为 None(走 self.temperature
  • 模型下拉框始终显示已保存的模型refreshModels 接受 savedValue 参数,配置模型不在 API 返回列表时追加 xxx(已配置) option
  • RAG 停止按钮:配置页新增 "停止 RAG" 按钮 → 后端 _handle_rag_stoptaskkill /F /T 杀进程树 + netstat 查 8767 + 等端口释放 + auto-restart 检测
  • RAG 停止后不再显示"运行中"_ragManuallyStopped 标记阻止轮询跳回运行中状态,直到用户手动点击"冷启动 RAG"
  • RAG 状态轮询加速:cache-buster 防缓存,间隔 3s→1.5s,启动后立即查一次

变更

  • 自检从额外 LLM 调用改为内嵌标记:删除 FACT_CHECK_PROMPT 和独立 SELF_CHECK_SYSTEM_PROMPT,改为在写作 prompt 末尾追加 【事实待核查】 标注要求,response 里直接解析
  • 规划器 max_tokens 从配置读:删除硬编码 4096,改用 max(4096, llm_client.max_tokens)
  • 写作器/规划器 LLM 客户端统一工厂_create_writer_client() / _create_planner_client()temperature
  • Planner/writer temperature 硬编码删除planner.py temperature=0.6Nonewriter.py temperature=0.7None(走客户端配置)
  • status_text 仅 writing 阶段返回get_progress() 非 writing 阶段返回空字符串,防止加载旧会话显示脏数据
  • 状态文本生成时自动清空_handle_generate 入口调用 set_status_text("")
  • 配置页提示文案更新:改为 "推理模型建议不低于 4096(默认最低值),长文建议 8192 以上"

修复

  • planner.py 硬编码 max_tokens=4096 导致推理模型 thinking 吃掉全部 token → JSON 输出为空
  • config_manager.py update() 无法写入新增配置键 → fact_check_enabled 等不持久化
  • config_manager.py load() 不合并 DEFAULT_CONFIG 缺失项 → 旧 config.json 没有新字段
  • 自检 max_tokens 各值(2048/8192/512)导致推理模型 thinking 吃光 → 改为 None(走配置的 81920)
  • 自检使用独立 system prompt → LLM 混淆角色 → 改为共享 WRITER_SYSTEM_PROMPT
  • 自检额外 LLM 调用导致额外 token 消耗 → 改为内嵌标记法,零额外调用
  • 加载旧会话时 _status_text 脏数据被轮询读出并显示
  • 章节字数 input 可编辑但子结构字数不变 → 数据不一致
  • 子结构取消勾选后章节字数不减 → 重算函数忽略未勾选
  • 模型下拉框加载时显示"(请选择)"而非已保存模型 → refreshModels 接受 savedValue 回退
  • RAG 冷启动后无法关闭 → 新增停止按钮 + 后端进程树 kill + 端口释放等待
  • RAG 停止后轮询仍跳回"运行中" → _ragManuallyStopped 标记保护
  • RAG 状态检测被浏览器缓存 → 加 ?_=Date.now() cache-buster

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

structured_writer_ldxs-1.1.0b0-py3-none-any.whl (59.7 kB view details)

Uploaded Python 3

File details

Details for the file structured_writer_ldxs-1.1.0b0-py3-none-any.whl.

File metadata

File hashes

Hashes for structured_writer_ldxs-1.1.0b0-py3-none-any.whl
Algorithm Hash digest
SHA256 8b5920d331e22fa2634d8c241ce26a0af18d7450527acc02ee9788cf11d67bcc
MD5 8b6093a6e125bde4964c89a34764a87f
BLAKE2b-256 5e7a6a7ac7b5c1e04ac60aead3bcad4fec9567f637be050cec1ee2e045455e4d

See more details on using hashes here.

Provenance

The following attestation bundles were made for structured_writer_ldxs-1.1.0b0-py3-none-any.whl:

Publisher: publish-pypi.yml on Ldxs001/workbuddy-skills

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page