docs(prompt-mgmt): 方案A 协同回写 + 补声明 structlog 依赖

- memory/contracts.md:立 C6-ext(load_prompt/SPECS/SCHEMA_CATALOG/
  REVIEW_RESERVED_NAMES/SpecResolver + 打包契约)+ 变更日志一笔
- memory/decisions.md:方案A 决策(运行时值金标准/尾换行方案B/守卫前移/
  schema 留 Python/同一实例)
- memory/gotchas.md:spec.name 连字符命名 / 改稿须重生成金标准 /
  .gitattributes 完整嵌套路径 / wheel artifacts 带 .md / structlog 补声明 /
  SpecResolver 零 DB + 精确匹配
- PROGRESS.md:已封板「Prompt 管理重构 + 全量重写」波次
- ARCHITECTURE.md §5.1:补 prompt 外置 + SPECS/SCHEMA_CATALOG/SpecResolver,
  内置 agent 计数 8→21
- packages/{llm_gateway,core}/pyproject.toml:补声明 structlog>=24.1
  (原直接 import 未声明,靠 apps/api 传递;裸装 import ww_agents 会缺)
This commit is contained in:
Yaojia Wang
2026-06-24 08:25:26 +02:00
parent eb356c42a9
commit 0021426f09
8 changed files with 48 additions and 2 deletions

View File

@@ -597,7 +597,7 @@ tier ──▶ resolve(scope) ──▶ { provider, model, fallback[] }
class AgentSpec(BaseModel):
name: str # worldbuilder / writer / continuity ...
tier: Tier # 能力档位(网关解析 provider+model)
system_prompt: str # 角色与约束
system_prompt: str # 角色与约束(值由 load_prompt(name) import 期注入, 见下)
input_schema: type[BaseModel] # 入参契约
output_schema: type[BaseModel] | None # 结构化产出契约(网关保证; writer 为 None=纯文本)
reads: list[TableName] # 声明式表读权限
@@ -605,8 +605,11 @@ class AgentSpec(BaseModel):
genre: str | None = None # 题材适用(Skill 用)
```
- 内置 8 Agent 即 `scope=builtin` 的 AgentSpec用户 Skill 为 `custom/community`§5.6)。
- 内置 21 Agent 即 `scope=builtin` 的 AgentSpec用户 Skill 为 `custom/community`§5.6)。
- `reads/writes` 是**契约**:运行时强制,越权拒绝(安全见 §5.6 / §9.2)。
- **Prompt 外置方案A2026-06**`system_prompt` 散文不再内联于 Python 常量,而外置为 `packages/agents/ww_agents/prompts/<spec.name>.md`,由 `load_prompt(name)``prompt_loader.py`)在 **import 期确定性加载**(去 BOM/LF 归一/NFC/`rstrip` 尾 LF + 内存缓存 + fail-fast `PromptNotFoundError`,无任何运行期插值)。`system_prompt` 仍是字节稳定的整块 `str`,进 `system``cache=True`——缓存断点前块字节不变(不变量 #9);改稿只动 `.md`,金标准 fixture `tests/fixtures/prompt_hashes.json` 守字节回归。Pydantic 类型**永留 Python**`SCHEMA_CATALOG[name]→output type` 是唯一真相源,`output_schema` 由它派生。
- **注册表 `SPECS: dict[name, AgentSpec]`** 是内置 agent 的集中名册name 为唯一主键,`SPECS[name]`/`prompts/<name>.md`/`SCHEMA_CATALOG[name]` 三者由 name 对齐,缺一即 fail-fast。四审受信名锚在显式白名单 `REVIEW_RESERVED_NAMES={continuity,foreshadow,style,pace}`
- **统一解析入口 `SpecResolver.get(name)`**`packages/skills/ww_skills/spec_resolver.py`):内置走纯内存 `SPECS`(零 DB用户 skill 走 `SkillRegistry`DB。同读接口、不同信任级别内置 name 为保留命名空间,用户 skill 同名在 **SkillRegistry 入库校验期**即被拒(不在读路径),守不变量 #3
### 5.2 编排器LangGraph 图)