Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DevPilot

DevPilot 是一个面向 Agent Engineering 学习与实践的练习仓库:一个从零搭建的最小 Agent Runtime,加上多个在它之上组合出的应用层 Agent(Research / RAG / Memory / Planning / Resume)。

它不是 LLM API 的薄封装。项目从 Agent 运行时真正需要回答的工程问题出发:Agent Loop 如何驱动执行、Tool Calling 如何调度与隔离错误、Context / Session 如何进入下一次 LLM 请求、State / Checkpoint 在哪里划边界、Verification 如何成为交付闸门、Retry 如何被有界策略约束。先把这些基础能力显式搭出来,再复用它组合具体 Agent。

其中 Resume Agent V1 是当前最完整的应用层 Demo:它演示了“用户资料 + 招聘 JD → 事实约束下的生成 → 确定性验证 → Markdown 简历”这样一个可运行的垂直闭环。

定位:个人 Agent Engineering practice / portfolio 项目,刻意保持小而可读,不是商业产品。

About(项目概览)

  • 语言 / 环境:Python 3.12,纯异步(asyncio)。
  • 运行时基础能力(Core,位于 devpilot/ 根级模块):Agent Loop、Tool Calling、Session / Projection / RequestBuilder、LLM Provider 抽象、State / Phase、Checkpoint / Recovery、ExecutionStore / TraceStore。
  • 工程闭环能力:Verification、Retry / Stop Condition、Planning / Replan、Evaluation(确定性 metric)。
  • 应用层 Agent:Research Agent、RAG Agent、Memory Agent、Resume Agent V1(目录见 Project Structure)。
  • 依赖:核心代码仅依赖 openai SDK(真实 LLM 调用)与 mcp(MCP 接入),其余为标准库;Evaluation 额外依赖 deepeval

Why This Project

我希望能真正理解 Agent Engineering 中“运行时”层面的问题,而不只是停留在“调用一次 LLM”:

  • Agent Loop 如何驱动 Turn / Step,如何避免无界循环(max_iterations、终态语义);
  • Tool Calling 如何注册、调度(serial / parallel),并在出错时隔离而不是击穿 Runtime;
  • Context / Session 如何被组织、投影并进入下一次 LLM 请求;
  • State / Checkpoint / Recovery 的职责边界与恢复语义;
  • Verification 如何成为应用层交付闸门;
  • Retry / Replan 如何受 bounded policy 约束;
  • 应用层 Agent 如何复用同一套 Core,而不是为每个场景重写 Runtime。

这个项目把上述边界用尽量小的代码量显式实现,并用测试锁定“这些契约确实成立”。

Architecture

DevPilot 分为两层:与具体应用无关的 Core Runtime,和复用 Core 的应用层 Agent。

flowchart TB
    subgraph CORE["Core Runtime(devpilot/ 根级模块,与具体应用无关)"]
        direction TB
        C0["Core Runtime"]
        C0 --> C1["Runtime / AgentLoop"]
        C0 --> C2["Tool / ToolRegistry / ToolScheduler"]
        C0 --> C3["Session / Context / RequestBuilder"]
        C0 --> C4["Provider"]
        C0 --> C5["State / Checkpoint / Recovery"]
        C0 --> C6["ExecutionStore / TraceStore"]
    end

    C0 -->|"shared foundation"| A0

    subgraph APP["Application Layer(应用层)"]
        direction TB
        A0["Application Layer"]
        A0 --> A1["Research"]
        A0 --> A2["RAG"]
        A0 --> A3["Memory"]
        A0 --> A4["Planning"]
        A0 --> A5["Resume Agent V1"]
    end

    A1 --> G["普通 Agent 路径:Agent → Runtime + AgentLoop → Tool / Session / Provider"]
    A2 --> G
    A3 --> G
    A5 --> R["正式 Resume Workflow:ResumeService → Document → Fact → JD → Matching → ResumeModel → Verification → Delivery"]
    C4 -. "可选 LLM 调用" .-> R
Loading

两层之间有两种真实存在的执行方式(与代码一致,需要区分):

  • Research / RAG / Memory,以及 Resume 的 Prompt Demo,以 Agent(内部是 Runtime + AgentLoop)作为执行载体:注册 Tool + 注入 Skill prompt,复用同一套 Tool / Session / Provider。Planning 作为应用层的 Planner → Executor → Verifier → Replanner / Retry 编排,不新建 Runtime。
  • Resume Agent 的正式入口是应用层的结构化 Resume Workflow(run_resume_workflow / ResumeService / CLI resume):它在应用层编排 Document → Fact → JD → Matching → ResumeModel → Verification → Delivery,只复用 Core 的 LLM Provider 抽象做可选 LLM 调用,不经过 AgentLoop / ToolScheduler,也没有为 Resume 重写第二套 Runtime。

Resume Agent V1

(主 Demo:用户资料 + 招聘 JD → Markdown 简历)

flowchart LR
    A["Profile + JD(TXT / Markdown / plain text,多文档)"] --> B["Document Parsing"]
    B --> C["Fact Extraction(逐行 verbatim → UserFact,保留来源)"]
    C --> D["UserProfile(User Facts = Source of Truth)"]
    D --> E["JD Analysis(→ JDRequirement)"]
    E --> F["Requirement Matching(STRONG / PARTIAL / MISSING)"]
    F --> G["Resume Generation(→ ResumeModel / ResumeStatement,绑定 fact / requirement)"]
    G --> H["Deterministic Verification"]
    H --> I{"Delivery Gate"}
    I -- "pass" --> J["Markdown Resume + ResumeVersion"]
    I -- "fail" --> K["阻止交付:不渲染 / 不建版本 / 不写文件"]
Loading

核心设计原则(与代码一致):

  • User Facts 是 Source of Truth:事实抽取为逐行 verbatim,保留来源(source_document_id / 文档位置);生成内容必须绑定已有事实,不允许模型凭空增加公司、项目、技术、数字、职责或成果
  • 可追溯(provenance):每条 ResumeStatement 记录支撑它的 UserFact id 与对应的 JD requirement id;用 --annotate 可在 Markdown 注释里输出 provenance。
  • Matching 三档:STRONG / PARTIAL / MISSING。MISSING 表示“证据缺口”而不是错误;它可以驱动 gap-driven interview(追问 → 用户补充新事实 → 重新匹配)。
  • Verification = Delivery Gate:error 级问题(空简历 / 无来源陈述 / 缺小节等)会阻止交付——不渲染、不创建 ResumeVersion、不写文件;warning(疑似新增词/数字、JD 必须项缺口等)需要人工确认。
  • 一个 UserProfile + 多个 JD → 多个 ResumeVersion:同一个 ResumeService 可面向不同 JD 多次运行,每次生成独立的 ResumeVersion(单次运行接收一个 JD,对应 run() / run_from_texts() 的签名)。

结构上,devpilot/resume/ 由领域模型(Document / UserFact / UserProfile / JD / ResumeModel…)、parsers(文本解析)、skills(FactExtraction / JDAnalysis / Matching / Interview / Generation)、verifier、renderer、service(编排)组成。它是 Application Layer,不修改 Runtime / AgentLoop / Session / Provider / ToolRegistry。

Quick Start

仓库当前没有 pyproject.tomlrequirements.txtsetup.py 等标准安装入口。使用 Python 3.12;离线 Resume Demo 仅依赖标准库,无需额外安装。需要真实 LLM / MCP 时再安装可选依赖:

git clone https://github.com/RainCongeals/DevPilot.git
cd DevPilot
python --version  # Python 3.12
# 仅需真实 LLM / MCP 时执行;离线 Resume Demo 不需要额外安装
python -m pip install openai mcp

Demo

这是一个 offline deterministic Resume Agent V1 vertical slice:不需要 API Key,也不需要网络。

Input: profile.md + jd_backend.txt
  → Document Parsing → Fact Extraction → UserProfile
  → JD Analysis → Matching(STRONG / PARTIAL / MISSING)
  → ResumeModel → Deterministic Verification → Delivery Gate
Output: resume.md(Verification 通过时)

从仓库根目录运行:

# 从仓库根目录运行
python -m devpilot resume \
  --profile examples/resume_samples/profile.md \
  --jd examples/resume_samples/jd_backend.txt \
  --out resume.md
  • 默认无 Key 时走确定性链路:解析 → 事实抽取 → JD 分析 → 匹配 → 生成 → 验证 → 交付,全程不调用真实 LLM。
  • 运行后在仓库根目录生成 resume.md:只有 Verification 通过才会写入;失败会打印原因并阻止交付。
  • 等价脚本版:python examples/resume_pipeline_demo.py --out resume.md
  • 若设置了 OPENAI_API_KEY / DEEPSEEK_API_KEY,会启用可选的 LLM 步骤(事实类别复核 + 表达润色),但不会改写事实内容与 provenance。
  • 样例输入(devpilot/resume/samples.py 内置样例、examples/resume_samples/ 文件)均为虚构数据,方便直接跑通。
  • 环境:Python 3.12。纯离线 demo 无需额外安装;真实 LLM / MCP 需要 pip install openai mcp;Evaluation 需要 pip install deepeval

Expected Output

成功运行后,输出/结果会包含 JD requirements、STRONG / PARTIAL / MISSING matching、结构化 ResumeModel / 生成简历和 Verification 结果;Verification 通过时会交付 resume.md,否则不渲染、不创建 ResumeVersion、不写文件。

Agent Engineering Highlights

(工程点说明,不逐条罗列开发历史)

  • Agent Loop:把“驱动”与“单步行动”分开Runtime 负责生命周期:启动 Turn、在 max_iterations 内推进、决定终态(COMPLETED / FAILED / STOPPED);AgentLoop 只执行单步:从 Inbox 认领输入 → Projection 投影 → RequestBuilder 构造请求 → 调用 LLM → 执行工具或产出最终文本。分开之后,Checkpoint / Recovery / Trace 才能挂到明确的边界上。
  • Tool Calling:注册、调度、错误隔离。Tool 以唯一 name 注册进 ToolRegistryToolScheduler 支持 serial / parallel 调度;工具抛错由错误边界转成 ToolResult(success=False) 回到对话流,而不是让整个 Runtime 崩溃。Tool 还声明 execution_mode(serial / parallel)与 effect(read_only / idempotent / side_effect),为 Recovery 决策提供依据。
  • Context / Session:历史与请求之间的显式边界Session 保存对话历史(含 tool call / tool result / reasoning_content);每次请求前由 Projection 生成独立的 RuntimeContext 快照,再由 RequestBuilder 组装 provider 请求。历史不直接裸传给 LLM,中间有明确的投影边界。
  • Provider 抽象:离线可测 + 真实可切换EchoProvider(离线、确定性)让核心逻辑不依赖外部 API 即可测试;OpenAIProvider / DeepSeekProvider 走真实模型,DeepSeek thinking 模式的 reasoning_content 会在多轮 tool calling 中回传。ProviderFactory 按显式优先级选择(显式 provider → provider_name → 环境变量 → Echo)。
  • Verification 作为交付闸门。在 Resume 场景,Verifier 在“生成之后、渲染 / 写文件之前”执行,error 级问题直接阻断交付;验证与生成分离,验证器只判断、不修改内容。
  • Retry / Replan 受 bounded policy 约束。Retry 只有两个停止条件:验证成功,或达到 max_retries 上限;Planning 提供 Planner → Executor → Verifier → Replanner / Retry 的有界闭环,避免无界的“自我修正”循环。
  • 可观测性分层。ExecutionStore 记录每次 ToolCall 的执行事实(NOT_STARTED / RUNNING / SUCCEEDED / FAILED),TraceStore 记录 Run / Turn / Step / LLM / Tool 的事件轨迹,TraceAnalyzer 做只读分析;Trace 不保存 Secret 或完整 prompt,属于观察层而非控制层。
  • 应用层复用 Core。新增“一种 Agent”时,主要工作是“注册哪些 Tool + 注入什么 Skill 方法论”,而不是复制 Runtime;Resume Agent 进一步展示了“结构化应用层编排 + 复用 Provider 抽象”这种不依赖 AgentLoop 的形态。

Testing

当前离线测试结果(本轮复核,未设置外部 API Key,Python 3.12.10):

pytest: 656 passed, 9 skipped(0 failed)
  • 9 个 skipped 全部是外部 / 真实 LLM 集成用例,默认 gated:需设置 OPENAI_API_KEY / DEEPSEEK_API_KEY(部分还需 *_E2E=1)才运行;没有 Key 时跳过,而不是伪造成功。
  • 覆盖范围:Runtime / AgentLoop 生命周期、Tool 调度与错误边界、Session / Projection / Request(含 thinking reasoning_content)、Checkpoint / Recovery、Trace、Memory / RAG / Planning、Resume Agent 的 workflow contract、Verification Delivery Gate、回归测试、CLI E2E。
  • 重要说明:这些测试验证的是确定性行为、workflow 契约、验证闸门与回归,它们不能证明模型输出“没有幻觉”。Resume 的防编造体现为“事实绑定 + 确定性校验 + 人工确认警告”,而不是“证明无幻觉”。

运行测试:

python -m pytest -q
#
python -m unittest discover -s tests

Project Structure

DevPilot/
├── devpilot/                    # 核心包
│   ├── agent.py / runtime.py / loop.py      # Agent 组装、Runtime、AgentLoop
│   ├── session.py / projection.py / request.py / runtime_context.py   # Context/Session
│   ├── tool.py / tool_registry.py / tool_scheduler.py / tool_error.py # Tool Layer
│   ├── checkpoint.py / recovery.py / state.py / phase.py / turn.py / inbox.py / execution.py
│   ├── trace.py / trace_analysis.py          # 运行轨迹(观察层)
│   ├── llm_provider.py / llm_client.py / llm_config.py / llm_error.py / llm_stream.py
│   ├── provider_factory.py / openai_provider.py / deepseek_provider.py
│   ├── resume/                   # Resume Agent V1(应用层)
│   ├── research/                 # Research Agent(应用层)
│   ├── rag/                      # RAG(应用层,本地文档关键词检索)
│   ├── memory/                   # Memory(应用层,跨 Session)
│   └── planning/                 # Planning / Replan / Retry(应用层)
├── examples/                     # 可运行示例 + Resume 样例输入(examples/resume_samples/)
├── tests/                        # 单元 / 集成 / E2E / 回归测试
└── evaluation/                   # DeepEval 最小评估层

devpilot/ 根级模块构成 Core;devpilot/resume/devpilot/research/devpilot/rag/devpilot/memory/devpilot/planning/ 是应用层子包,复用 Core 而不修改 Runtime。

Limitations

与当前代码一致的诚实边界:

  • PDF / DOCX:目前只能识别类型(占位),解析器尚未接入——直接输入会抛 UnsupportedDocumentTypeError;输出渲染目前只支持 Markdown。
  • Semantic verification 尚未实现ResumeVerifier.verify_semantic(LLM-as-Judge 方向)只是接口占位,没有实现。
  • DeepEval Resume 专项评估尚未完成evaluation/ 目前是最小确定性评估链路,尚无 Resume-specific cases。
  • TraceStore 与 Resume audit 尚未完全统一:Resume workflow 的 audit 目前是结构化列表,与 Core TraceStore 是两套记录。
  • CJK matching 可能误报:Matching 基于关键词与中文 bigram,可能出现 false positives,需要人工确认。
  • Deterministic verifier 不能证明“绝对无幻觉”:它通过“事实绑定 + 启发式检查(疑似新增词/数字)”给出需要人工确认的 warning,而不是语义级证明。
  • Interactive interview CLI 尚未完成:gap-driven interview 的核心逻辑(问题生成、回答转事实、重新匹配)已实现,但交互式 CLI 对话流程尚未完成。

Roadmap

  • PDF / DOCX robust parsing(及对应 renderer)
  • Stronger semantic verification(LLM-as-Judge 方向)
  • Resume-specific evaluation cases
  • TraceStore 与 Resume audit 的统一
  • Human-in-the-loop review
  • GUI / Web UI(明确为未来方向,非当前目标)

结语:项目定位

这是一个 Agent Engineering practice / portfolio 项目,希望向读者展示:

  • Agent Runtime 的分层与生命周期设计(Runtime / AgentLoop / State / Phase / Checkpoint / Recovery)
  • Tool orchestration(Registry / Scheduler / 错误边界 / 副作用分类)
  • Context / State / Session 的边界与可观测性分层(ExecutionStore / TraceStore)
  • Verification 作为交付闸门的工程实践
  • Planning / Replan / Retry 的有界闭环
  • Application-layer Agent 设计:如何在不修改 Runtime 的前提下组合出可工作的 Agent(以 Resume Agent V1 为主线案例)

它不是、也不包装成成熟商业产品;它以“小、可读、可测试、边界清晰”为目标,方便读者快速理解每一层的职责与取舍。

License

MIT License,见 LICENSE

About

一个 Agent Engineering 实践项目,实现最小 Agent Runtime,并在 Research、RAG、Memory、Planning 和 Resume Agent 等应用中验证这些能力,其中 Resume Agent V1 是目前最完整的应用案例。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages