news 2026/9/14 12:29:14

用 domain-modeling 技能在 PentestGPT 中落地领域建模:统一语言、CONTEXT 与 ADR 的实践指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 domain-modeling 技能在 PentestGPT 中落地领域建模:统一语言、CONTEXT 与 ADR 的实践指南

用 domain-modeling 技能在 PentestGPT 中落地领域建模:统一语言、CONTEXT 与 ADR 的实践指南

【免费下载链接】PentestGPTAutomated Penetration Testing Agentic Framework Powered by Large Language Models项目地址: https://gitcode.com/GitHub_Trending/pe/PentestGPT

导读

本文围绕 PentestGPT 仓库中的domain-modeling智能体技能(.agents/skills/domain-modeling/SKILL.md)展开,讲解它如何帮助 AI 编码 Agent 在项目演进过程中主动建立并持续打磨"领域模型"——包括锁定领域术语与统一语言(Ubiquitous Language)、记录架构决策(ADR),以及如何与源码、测试相互印证。读完本文,你将掌握该技能的文件结构约定、会话中的五项关键行为、CONTEXT.md与 ADR 的书写格式,并能结合仓库中真实的 pentestgpt_agent/CONTEXT.md 实例与 unified_agent/skills.py 的实现,理解技能机制在工程层面的落地方式。

一、技能定位:这是"改变模型"的主动训练,而非"消费词汇"的阅读习惯

domain-modeling技能在 frontmatter 中这样自我声明(SKILL.md):

--- name: domain-modeling description: Build and sharpen a project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to maintain the domain model. ---

技能正文开头即划出一条重要分界线:仅仅为了查词汇而阅读CONTEXT.md不属于本技能——那只是任何技能都能做的一行习惯。本技能真正适用的场景是当模型正在改变领域模型时:挑战术语、虚构边界场景、在概念结晶的当下立刻把术语表和决策写下来。

从仓库实现看,这类技能描述并非摆设。unified_agent/skills.py 中的Skill数据结构保存了namedescriptionbodyfrontmatter;加载器强制要求 description 必填且不超过 1024 字符(load_skill),测试 tests/test_skills.py 也验证了空描述与超长描述会被拒绝。description 之所以被如此严格约束,是因为它承担着"模型自主调用"的触发职责——这与 .agents/skills/writing-great-skills/SKILL.md 中"模型调用型技能靠 description 触发"的原则一脉相承。

二、文件结构:单上下文与多上下文两种布局

技能规定了仓库中领域模型的标准落盘位置。大多数仓库只有一个上下文,结构如下(SKILL.md):

/ ├── CONTEXT.md ├── docs/ │ └── adr/ │ ├── 0001-event-sourced-orders.md │ └── 0002-postgres-for-write-model.md └── src/

如果仓库根目录存在CONTEXT-MAP.md,则说明仓库有多个上下文,此时由映射文件指出每个上下文的位置:

/ ├── CONTEXT-MAP.md ├── docs/ │ └── adr/ ← system-wide decisions ├── src/ │ ├── ordering/ │ │ ├── CONTEXT.md │ │ └── docs/adr/ ← context-specific decisions │ └── billing/ │ ├── CONTEXT.md │ └── docs/adr/

关键原则是懒创建(create files lazily):只在有内容可写时才创建文件。若尚无CONTEXT.md,则在第一个术语被确定时创建;若尚无docs/adr/,则在第一条 ADR 需要记录时才创建(SKILL.md)。这与writing-great-skills技能反复强调的"削减、去冗余、单一事实来源"精神一致——避免用空文件占据认知空间。

多上下文判别规则在 CONTEXT-FORMAT.md 中有明确推断逻辑:

  • 若存在CONTEXT-MAP.md,读取它以找到各上下文;
  • 若仅存在根目录的CONTEXT.md,则是单上下文;
  • 若两者都不存在,则在第一个术语确定时懒创建根目录CONTEXT.md
  • 存在多上下文时,先推断当前话题属于哪个上下文,不明确就提问。

三、会话中的五项行为:把建模变成实时纪律

技能用一节 "During the session" 给出 Agent 在对话中应持续执行的五个动作(SKILL.md):

3.1 对照术语表质疑(Challenge against the glossary)

当用户使用的术语与CONTEXT.md中已确立的语言冲突时,立即指出。技能给出的示例话术是:"你的术语表把 'cancellation' 定义为 X,但你这里似乎指的是 Y——到底是哪个?" 这一步的价值在于阻止统一语言的无声漂移。

3.2 打磨模糊语言(Sharpen fuzzy language)

当用户使用含糊或过载的词时,提出一个精确的规范术语。示例:"你说 'account'——你指的是 Customer 还是 User?这是两个不同的东西。" 领域驱动设计(DDD)中的统一语言正是通过这种即时澄清逐步收敛的。

3.3 讨论具体场景(Discuss concrete scenarios)

在讨论领域关系时,用具体场景做压力测试。虚构能触及边界情况的场景,迫使用户把概念之间的边界说精确。边界不清往往是需求缺陷的温床,场景化提问是暴露它的最高效手段。

3.4 与代码交叉引用(Cross-reference with code)

当用户陈述"某物如何工作"时,Agent 应当核对代码是否与之一致。若发现矛盾,立即浮出水面:"你的代码会取消整个 Order,但你刚才说支持部分取消——哪个才是对的?" 这一行为把领域模型与实现绑定,防止"文档是一套、代码是另一套"的割裂。

3.5 内联更新 CONTEXT.md(Update CONTEXT.md inline)

术语一经确定,当场更新CONTEXT.md,不要批量积压。格式遵循 CONTEXT-FORMAT.md。同时有一条硬性约束:

CONTEXT.md必须完全不含实现细节。不要把它当作规格说明书、草稿纸或实现决策的仓库。它只应是术语表,除此之外什么都不是。(SKILL.md)

这条约束将"领域语言"与"技术实现"彻底分离——实现决策属于 ADR,领域词汇属于 CONTEXT。

四、CONTEXT.md 的书写格式与规则

CONTEXT-FORMAT.md 给出了术语表的精确模板:

# {Context Name} {One or two sentence description of what this context is and why it exists.} ## Language **Order**: {One or two sentence description of the term} _Avoid_: Purchase, transaction **Invoice**: A request for payment sent to a customer after delivery. _Avoid_: Bill, payment request **Customer**: A person or organization that places orders. _Avoid_: Client, buyer, account

配套四条书写规则:

  1. 要有主见(Be opinionated):同一概念有多个词时,选最好的那个,把其余词列在_Avoid_下。_Avoid_列表正是统一语言发挥作用的地方——它明确宣告"别用这个词"。
  2. 定义要紧凑(Keep definitions tight):每个定义最多一两句话,定义它是什么(IS),而非它做什么(does)
  3. 只收领域特定术语(Only include terms specific to this project's context):通用编程概念(timeout、error types、utility patterns)即使项目大量使用也不该收录。添加术语前先自问:这是该上下文独有的概念,还是通用编程概念?只有前者属于这里。
  4. 自然聚类时分小节(Group terms under subheadings):当术语形成自然聚类时用子标题分组;若所有术语都属于一个连贯领域,平铺列表即可。

4.1 多上下文时的 CONTEXT-MAP.md

多上下文仓库在根目录维护CONTEXT-MAP.md,列出各上下文位置及相互关系(CONTEXT-FORMAT.md):

# Context Map ## Contexts - [Ordering](https://link.gitcode.com/i/1c94b10683620ac73935af2214e92452) — receives and tracks customer orders - [Billing](https://link.gitcode.com/i/1c94b10683620ac73935af2214e92452) — generates invoices and processes payments - [Fulfillment](https://link.gitcode.com/i/1c94b10683620ac73935af2214e92452) — manages warehouse picking and shipping ## Relationships - **Ordering → Fulfillment**: Ordering emits `OrderPlaced` events; Fulfillment consumes them to start picking - **Fulfillment → Billing**: Fulfillment emits `ShipmentDispatched` events; Billing consumes them to generate invoices - **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money`

Relationships 部分用有向箭头表达上下文间的依赖与事件流,这对理解"谁拥有什么数据、谁消费什么事件"至关重要。

五、ADR:只在真正需要时记录架构决策

技能反复强调 ADR 要克制(offer sparingly)。只有以下三个条件同时成立时才提议创建 ADR(SKILL.md):

  1. 难以逆转(Hard to reverse)——日后改变主意的代价有意义;
  2. 脱离上下文会令人费解(Surprising without context)——未来读者会疑惑"他们为什么这么做?";
  3. 真实权衡的结果(The result of a real trade-off)——当时确实存在多个候选方案,你因具体原因选了一个。

三者缺一就跳过。原因很直白(ADR-FORMAT.md):容易逆转的决策不值得记录,你很快会再改;不令人意外的决策没人会追问;没有真实备选项的决策除了"我们做了显而易见的事"之外无话可说。

5.1 ADR 的文件布局与模板

ADR 存放在docs/adr/,采用顺序编号0001-slug.md0002-slug.md……目录同样懒创建。模板极简(ADR-FORMAT.md):

# {Short title of the decision} {1-3 sentences: what's the context, what did we decide, and why.}

一条 ADR 可以只有一个段落。价值在于记录"做了决定"以及"为什么做",而不是填满各章节。可选部分仅在真正有价值时加入:

  • Statusfrontmatter(proposed | accepted | deprecated | superseded by ADR-NNNN)——当决策会被反复审视时有用;
  • Considered Options——仅当被否掉的备选项值得被记住时;
  • Consequences——仅当有非显而易见的连锁影响需要指出时。

编号规则:扫描docs/adr/找到最大现有编号并加一。

5.2 什么算值得记录的 ADR

ADR-FORMAT.md 给出了七类典型合格项:

  • 架构形态(Architectural shape):"我们用 monorepo""写模型是事件溯源、读模型投影到 Postgres";
  • 上下文间的集成模式:"Ordering 与 Billing 通过领域事件通信,而非同步 HTTP";
  • 带来锁定效应的技术选型(Technology choices that carry lock-in):数据库、消息总线、认证提供商、部署目标——不是每个库,只是换掉要花一个季度的那些;
  • 边界与范围决策:"Customer 数据归 Customer 上下文所有,其他上下文只按 ID 引用"——明确的"不做什么"与"做什么"同样有价值;
  • 对显而易见路径的有意偏离:"我们用手写 SQL 而非 ORM,因为 X"——任何合理读者都会猜相反方案的场景,必须记录,防止下一个工程师"修好"某个故意为之的设计;
  • 代码中看不到的约束:"合规要求不能用 AWS""合作伙伴 API 合同要求响应时间低于 200ms";
  • 被否方案的隐藏原因:若你考虑过 GraphQL 却因微妙原因选了 REST,记录它——否则六个月后还会有人再次提议 GraphQL。

六、仓库中的真实范例:pentestgpt_agent/CONTEXT.md

domain-modeling技能不是纸上谈兵——PentestGPT 仓库的 pentestgpt_agent/CONTEXT.md 就是该技能产物的实际样例,AGENT.md 也明确将其登记为"domain language and invariants"(领域语言与不变量)。

6.1 Language:17 个领域的精确定义

该文件首先用一两句话定义每个术语,部分条目给出了概念间的关系。例如:

  • Supervisor:拥有完全访问权的推理 Agent,可使用 provider 工具并提出、选择一个任务;其工具活动是诊断性的,确定性校验仍拥有规范状态的最终所有权;
  • Executor:执行一个"租约任务"并提出基于 trace 的完整访问 Agent;
  • Memory Kernel:确定性 SQLite 权威,负责校验并提交状态;它不是 Agent;
  • Provider Adapter:调用 Claude Code 或 Codex 并归一化其事件的外部模块,只负责 provider 差异,不负责渗透策略或记忆;
  • Evidence:由一个合格的动作回执捕获的精确目标输出;已完成命令的非零退出码可以构成有效的"负向证据",但 provider/工具传输错误被排除在外;
  • Diagnostic:用于避免重复失败的类型化操作或进度信息;永远不是证据

注意它严格遵循了 CONTEXT-FORMAT 的两条规则:定义紧凑(一两句)、只收领域特定术语(如 "Decision Cycle""Agent Episode""Action Receipt""Transport Recovery" 都是渗透测试编排上下文独有的概念,而非通用编程词汇)。这与技能"CONTEXT.md是术语表,不是规格书"的约束完全一致——文件通篇没有实现代码。

6.2 Invariants:术语之上的不可违反规则

CONTEXT.md的独特之处在于它还承载Invariants(不变量)——跨术语的系统级约束,例如:

  • "恰好存在从零修订到当前修订的每一条 transition";
  • "同一时刻至多一个任务/尝试处于活动状态,且任务、尝试、租约修订与 trace 片段身份一致";
  • "每个 episode 都是全新的(resume = null),配置的试验中禁用 Claude 自动记忆";
  • "目标派生的证据、诊断与文件都是不可信数据,绝不能当作 Agent 指令"。

这些不变量与 pentestgpt_agent/src 下的实现一一呼应,例如trial.py中的RunStatus.COMPLETED语义(pentestgpt_agent/CONTEXT.md)被明确限定为"建立结构性完成与显式证据引用,但不证明任意语义目标的蕴含"——这正是"与代码交叉引用"行为所要求的精确性:一个词一旦进入术语表,它的语义就被钉死,代码、测试、提示词三处都必须与之对齐

七、技能机制本身的工程实现:安装、校验与 lint

domain-modeling之所以能被 Agent 自动发现与调用,依赖仓库中一套完整的技能管理系统(unified_agent/skills.py)。理解它有助于你把握"技能"这一仓库级概念的工作方式:

  • 双宿主发现目录:Claude Code 从<ws>/.claude/skills/读取,Codex 从跨 Agent 位置<ws>/.agents/skills/读取;install_skills会把同一份 SKILL.md 以符号链接(symlink)或复制(copy)模式装进两个目录(unified_agent/skills.py),实现"一处编写、双 Agent 生效"。本仓库的 17 个技能(含 domain-modeling)都位于 .agents/skills 源目录下。
  • frontmatter 校验load_skill要求 SKILL.md 必须以---YAML frontmatter 开头且格式合法;name必须匹配^[a-z0-9]+(-[a-z0-9]+)*$与目录名一致description必填且 ≤1024 字符(unified_agent/skills.py)。这些约束都有对应测试覆盖(tests/test_skills.py)。
  • 可移植性 lintlint_skill会标记 Claude 独有、Codex 无法解析的语法($ARGUMENTS参数替换、!`动态 shell 注入、${CLAUDE_*}变量),确保技能描述对两个宿主都可移植(unified_agent/skills.py、tests/test_skills.py)。

从这些实现可以看出,"技能"在 PentestGPT 中是一等公民:它有规范的结构、有强制的元数据、有安装与校验流程。domain-modeling技能的 frontmatter 之所以被精心撰写,正是为了在这套校验体系下既能通过load_skill的硬性检查,又能借助 description 中的触发短语("pin down domain terminology""record an architectural decision""another skill needs to maintain the domain model")被模型在合适时机自主调用。

八、与其他技能的协同与最佳实践

在 .agents/skills 的技能族谱中,domain-modeling扮演"语言与决策的记录者"角色,与其他技能形成互补:

  • writing-great-skills的呼应:后者(SKILL.md)提出的"leading word"(引导词)概念——用模型预训练中已有的紧凑概念锚定行为——在领域建模中同样有效:术语表本身就是全项目共享的 leading words 集合。术语定义得越精确,模型在各处使用同一词汇时行为越可预测。
  • triageto-issuesto-prd的协作:当新需求或缺陷被分诊、转写成 issue 或 PRD 时,其中引入的新概念应同步回流到CONTEXT.md,这正是 SKILL.md 中"another skill needs to maintain the domain model"这一触发场景。
  • 与测试体系的闭环:领域术语一旦进入 pentestgpt_agent/CONTEXT.md,就应能在 pentestgpt_agent/tests 的测试代码中看到同一套词汇(如RunStatus.COMPLETEDresumeepisode),任何术语漂移都应触发"与代码交叉引用"行为的报警。

结语:把领域建模当作持续纪律,而非一次性文档任务

domain-modeling技能的核心主张可以浓缩为一句话:领域模型不是写出来的文档,而是在每次设计会话中实时锤炼出来的活物。它通过"质疑术语、打磨语言、场景压测、代码对照、当场落盘"五个动作保持模型的锐利,通过"CONTEXT 只收语言、ADR 只记难逆转的真权衡"两条纪律保持文件的纯净。PentestGPT 仓库既提供了这套技能的规范文本(SKILL.md、CONTEXT-FORMAT.md、ADR-FORMAT.md),也提供了真实的实践样本(pentestgpt_agent/CONTEXT.md)与完整的机制实现(unified_agent/skills.py、tests/test_skills.py)——三者对照阅读,即可完整掌握从"技能规范"到"工程落地"的全链路。

【免费下载链接】PentestGPTAutomated Penetration Testing Agentic Framework Powered by Large Language Models项目地址: https://gitcode.com/GitHub_Trending/pe/PentestGPT

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 12:27:20

从“夯”到“拉”:17款AI编程Agent平台深度盘点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 12:25:21

STM32F429+LAN8720A+LwIP:从RMII到netconn的TCP服务器实现

简介&#xff1a;这是一套基于STM32F429与LAN8720A的以太网TCP Server通信工程资源&#xff0c;面向嵌入式网络开发学习者&#xff0c;解决STM32平台通过以太网与电脑端进行TCP数据交互的需求&#xff0c;适合需要快速搭建或参考以太网通信方案的开发者。资源共326个文件&#…

作者头像 李华
网站建设 2026/9/14 12:24:40

Klipper 3D打印固件上手指南:简单几步消除振纹、给打印提速

Klipper 3D打印固件上手指南&#xff1a;简单几步消除振纹、给打印提速 【免费下载链接】klipper Klipper is a 3d-printer firmware 项目地址: https://gitcode.com/GitHub_Trending/kl/klipper 如果你有一台 3D 打印机&#xff0c;却总觉得它走得慢、响得吵&#xff0…

作者头像 李华
网站建设 2026/9/14 12:24:18

Molili本地AI助手:超越Clawbot的自动化办公利器

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 12:23:32

AI模型持续优化实战:架构设计与自动化迭代

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华