AI Agent 入门教程:03-基本结构与项目搭建

从空目录接通一次真实模型调用,并用数据类定义 Goal、State、Action、Observation、Tool、Runtime 与 Stop Policy。文章保留离线模型,让主体结构在加入循环前可以独立测试。

本文目录11 个章节

建立一眼能看懂的仓库

技术简报 Agent 的输入、输出、工具白名单和禁止项已经确定。现在把这张能力边界落到同一个 brief-agent 仓库,先准备模型适配器和领域类型。

TEXT
brief-agent/
├── src/brief_agent/
│   ├── config.py
│   ├── model.py
│   ├── domain.py
│   ├── runtime.py
│   └── cli.py
├── tests/
├── fixtures/
├── artifacts/
└── pyproject.toml

配置、模型适配器和命令行入口先分开。后面加入工具和状态时,入口不会变成所有逻辑的堆放处。

配置只从环境读取一次

PYTHON
import os
from dataclasses import dataclass

@dataclass(frozen=True)
class Settings:
    model: str
    offline: bool

def load_settings() -> Settings:
    return Settings(
        model=os.getenv("OPENAI_MODEL", ""),
        offline=os.getenv("BRIEF_AGENT_OFFLINE", "0") == "1",
    )

API Key 由 SDK 的标准环境变量读取,不进入 Settings 的字符串输出,也不写入日志。

定义最小模型协议

PYTHON
from typing import Protocol

class TextModel(Protocol):
    def complete(self, prompt: str) -> str: ...

class EchoModel:
    def complete(self, prompt: str) -> str:
        return f"OFFLINE: {prompt}"

EchoModel 没有智能,它保证 CLI、配置和测试在无网络环境仍然可运行。

接通真实 Responses API

PYTHON
from openai import OpenAI

class OpenAITextModel:
    def __init__(self, model: str) -> None:
        self.client = OpenAI()
        self.model = model

    def complete(self, prompt: str) -> str:
        response = self.client.responses.create(
            model=self.model,
            input=prompt,
        )
        return response.output_text
TEXT
CLI ──▶ TextModel.complete ──▶ OpenAI Responses API
 │
 └────▶ EchoModel(离线)

CLI 根据 Settings 选择适配器,输入“解释 Agent Loop”,然后打印结果。此时程序仍是一问一答。

模型适配器的验收

  • 离线模式不访问网络。
  • 未配置模型时,在线模式在请求前给出清楚错误。
  • 日志不包含 API Key 和完整私有 Prompt。
  • CLI 只依赖 TextModel 协议。

模型适配器接通后,下面定义 Agent 的主体结构,把目标、状态、行动、观察、工具与停止条件变成 Python 类型。

先画主体结构,再写循环

TEXT
┌──────── Goal ────────┐
│ 主题、受众、验收规则   │
└──────────┬───────────┘
           ▼
┌──────── Runtime ───────────────────────────┐
│ State ─▶ Model ─▶ Action ─▶ Tool ─▶ Observation │
│   ▲                                      │ │
│   └──────────────────────────────────────┘ │
│            Stop Policy / Budget             │
└────────────────────────────────────────────┘

Goal 描述要完成的任务。State 保存当前进度。Model 根据状态选择 Action。Tool 执行动作并返回 Observation。Runtime 连接所有部件。Stop Policy 决定成功、失败或预算耗尽。

用类型固定 Agent 语言

把下面的领域类型放进 src/brief_agent/domain.py,让模型适配器和运行时共同依赖它们。

PYTHON
from dataclasses import dataclass, field
from typing import Any, Literal

@dataclass(frozen=True)
class Goal:
    topic: str
    audience: Literal["engineer", "manager"]

@dataclass(frozen=True)
class Action:
    kind: Literal["tool", "finish"]
    name: str = ""
    arguments: dict[str, Any] = field(default_factory=dict)
    answer: str = ""

@dataclass(frozen=True)
class Observation:
    ok: bool
    source: str
    data: dict[str, Any]

@dataclass
class AgentState:
    goal: Goal
    turn: int = 0
    observations: list[Observation] = field(default_factory=list)
    status: str = "running"

这些类型不依赖 OpenAI SDK。模型适配器只需要把当前 State 转成请求,再把模型输出转成 Action。

Runtime 拥有控制权

PYTHON
class DecisionModel:
    def decide(self, state: AgentState) -> Action:
        raise NotImplementedError

class ToolRunner:
    def execute(self, action: Action) -> Observation:
        raise NotImplementedError

class StopPolicy:
    def check(self, state: AgentState) -> str | None:
        if state.turn >= 6:
            return "budget_exhausted"
        return None

模型不能直接改 State,也不能直接调用 Tool。Runtime 接收 Action,检查白名单与预算后才执行,并把 Observation 追加到 State。

一轮运行发生什么

TEXT
state.turn += 1
      │
      ▼
model.decide(state)
      │
      ├── finish ─▶ validate answer ─▶ succeeded
      │
      └── tool ───▶ runner.execute ─▶ observation ─▶ state

Action 使用结构化字段,避免解析“请调用某个工具”这类自然语言约定。Observation 同时保存成功与错误,模型下一轮才能看到工具失败。

简单 Agent 暂时不需要哪些部件

第一版没有长期记忆、Planner、多 Agent、MCP 和向量数据库。它只需要一个 Goal、一个 State、一个决策模型、一个工具执行器和一个循环。

省略这些能力不会影响 Agent 的最小结构,反而让每次状态变化都能被打印和测试。

主体结构的验收

  • State 可以序列化,不保存客户端连接和函数对象。
  • Action 只有 toolfinish 两类。
  • ToolRunner 拒绝未注册名称。
  • StopPolicy 独立于模型输出。
  • Runtime 的每次状态变化都生成事件。

第 4 篇沿用这些领域类型,接入第一个 Function Calling 工具,并把模型请求、工具执行和结果回传收进 Agent Loop。

REFERENCES

参考链接

  1. 01Agents SDK Quickstart | OpenAI API
  2. 02Running Agents | OpenAI API
  3. 03A Practical Guide to Building Agents | OpenAI

所属系列

AI AGENT 入门教程

下一步

继续浏览相关主题

沿着同一主题继续阅读。

查看最新资讯