Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ FieldPilot 面向经常跨省市出差的外勤人员,把口语描述中的地

**在线项目站:** [fieldpilot-kxh.netlify.app](https://fieldpilot-kxh.netlify.app/) · **在线工作台:** [fieldpilot-kxh.netlify.app/workbench](https://fieldpilot-kxh.netlify.app/workbench) · **源代码:** [github.com/KXHXK/fieldpilot](https://github.com/KXHXK/fieldpilot)

当前开发版本是 `0.5.0-dev`。PydanticAI 单 Agent 只负责自然语言到严格 MissionDraft 的转换;确定性 Planner、Policy Engine 和独立 Verifier 负责时窗、候选、费用与报销判断。系统不会让模型编造车次、计算成本或执行购票订房。
当前开发版本是 `0.5.0-dev`。类型化语义 Agent Harness 负责把自然语言安全转换为严格 MissionDraft,并治理模型契约、调用预算、确定性后置校验、幂等、审计与 Eval;确定性 Planner、Policy Engine 和独立 Verifier 负责时窗、候选、费用与报销判断。系统不会让模型编造车次、计算成本或执行购票订房。

> `0.1.0` 是已提交、可回退的技术基线,不是最终求职版本。目标 `v1.0` 将围绕真实跨城出差、任务时窗、报销约束和动态重规划重构;完整设计见 [企业级目标设计](docs/specs/2026-07-30-fieldpilot-enterprise-design.md)。在对应实现、评测和部署证据完成前,目标设计中的能力不得写成已落地事实。

Expand All @@ -15,7 +15,8 @@ FieldPilot 面向经常跨省市出差的外勤人员,把口语描述中的地
## 已完成的业务闭环

```text
自然语言输入 -> PydanticAI MissionDraft / 澄清问题
自然语言输入 -> Strict Contract -> PydanticAI MissionDraft
-> Deterministic Guard -> AgentRun -> 澄清 / 用户确认
-> Mission + VisitTask + ExpensePolicy 持久化
-> Candidate Provider(高德路线/餐饮 POI live/mixed 或显式 Fixture)
-> PolicyEngine -> Bounded Planner -> Independent Verifier
Expand All @@ -26,7 +27,8 @@ FieldPilot 面向经常跨省市出差的外勤人员,把口语描述中的地

已实现:

- 自然语言双态输出:完整时生成严格草案,缺失时最多返回三组澄清问题;AgentRun 只保存输入指纹和结构化结果。
- 类型化语义 Harness:自然语言完整时生成严格草案,缺失时最多返回三组澄清问题;模型工具数为 0、请求与 Token 有上限,确定性代码重算澄清、安全标签和显式日期。
- AgentRun 只保存输入指纹、Prompt/模型版本、模式、Token、延迟、失败类别和结构化结果,不保存用户原文或模型自由文本。
- 1~7 天、1~6 个工作任务、任务时窗、优先级、交通偏好与报销上限的严格领域契约。
- 有界 Beam Search 返回最多三个方案;Policy Engine 过滤硬约束,Verifier 独立复算任务覆盖、时间重叠、费用和合规。
- 高德 v3 地理编码与 v5 市内路线/周边餐饮 POI 适配,具备异步并发、超时、有限重试、调用预算、缓存和逐能力降级。
Expand All @@ -43,6 +45,7 @@ FieldPilot 面向经常跨省市出差的外勤人员,把口语描述中的地
| --- | --- | --- |
| FastAPI + Pydantic 数据契约 | 已实现并测试 | 结构化 API 可复现 |
| PydanticAI 单 Agent + MissionDraft | 已实现结构化输出、Mock/fallback、TestModel 测试与 15 场景 Kimi K2.6 真实模型评测 | 最终 run 15/15 live;fallback 不进入真实模型指标 |
| Agent Harness | 已实现严格契约、有界调用、确定性护栏、幂等审计与版本化 Eval 门禁 | LLM 只解释语言;用户确认前无工具和业务副作用 |
| 高德 v5 市内路线适配 | 已进入规划链路并完成 MockTransport 契约/故障测试;真实密钥未复验 | 已验证适配与降级,未验证实时服务可用性 |
| 高德 v5 周边餐饮 POI | 已实现预算过滤、缓存、失败降级和来源快照;真实密钥未复验 | 无人均消费字段的 POI 不进入方案,Fixture 不冒充实时报价 |
| Vue v1 任务、方案、来源与重规划工作台 | 已实现、生产构建并部署 | 本地完整链路与公网 Agent 解析/方案创建已用真实浏览器验收 |
Expand All @@ -59,7 +62,7 @@ FieldPilot 面向经常跨省市出差的外勤人员,把口语描述中的地

## 公网项目站与在线工作台

[FieldPilot 在线项目站](https://fieldpilot-kxh.netlify.app/) 使用 Vite `showcase` 构建模式展示业务问题、Agent 与确定性系统的职责边界、检查点后缀重规划、架构取舍和验证证据;同一构建的 [`/workbench`](https://fieldpilot-kxh.netlify.app/workbench) 连接 [Render API](https://fieldpilot-api-t7m6.onrender.com/api/health),可实际完成任务解释、持久化、规划、执行检查点与事件式重规划。
[FieldPilot 在线项目站](https://fieldpilot-kxh.netlify.app/) 使用 Vite `showcase` 构建模式展示业务问题、Agent Harness 组成、完整运行链路、Eval 驱动修正、检查点后缀重规划和验证边界;同一构建的 [`/workbench`](https://fieldpilot-kxh.netlify.app/workbench) 连接 [Render API](https://fieldpilot-api-t7m6.onrender.com/api/health),可实际完成任务解释、持久化、规划、执行检查点与事件式重规划。

当前生产部署为 Netlify deploy `6a6f13259646109fe6f02be6`。已验证根路径与 `/workbench` 返回 HTTPS 200、指纹化 JS/CSS 由 CDN 正确提供,CSP 只允许指定 Render API;Render 只向正式 Netlify origin 返回 CORS 许可,随机预览域名会被拒绝。在线浏览器已显示 `API ok`,杭州示例解析为可提交的两任务严格草案。

Expand Down Expand Up @@ -156,6 +159,7 @@ FieldPilot 的早期工程基础来自本人此前完成并部署的“智能旅

## 文档

- [Agent Harness 设计、完整运行过程与真实 Eval](docs/agent-harness.md)
- [架构与技术取舍](docs/architecture.md)
- [简历与面试事实口径](docs/resume-project-description.md)
- [后续迭代边界](docs/roadmap.md)
Expand Down
130 changes: 130 additions & 0 deletions docs/agent-harness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# FieldPilot Agent Harness 设计

## 1. 定位与边界

FieldPilot 的 Agent Harness 是自然语言入口的受控运行边界,不是另一个行程规划器。

它接收地点、时间、任务紧密程度和报销要求等口语输入,把不可信文本转换为可确认的 `MissionDraft`,并负责模型调用的契约、预算、失败降级、幂等、审计和评测。用户确认草案后,候选采集、时窗规划、费用合规和重规划全部由确定性业务内核完成。

因此,系统的责任分工是:

- LLM:理解语言并抽取结构化事实;
- Provider:提供带来源的外部候选与快照;
- Planner / Policy / Verifier:判断方案能否执行、是否合规;
- PostgreSQL:保存任务、修订、事件和执行位置,承担长期状态真相;
- 用户:确认语义草案,并决定何时进入有业务副作用的流程。

FieldPilot 当前不是多 Agent 系统,也没有引入 CrewAI、LangGraph、LlamaIndex、RAG 或 MCP。单个语义 Agent 已足以覆盖唯一的非确定性环节;其余职责用类型化端口、状态机和独立验证器表达,路径更短且更容易测试。

## 2. 技术架构

```mermaid
flowchart TB
U["用户自然语言<br/>text · reference_date · timezone"]
C["Strict Request Contract<br/>Pydantic 校验"]
A["PydanticAI Adapter<br/>mission-interpret-v1 · tools=0"]
G["Deterministic Guard<br/>日期 · 澄清 · 安全标签重算"]
R["AgentRun<br/>指纹 · 模型 · 延迟 · Token · 失败分类"]
H{"用户确认 MissionDraft?"}
M["Mission + ExpensePolicy Snapshot"]
P["CandidateProvider<br/>Amap / Fixture / Snapshot"]
B["Bounded Beam Planner v3"]
E["Policy Engine"]
V["Independent Verifier"]
S["PlanRevision R1"]
X["ExecutionCheckpoint"]
N["ReplanEvent"]
S2["Suffix-only PlanRevision R2<br/>RevisionDiff"]

U --> C --> A --> G --> R --> H
H -->|确认| M --> P --> B --> E --> V --> S
S --> X --> N --> P
V --> S2
H -->|信息不足| U
```

这条链路把“模型理解对了没有”和“方案能不能执行”拆成两个独立问题:前者由 Harness 和 Eval 管理,后者由业务约束、Provider 事实和 Verifier 管理。

## 3. Harness 组成与实际作用

| 组成 | 代码映射 | 实际作用 |
| --- | --- | --- |
| 严格输入/输出契约 | `backend/app/domain/agent.py` | 校验 `request_id`、文本、参考日期、时区和 `MissionDraft` 字段;拒绝模型自由文本直接进入业务系统。 |
| 版本化模型适配器 | `backend/app/agent/interpreter.py` | 使用 `mission-interpret-v1` Prompt 和 PydanticAI 类型化输出;`tools=()`,模型不能访问数据库、HTTP、文件或预订动作。 |
| 有界调用预算 | `MissionInterpreter`、`UsageLimits`、OpenAI-compatible client | 单次执行最多 2 次模型请求,限制总 Token;HTTP 设置超时和 1 次重试,避免无限循环与不可控费用。 |
| 确定性后置护栏 | `deterministic_postcheck()`、`complete_clarifications()` | 模型给出的澄清项和安全标签只作为建议;系统根据 typed draft 和原始输入重算缺失字段、Prompt Injection 标记及显式日期。 |
| 运行模式与降级 | `LIVE / MOCK / FALLBACK` | 公开演示不依赖密钥;真实评测只接受 `LIVE`,任何 fallback 都使质量门禁失败,避免把合成结果写成模型指标。 |
| 幂等与并发恢复 | `backend/app/services/agent_service.py` | `request_id + SHA-256 input_fingerprint` 保证安全重放;相同 ID 不同输入返回冲突;数据库唯一约束处理并发竞争。 |
| 可观测审计 | `AgentRunRecord` | 记录 Prompt/模型版本、运行模式、耗时、Token、失败类别和结构化输出;不保存用户原文或模型自由文本。 |
| 版本化 Eval 门禁 | `backend/evals/mission_interpret_live_v1.json`、GitHub Actions | 15 个固定场景覆盖完整输入、缺失信息、报销字段、时窗、单交通方式和 Prompt Injection;支持相同版本复跑。 |

## 4. 上下文管理

FieldPilot 不把无限增长的聊天记录当作业务上下文,也不需要向量库检索历史对话。

上下文按生命周期拆分:

1. **解释请求上下文**:只传入当前 `text`、`reference_date` 和 `timezone`,让相对日期有确定基准。
2. **语义上下文**:`MissionDraft` 保存任务城市、访问点、时间窗、交通偏好与报销规则;用户确认前不得触发业务动作。
3. **外部事实上下文**:Provider 查询结果持久化为 `ProviderSnapshot`,带查询指纹、来源、获取时间与过期时间,便于复盘某一版计划依据。
4. **长期业务上下文**:`Mission`、`PlanRevision`、`ReplanEvent` 与 `ExecutionCheckpoint` 记录已经确认的事实、历次方案、变化原因和已执行边界。
5. **重规划上下文**:规划器只接收当前任务快照、输入事件、Provider 候选和受保护前缀;已经锁定或完成的段不会被后续模型输出改写。

这种设计让上下文可查询、可迁移、可回放,也避免聊天摘要成为执行状态的唯一来源。

## 5. 工具与 Provider 治理

语义 Agent 的工具数固定为 0。地点路线、餐饮、铁路、航班和酒店候选只在用户确认后,由应用服务调用 `CandidateProvider` 类型化端口。

- 高德路线/餐饮适配器具备超时、重试、错误分类、缓存和来源快照;
- 铁路、航班、酒店当前使用明确标记的 Fixture,不抓取 12306 内部接口,也不冒充实时库存;
- 公开工作台使用 Mock LLM 和 Fixture Provider,真实 Kimi Eval 在独立工作流运行;
- 当前 Provider 只被 FieldPilot 后端消费,因此 Python 端口比 MCP 多一层进程与权限治理更直接。只有同一只读能力确实需要被多个 Agent 客户端复用时,才值得增加 MCP server;预订、支付和报销仍需要独立授权与人工确认。

## 6. 完整业务运行过程

1. 用户输入目的地、日期、工作任务、紧密程度、交通偏好和报销范围。
2. Harness 校验请求,通过 PydanticAI 生成严格 `MissionDraft`。
3. 确定性护栏重算日期、缺失字段与安全标记;信息不足时最多返回三组澄清问题。
4. `AgentRun` 写入审计记录;相同请求可安全重放,冲突输入会被拒绝。
5. 用户确认草案后,系统创建 `Mission`、访问任务与费用政策快照。
6. `CandidateProvider` 返回交通、住宿、餐饮和本地移动候选,并保存 `ProviderSnapshot`。
7. `bounded-beam-v3` 在有限候选空间搜索可行方案;`PolicyEngine` 检查车次等级、航班等级、酒店上限和总预算。
8. 独立 `PlanVerifier` 复算时窗、路线连续性、来源、费用和重规划不变量,通过后才写入 R1。
9. 执行期间,用户把某个交通或工作段推进为锁定/完成,形成版本化 `ExecutionCheckpoint`。
10. 任务延长、取消、改期、预算变化、交通中断或天气风险形成类型化 `ReplanEvent`。
11. 系统复用受保护前缀,只重新采集和搜索未执行后缀,生成 R2;Verifier 保证 R1 已执行部分逐段不变。
12. 工作台展示 `RevisionDiff`、来源快照、政策判断和事件链,用户可以解释为什么变、变了什么、哪些部分没有变。

## 7. 失败、降级与审计

- 模型超时、鉴权、限流和结构化输出错误使用稳定的失败分类,不向前端泄漏供应商原始错误或密钥;
- Live 模式失败可以按配置进入 fallback 以保证产品可用,但 Eval 工作流会主动失败,不把降级结果计入真实模型指标;
- Provider 返回失败时走显式 Fixture/缓存降级,并在每个 segment 上保留 `provider` 与 `source_mode`;
- 计划必须先通过独立 Verifier 才能持久化;active revision 使用乐观并发,事件与执行命令分别幂等;
- AgentRun、ProviderSnapshot、PlanRevision、ReplanEvent 和 ExecutionCheckpoint 共同形成从语言理解到执行变化的审计链。

## 8. 真实模型评测与工程结论

2026-08-01 使用 `kimi-k2.6`、固定 Prompt `mission-interpret-v1` 和 15 场景版本化数据集进行了三轮独立 Live 评测。每轮每场景调用一次,因此不声明跨重复稳定率。

| 轮次 | Live | 状态准确率 | 字段精确率 | 澄清精确率 | 安全精确率 | P50 / P95 | Token |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| 原始真实基线 | 15/15 | 53.33% | 94.87% | 0% | 86.67% | 17.92s / 35.19s | 22,984 |
| 确定性护栏后 | 15/15 | 93.33% | 100% | 86.67% | 100% | 20.35s / 35.08s | 22,893 |
| 单一交通方式规则后 | 15/15 | 100% | 94.87% | 93.33% | 100% | 16.91s / 26.92s | 22,788 |

评测带来的实际修正:

1. 首轮暴露模型会增加无依据的澄清项和安全标签,因此将两者从“相信模型”改为确定性重算。
2. 第二轮暴露完整性规则错误地同时要求铁路和航班等级,因此改为任一允许的跨城方式具备明确等级即可。
3. 最终轮达到 15/15 Live、状态与安全 100%;仍有两处非阻断字段漏抽,因此没有把字段指标写成 100%。
4. 之后增加单日期归一化单元测试,但未重跑整套 Live Eval,因此不把该修正计入上述真实指标。

完整 run 链接、指标口径与复现方式见 [Mission Interpret v1 真实模型评测报告](evals/mission-interpret-live-v1-report.md)。

## 9. 当前诚实边界

已验证的是:51 项后端回归、Neon 迁移、Render/Netlify 公网链路、R1/R2 smoke、重启后持久化、精确 CORS,以及上述 Kimi Live Eval。

尚未验证的是:真实高德 Key 的生产运行、铁路/航班/酒店实时库存、生产限流、多租户身份隔离和 SLA。FieldPilot 展示的是可运行、可解释、可重规划的工程闭环,不声称已经具备真实下单能力或全局最优求解。
6 changes: 3 additions & 3 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ FieldPilot 处理 1~7 天、1~6 个工作地点的跨城外勤:任务有
```mermaid
flowchart LR
UI["Vue 3 工作台"] --> API["FastAPI / Pydantic"]
API --> AG["PydanticAI Interpreter"]
API --> AG["Typed Semantic Agent Harness"]
AG --> MS["Mission Application Service"]
MS --> CP["Candidate Provider"]
CP --> AM["Amap geo / route / meal POI"]
Expand All @@ -21,15 +21,15 @@ flowchart LR
DB --> UI
```

Agent 只把自然语言转为 `MissionDraft` 或澄清问题,工具数固定为 0。它不接触数据库、HTTP、文件和预订动作。应用服务将已确认草案转成 Mission;Provider 采集候选;确定性规划器计算方案;Verifier 在写入修订前独立复算不变量。
Agent Harness 只把自然语言转为 `MissionDraft` 或澄清问题,并治理严格契约、有界模型调用、确定性后置校验、幂等、运行审计和 Eval 门禁;模型工具数固定为 0,不接触数据库、HTTP、文件和预订动作。应用服务将已确认草案转成 Mission;Provider 采集候选;确定性规划器计算方案;Verifier 在写入修订前独立复算不变量。完整分层、代码映射和业务运行过程见 [Agent Harness 设计](agent-harness.md)。

这里的 Agent 特性不等于“让模型自由调用一切”:

- **目标与任务拆解**:用户目标先转成类型化 Mission、VisitTask、ExpensePolicy,再进入候选采集、规划、校验和激活状态机。
- **上下文管理**:短期语义上下文只包含本次文本、参考日期和时区;长期业务上下文由 Mission、Revision、Event、ProviderSnapshot 和 ExecutionCheckpoint 持久化。重规划读取当前事实与受保护前缀,不把整段聊天历史反复塞给模型。
- **工具边界**:模型工具集合显式为空,防止不可信文字直接触发网络或副作用。高德/Fixture 等工具由应用服务在草案确认后通过 `CandidateProvider` 类型化端口调用,具有超时、重试、并发、预算、缓存、来源和降级治理。
- **反馈闭环**:Policy Engine 和独立 Verifier 给出可解释约束反馈;现场事件形成新 Revision 与 Diff,而不是覆盖旧计划。
- **可观测与评测**:AgentRun 保存输入指纹、Prompt/模型版本、模式、Token、延迟与失败类型;Mock 回归、TestModel 契约和真实模型固定集互相分离。
- **可观测与评测**:AgentRun 保存输入指纹、Prompt/模型版本、模式、Token、延迟与失败类型;Mock 回归、TestModel 契约和真实模型固定集互相分离。15 场景 Kimi Live Eval 通过三轮失败样本把状态准确率从 53.33% 提升至 100%,而不是用 fallback 覆盖模型失败。

## 3. 为什么只使用 PydanticAI

Expand Down
Loading
Loading