vision-agent 数据模型层全解析:Agent 消息、上下文与工具请求的 Pydantic 模型指南
【免费下载链接】vision-agentThis tool has been deprecated. Use Agentic Document Extraction instead.项目地址: https://gitcode.com/GitHub_Trending/vi/vision-agent
vision-agent 是一个面向视觉任务的多 Agent(规划、编码、对话)系统。其数据模型层 docs/api/models.md 定义的 14 个 Pydantic 模型,是贯穿 Agent 通信、LMM(大视觉语言模型)调用与工具执行的"数据结构契约"。本文以该 API 文档为核心骨架,结合仓库源码逐一拆解这些模型的字段定义、枚举取值与真实调用场景,帮助你在二次开发、调试与扩展工具时准确构造与解析数据。
说明:本文所引源码均来自当前仓库 vision_agent/models 目录,相关文件为 agent_types.py、lmm_types.py 与 tools_types.py。另据项目说明,本仓库工具已标记为 deprecated,新项目请参考其替代方案 Agentic Document Extraction;本文内容以当前仓库代码为准。
模型层概览:三个模块、三种职责
vision_agent.models包由三个模块组成,并通过 vision_agent/models/init.py 统一导出全部类型:
| 模块 | 职责域 | 包含模型 |
|---|---|---|
agent_types.py | Agent 系统内部通信与上下文 | AgentMessage、PlanContext、CodeContext、InteractionContext、ErrorContext |
lmm_types.py | LMM 的输入输出类型 | TextOrImage、Message |
tools_types.py | 工具/API 请求与响应 | BboxInput、BboxInputBase64、BoundingBoxes、ODResponseData、Florence2FtRequest、PromptTask、JobStatus |
所有结构体均继承自pydantic.BaseModel,因此天然具备字段类型校验、序列化(model_dump()/model_dump_json())与别名(alias)支持等能力,可以直接用于类型注解与数据交换。
Agent 通信与上下文模型:多 Agent 协作的数据骨架
AgentMessage:统一消息载体
AgentMessage是整个 Agentic 系统(包括 LMM 与各子 Agent)之间传递消息的统一载体,定义于 agent_types.py。其字段为:
role:消息角色,取值是 11 种字面量类型的联合:user:用户消息;assistant:助手消息(planner、coder、conversation 均属此类);observation:执行某个动作后的观察结果(可由用户或助手产生);final_observation:最终代码输出产生的观察;error_observation:错误消息产生的观察;interaction:用户与助手之间的交互(例如助手请求用户帮助);interaction_response:用户对交互消息的回应;conversation:来自对话 Agent 的消息(一种助手消息);planner:来自规划 Agent 的消息(一种助手消息);planner_update:规划器输出的中间进度更新;coder:来自编码 Agent 的消息(一种助手消息)。
content:字符串类型的消息正文;media:可选的多媒体资源列表,元素类型为str或Path,默认None。
源码中大量使用该模型组织多轮对话,例如 vision_agent_planner_v2.py 中,规划器在执行代码后向会话追加planner与observation消息;vision_agent_v2.py 则按coder、final_observation、error_observation等角色拼接上下文。角色字段的意义在于:不同子 Agent 产出的消息被打上独立标签,便于在汇总对话时按角色过滤(见extract_conversation对coder、conversation等角色的筛选逻辑)。
PlanContext:规划结果
PlanContext(agent_types.py)承载一次规划任务的产物:
plan:整体计划的文字描述;instructions:逐步执行指令列表(List[str]);code:规划阶段使用的代码片段。
它是create_finalize_plan(vision_agent_planner_v2.py)的正常返回类型:规划器将模型的 JSON 输出解析为{"plan": ..., "instructions": [...], "code": ...}结构后,构造PlanContext交付给上层 Agent 继续执行。
CodeContext:最终代码与测试结果
CodeContext(agent_types.py)表示编码 Agent 产出的最终代码及测试情况:
code:最终写出的代码;test:编写的测试用例;success:布尔值,表示代码是否通过测试;test_result:运行测试的结果,类型为vision_agent.utils.execute.Execution。
在 vision_agent_coder_v2.py 中,编码器完成代码生成与测试执行后即构造并返回CodeContext;上层 vision_agent_v2.py 再将其格式化后以AgentMessage的形式送入对话。
InteractionContext:人机交互会话
InteractionContext(agent_types.py)仅含一个字段chat:用户与助手之间交换的AgentMessage列表。它用于封装"人类介入"场景,例如 vision_agent_planner_v2.py 中当 Agent 需要向用户确认工具选择时,将交互过程以InteractionContext(chat=int_chat)形式返回。
ErrorContext:错误上下文
ErrorContext(agent_types.py)表示一条错误消息,字段仅error(字符串)。其典型触发场景是:规划阶段模型未输出正确格式的响应(例如模型因安全顾虑拒绝回答),导致无法解析出计划 JSON。对应逻辑见 vision_agent_planner_v2.py:当json.JSONDecodeError抛出时,返回ErrorContext(error=plan_str)交由上层处理。
LMM 输入输出类型:与模型交互的数据契约
TextOrImage 与 Message
vision_agent/models/lmm_types.py 定义了两个高度抽象的类型别名:
TextOrImage = Union[str, Sequence[Union[str, Path, ImageType, np.ndarray]]] Message = Dict[str, Union[TextOrImage, Execution]]TextOrImage:既可以是一个纯文本字符串,也可以是一系列媒体元素(本地路径str/Path、PIL 图像ImageType、numpy 数组np.ndarray);Message:一条对话消息,本质是键为字符串、值为TextOrImage或Execution的字典。实际使用中消息通常包含role、content、media三个键。
Message被 vision_agent/lmm/lmm.py 中的LMM抽象基类广泛使用:chat(chat: Sequence[Message], **kwargs)接口即接收消息序列。各厂商实现(OpenAILMM、AnthropicLMM、GoogleLMM、OllamaLMM)会统一把content与media转换为对应厂商 API 的格式。以OpenAILMM.chat(lmm.py)为例,一条带图片的消息可表示为:
[ { "role": "user", "content": "这张图里有什么?", "media": ["image1.jpg", ...], }, ... ]发送前实现会把media中的每张图片经encode_media编码后,附加为image_url类型的内容块。测试方面,tests/unit/fixtures.py 提供了openai_lmm_mock、anthropic_lmm_mock、google_lmm_mock、chat_ollama_lmm_mock等夹具,mock 了不同厂商的流式与非流式响应,可用于验证消息格式的构造是否符合预期。
工具与 API 数据模型:目标检测、微调请求与任务状态
BboxInput / BboxInputBase64:检测标注输入
两个模型用于向工具提交带标注的检测样本(tools_types.py):
BboxInput:image_path:图片路径(字符串);labels:标签列表;bboxes:边界框列表,每个框是(x1, y1, x2, y2)形式的(int, int, int, int)四元组。
BboxInputBase64:与前者字段几乎一致,但以image(base64 编码字符串)+filename(文件名)代替本地路径,适用于通过 HTTP/API 上传图片的场景。
BoundingBoxes 与 ODResponseData:检测响应结构
class ODResponseData(BaseModel): label: str score: float bbox: Union[list[int], list[float]] = Field(alias="bounding_box") model_config = ConfigDict(populate_by_name=True) BoundingBoxes = list[ODResponseData]ODResponseData(tools_types.py)表示单条目标检测结果:label(类别标签)、score(置信度分数)、bbox(边界框坐标)。注意bbox字段对外序列化名称为bounding_box(别名alias),同时通过populate_by_name=True允许调用方用字段名或别名任意一种传入;BoundingBoxes是ODResponseData的列表类型别名,代表一整张图的检测结果集合。
该结构在示例前端中被直接消费:如 examples/chat/chat-app/src/components/ResultImageWithBoundingBoxes.tsx 与 PreviewSection.tsx 会按label、score、bounding_box渲染检测框与置信度。
PromptTask:Florence2 任务提示词枚举
class PromptTask(str, Enum): """Valid task prompts options for the Florence2 model.""" PHRASE_GROUNDING = "<CAPTION_TO_PHRASE_GROUNDING>"PromptTask(tools_types.py)是字符串枚举,目前定义了一项任务:PHRASE_GROUNDING,其值为 Florence2 模型的短语定位任务标记<CAPTION_TO_PHRASE_GROUNDING>。从源码结构看,该枚举为后续扩展其他 Florence2 任务(如检测、分割)预留了接口。
Florence2FtRequest:微调请求体
Florence2FtRequest(tools_types.py)封装向服务端提交 Florence2 微调任务的请求:
image:可选,图片(字符串);video:可选,视频(bytes);task:必填,PromptTask枚举,指定任务类型;prompt:可选提示词,默认空字符串;chunk_length_frames:可选,视频按帧切块的帧数;postprocessing:可选,后处理方式;job_id:可选,任务 UUID,别名(alias)为jobId(对齐 JSON/HTTP 命名习惯)。
该模型配置了populate_by_name=True,因此构造请求时jobId与job_id均可使用;同时通过@field_serializer("job_id")(tools_types.py)将 UUID 在序列化输出时统一转为字符串,保证 JSON 可传输。
JobStatus:微调任务状态机
JobStatus(tools_types.py)是字符串枚举,描述一个微调任务从创建到结束的完整生命周期:
| 取值 | 含义 |
|---|---|
CREATED | 任务已创建,等待被调度执行 |
STARTING | 任务开始运行,但尚未进入训练阶段 |
TRAINING | 任务正在训练模型 |
EVALUATING | 任务正在评估模型并计算指标 |
PUBLISHING | 任务正在将产物导出到外部目录(s3 或本地) |
SUCCEEDED | 任务已完成(训练、评估、产物发布全部结束) |
FAILED | 任务因内部原因失败(资源问题或代码本身) |
STOPPED | 任务被用户本地或云端停止 |
该枚举覆盖了"创建 → 启动 → 训练 → 评估 → 发布 → 成功/失败/停止"的完整流水线,可作为微调任务编排与前端状态展示的统一状态码。
实战要点:如何正确使用这些模型
- 构造带图片的对话:用
Message字典(role+content+media)组织输入,交给任意LMM实现(见 vision_agent/lmm/lmm.py),实现层会完成图片编码与厂商格式转换; - 解析规划器返回:
create_finalize_plan的返回值是(List[AgentMessage], Union[PlanContext, ErrorContext])元组,先用isinstance判断是正常计划还是错误上下文,再取用plan/instructions/code字段; - 序列化检测结果:
BoundingBoxes(即ODResponseData列表)对外输出字段名为bounding_box,前端解析时需使用别名,而非 Python 字段名bbox; - 提交微调请求:
Florence2FtRequest的task必填,其余字段按需设置;jobId/job_id均可写入,序列化后统一为字符串jobId; - 校验与调试:由于所有模型都是 Pydantic
BaseModel,可以在单元测试中直接实例化并借助校验报错快速定位字段类型或必填项问题。
小结
从 docs/api/models.md 列出的 14 个模型可以看出,vision-agent 的数据模型层被刻意划分为三层契约:面向多 Agent 协作的消息与上下文(AgentMessage、PlanContext、CodeContext、InteractionContext、ErrorContext)、面向 LMM 厂商差异的输入输出类型(TextOrImage、Message)、以及面向工具与 API 的业务数据结构(BboxInput、BoundingBoxes、Florence2FtRequest、JobStatus等)。理解这三层契约,是阅读 vision_agent/agent 下各 Agent 实现、扩展自定义工具、以及接入检测/微调服务的前提。若需在测试中模拟 LMM 响应,可参考 tests/unit/fixtures.py 中针对不同厂商实现的 mock 夹具。
【免费下载链接】vision-agentThis tool has been deprecated. Use Agentic Document Extraction instead.项目地址: https://gitcode.com/GitHub_Trending/vi/vision-agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考