☰
PydanticAI生产级Agent实战:从类型安全到可观测性
2026/10/21 6:55:15 网站建设 项目流程

做LLM应用做到后期,我最怕的不是模型答错,而是模型答得“看起来对但没法用”。你说返回JSON,它给你多出几个字段;你要的是枚举值,它给你一句“很高”;你说这是0到1的置信度,它传了个字符串。每一处偏差,到生产环境都是线上事故。把大模型接进业务系统,本质是在跟不确定性打交道,而工程上对抗不确定性的手段从来都是类型、校验、契约和可观测性。这篇文章是系列实战项目里的第五个项目,主题很明确:基于PydanticAI这种类型优先的Agent框架,实现一个真正能扛线上压力的生产级LLM Agent。我会把从架构思考到代码落地的全过程摊开讲,适合已经跑通过模型API、想进一步把代码做成企业级工程的Python开发者。

1. 为什么生产级Agent必须解决类型安全

1.1 从“能跑通到能上线”之间隔着一堆隐形坑

在Demo阶段,模型输出的文本只要能贴出来看一眼,项目就算“成了”。但到了生产环境,Agent的输出会被下游系统消费:它会作为工单系统的分类字段、作为数据库里的一条记录、作为另一个Agent的输入。这时候,输出就不是“一句话”,而是一份必须遵守契约的数据。

我见过太多场景翻车。要求模型返回JSON,结果字段名变成首字母大写的驼峰,对不上;要求category只能是“网络、账号、计费、其他”,模型返回了“系统问题”这种新增值;要求confidence是0到1之间的浮点数,模型返回了一个百分比字符串“85%”。更隐蔽的是,模型偶尔多返回一两个字段,当时解析看着没事,后续代码版本升级却突然崩掉。

这些问题的根源在于,自然语言生成天然具有随机性,而业务系统天然要求确定性。prompt里写的“请严格按照格式”只是软约束,它经不起边界情况和模型版本迭代的考验。生产系统需要的是硬约束:在进程边界处,对输入输出做一次全面校验,不合法就直接拒绝、重试或降级,而不是把脏数据放进行业核心流程流转。

这里有一个关键认知转变:LLM生成的输出,本质上等同于一个外部服务返回的响应体。你调用别的HTTP接口时,会用response model做反序列化和校验,为什么调用大模型时,能容忍它裸返回一个字符串,然后到处切片处理?类型安全,就是把这一层校验前移、内建到Agent框架里,让每一份从模型侧出来的数据,都先过一遍合同再进业务代码。

1.2 PydanticAI 为什么把类型安全做成地基

PydanticAI最让我欣赏的一点,是它没有把类型安全当作“附加功能”,而是直接做成了框架的地基。Pydantic本身是Python里最流行的数据校验库之一,定义模型类、自动生成JSON Schema、执行字段校验和类型转换,这一套成熟能力被直接继承到了Agent框架里。

使用起来感受完全不同。你定义Agent的输出类型,不是写死一个巨长的prompt让它猜,而是声明一个Pydantic模型类,字段约束、枚举、嵌套结构一目了然。模型返回后,框架会按这个模型做解析和校验,校验失败时可以触发重试机制,让模型重新生成。工具函数同样受到类型约束,框架会从函数签名生成工具Schema,模型在调用工具时,参数也会经过校验。

这和很多“编排优先”的框架是两条路线。编排优先的框架会提供一大堆链式组件、记忆模块、插件市场,帮你把业务串起来,类型校验只是其中一环,甚至不存在。PydanticAI的路线更像是把一个Agent当成一个强类型函数来对待:输入是结构化的用户消息和依赖,输出是校验过的结构化对象。

类比一下:普通框架让你把大模型当“同事”,你说一句它做一句,结果靠人情维系;PydanticAI让你把大模型当“外部服务”,前后端签好接口文档,任何违约都在网关层拦截。后者才是企业级项目需要的稳定关系。尤其对于从Java这类强类型语言转过来的同学,你会觉得Agent开发终于有章法了,而不是在写一段充满咒语的脚本。

1.3 企业级工程诉求与框架能力的映射

我在实际规划生产级Agent时,习惯先列一份工程诉求清单,再对照框架能力看哪些被天然满足,哪些还需要自己补。这张表是我自己整理的常用对照,供参考:

工程诉求说明PydanticAI的对应能力
输出契约校验字段类型、枚举范围、嵌套结构不能漂移结果模型解析与校验,验证失败自动重试
工具调用安全模型不能把工具参数拼错类型工具函数签名自动生成Schema,参数强校验
可观测性每次请求的token、耗时、重试次数可查运行结果对象、事件钩子、请求上下文
可测试性不依赖真实模型也能做单测可注入依赖、结构化输出可直接断言
配置治理模型、提示词、密钥分开管理模型标识走配置,提示词版本化靠工程约束

不是说框架能解决所有问题,而是说它把最难的那部分——不可预测的输出——放到了一个可校验、可失败的通道里。我在项目五里最终选它,核心原因是业务系统对输入输出有强约束:分类必须是预置枚举,紧急度要有明确映射,置信度要参与后续自动决策。这要求框架不仅能跑通对话,还要能产出信得过、查得到、可回滚的数据。选型时我也对比过几个方向,有的输出校验要靠自己额外封装,有的工具调用链路是黑盒,到了排查线上问题的时候,你根本不知道模型那一步做了什么决定。PydanticAI的模型和工具链路相对透明,出错时还能拿到原始消息与最终输出,这对排障特别重要。

2. 框架的整体架构设计与模块边界

2.1 一个Agent单元的职责划分

先不谈代码,谈组织架构。生产级的Agent应用,绝对不是把一堆Prompt拼在一起就完事。我倾向于把系统拆成若干“Agent单元”,每个单元负责一个有明确边界的业务动作,对外暴露结构化输入输出,内部可以有自己的工具和上下文。

一个标准Agent单元有四个组成部分。模型配置:选用哪个模型、温度参数、最大重试次数;系统提示词:描述角色、任务规则、输出约束;工具集:允许该Agent调用的函数列表,每个工具都有签名和说明;结果类型:当前任务必须返回的结构化数据类型。

设计边界时有个原则:如果某个Agent要挂超过10个工具,或者系统提示词超过一屏,说明职责过重,要拆。举个例子,我在做一个工单处理系统时,不会用一个巨大的Agent同时做分类、紧急度评估、知识库检索、回复生成。我会拆成三个:工单分诊Agent,负责分类和紧急度判断,输出结构化结果;方案检索Agent,基于分类结果检索知识库,返回候选方案;回复生成Agent,把方案结合工单原文,生成一段给用户的回复。

每个Agent只做一个决策,决策结果用类型固定的对象传递。这样做最大的好处是,单个Agent出错你很容易知道错在哪一环,而且可以针对不同环节用不同的模型。重要的环节用贵而准的模型,简单环节用便宜快的模型,成本控制也更容易做。

2.2 从单Agent到多Agent的组织形态

多个Agent之间怎么协作,是架构里必须提前想清楚的事。一般有三种常见形态:

  • 流水线模式:A的输出作为B的输入,像管道一样顺序往下走,适合分类、抽取、整理这类任务流;
  • 路由模式:由路由Agent根据输入派发到不同的专业Agent,适合客服机器人这种入口统一、后台能力分域的场景;
  • 会合模式:多个Agent并行处理子问题,最后汇总Agent合并结果,适合需要多角度分析的场景。

我更推荐流水线和路由的组合。因为每个Agent都输出强类型对象,Agent之间的数据传递天然是结构化的,不会出现“上一环节生成了一段废话,下一环节还得自己解析”的尴尬。多Agent之间的状态也可以统一存在结构化数据里,方便追踪和审计。

有一点要特别注意:别让Agent之间直接传递自由文本并反复对话。这样既难以控制成本,又很容易出现上下文漂移。正确做法是把上一步的结构化输出当作下一步的输入消息,配合系统提示词说明“你将收到上一步的结论,基于这些结论做后续处理”。一旦消息退回自由文本,你前面做的类型安全设计就白费了。

2.3 依赖注入与上下文处理的思路

Agent要从业务系统里读取数据,就得访问外部服务。生产环境里,模型服务、数据库连接、内部接口调用,这些都是Agent的外部依赖。如果依赖写在工具函数内部,测试和替换会非常痛苦。

PydanticAI的依赖注入机制解决了这个痛点。你可以定义Deps类型,把连接、配置、服务客户端封装进去,在运行Agent时一次性传入。工具函数通过上下文对象获取依赖,而不是自己创建全局单例。这样做之后,Agent的核心逻辑和外部资源解耦,换数据库、换安全服务、换配置中心,都不用改Agent本体。

依赖的生命周期也要分清楚。应用级依赖,比如配置、日志客户端、数据库连接池,进程启动时创建,全局共享;请求级依赖,比如当前用户身份、本次请求ID、会话上下文,每次请求时创建,避免串数据。我用一个比较土但很有效的办法检查代码是否健康:看工具函数里有没有出现模块级可变全局变量。只要出现,大概率就是并发安全隐患。

依赖注入还有一个隐藏福利:测试。单测时传入内存版依赖,集成测试时传入真实依赖,Agent代码本身不用改。这在后面讲测试策略时会重点展开。

3. 核心代码实现与关键步骤

3.1 环境准备与最小可运行示例

先搭环境。我习惯用虚拟环境隔离项目依赖,然后安装PydanticAI。这里以我当时使用的版本为例,版本更新后API可能有微调,具体以官方文档为准。

pip install pydantic-ai

PydanticAI会依赖Pydantic v2,安装时会自动带上。接着配置模型供应商的访问信息,一般通过环境变量传入。我在项目里会统一做一个配置组件,从环境变量读取模型名称和密钥,不会在业务代码里散落任何凭据。

一个最小可运行的Agent大概长这样:

import asyncio from pydantic_ai import Agent agent = Agent( "your-model-identifier", # 替换为你接入的模型服务商约定标识 system_prompt="你是一个简洁的助手,直接回答问题。", ) async def main(): result = await agent.run("用一句话解释什么是生产级Agent") print(result.output) if __name__ == "__main__": asyncio.run(main())

这个示例虽然简单,但已经包含了理解整个框架的最小路径:Agent对象承载模型配置和系统提示词,run方法接收用户输入,返回运行结果。后面的类型安全实现,都是在这个骨架上加肉。

3.2 用类型安全模型约束Agent的输出

接下来进入核心环节:让Agent的输出不再是自由文本,而是一个有契约的结构化对象。

假设场景是工单分诊Agent:输入一段用户报障文本,输出分类、紧急度、置信度和一句话摘要。我先定义一个Pydantic模型:

from typing import Literal from pydantic import BaseModel, Field class TicketAssessment(BaseModel): category: Literal["网络故障", "账号安全", "计费问题", "其他"] = Field(description="工单分类") urgency: Literal["低", "中", "高", "紧急"] = Field(description="紧急程度") confidence: float = Field(ge=0.0, le=1.0, description="本次判断置信度") summary: str = Field(max_length=100, description="一句话摘要")

如果你的Python版本低于3.10,Literal要从typing_extensions导入,Pydantic本身也会用到这个类型。定义好模型后,把它传给Agent的result_type参数:

agent = Agent( "your-model-identifier", system_prompt=( "你是工单分诊助手。请根据用户描述,判断工单分类和紧急程度。" "分类必须在给定枚举中,紧急程度也必须在给定枚举中," "置信度是0到1之间的浮点数,不要输出额外解释。" ), result_type=TicketAssessment, max_retries=3, )

运行后,result.output就是一个TicketAssessment实例,字段和类型都经过校验,可以直接被下游逻辑消费。一旦模型返回的JSON解析失败或字段校验失败,框架会按max_retries设定的次数让模型重新生成。

这带来的改变是质变级别的。你写的代码不再假设模型“大概率会守规矩”,而是要求它“必须守规矩,不守就重来”。只要重试仍然失败,异常会在你的进程里抛出,你可以捕获并做降级处理,这比拿到一份坏数据然后到处排查要舒服得多。

3.3 工具注册与依赖注入的完整案例

工单分诊不能只靠模型猜,需要调用真实数据辅助判断。比如用户说“我的账号在异地登录了”,Agent应该能查询历史登录记录,判断是否真的存在风险。

先定义依赖类型。依赖是每个请求独立的,所以我把当前请求ID也放在里面:

from dataclasses import dataclass @dataclass class AgentDeps: security_service: object # 安全服务客户端,真实项目替换为具体类型 ticket_repo: object # 工单仓库 request_id: str # 本次请求ID

再定义Agent,并在构造参数里声明依赖类型:

agent = Agent( "your-model-identifier", deps_type=AgentDeps, result_type=TicketAssessment, system_prompt="你是工单分诊助手...", )

然后通过装饰器注册工具。工具函数注意它的第一参数是上下文对象,框架会把运行时的依赖注入进来:

from pydantic_ai import RunContext @agent.tool async def query_login_logs( ctx: RunContext[AgentDeps], account: str, days: int = 30 ) -> list[dict]: """查询指定账号最近N天的登录日志,用于判断账号是否异常。""" return await ctx.deps.security_service.get_login_logs(account, days)

工具函数有几个细节值得专门说。第一个参数RunContext必须放在最前面,这是框架的约定,模型生成的参数会从第二个参数开始映射。函数签名里的注释很重要,模型会读它来理解工具的用途和参数含义,写得越清楚,调用成功率越高。返回类型要尽量具体,框架会根据返回类型对工具输出做解释,如果返回裸字符串,模型后续推理就容易失去抓手。

运行Agent时把依赖对象传进去:

async def main(): deps = AgentDeps( security_service=SomeService(), ticket_repo=SomeRepo(), request_id="req-001", ) result = await agent.run( "我的账号昨晚在异地登录了,请帮我评估风险", deps=deps, ) print(result.output)

这样Agent在处理过程中可以自主决定是否调用查询工具,再把工具结果作为上下文综合判断,最后输出结构化工单评估。整个调用链路里,工具返回值是结构化的,最终输出也是结构化的,没有一处需要靠正则去捞信息。

3.4 让Agent区分轻重缓急:紧急度评估场景实现

上面已经是一个能用的分诊Agent,我们再展开一个更完整的场景,看Agent如何把工具调用和结构化输出串起来。

业务规则是:账号安全问题优先级最高,其次计费问题,网络波动类问题往往不是紧急级。但规则不能写死,因为用户描述可能是“网连不上了,但用手机热点还能上”,模型需要结合语义判断。同时,模型可以调用“查询账号状态”工具拿到账号是否正常的信息来辅助判断。

这是我理解的生产级Agent典型特征:业务规则不可能穷尽所有输入,必须靠模型理解语义,但最终决策必须落到确定性的枚举和字段上。代码层面大致如下:

class AccountStatus(BaseModel): status: Literal["正常", "已被锁定", "存在风险"] last_active_days: int failed_attempts: int @agent.tool async def check_account_status( ctx: RunContext[AgentDeps], account_id: str ) -> AccountStatus: """查询账号当前状态,返回状态、最近活跃天数和失败尝试次数。""" raw = await ctx.deps.security_service.check(account_id) return AccountStatus(**raw) @agent.tool async def get_incident_history( ctx: RunContext[AgentDeps], account_id: str ) -> list[dict]: """查询该账号历史工单记录,用于识别重复问题。""" return await ctx.deps.ticket_repo.list_by_account(account_id)

Agent运行时会先分析用户描述,决定是否需要调用工具。比如用户提到“账号被锁定”,它会去查AccountStatus确认状态;如果用户只说“网慢”,它可能不调用工具直接分诊。这个“决定调不调工具”的动作,也由模型自己完成,只不过它的选择空间被工具Schema限制住了,不会调用不存在的函数。

系统提示词我也写出来,供参考:

你是企业级工单分诊Agent。 工作步骤: 1. 根据用户报障文本,判断是否需要查询账号状态或历史工单; 2. 必要时调用工具补充事实; 3. 结合工具返回结果,输出最终评估。 输出要求: - category只能是"网络故障、账号安全、计费问题、其他"; - urgency只能是"低、中、高、紧急"; - confidence是0到1浮点数; - summary不超过100字。

这种“步骤+输出约束”的提示词和结果模型配合,实测下来比单纯丢一句“请规范输出”稳定得多。因为提示词给了决策链路,结果模型给了最终格式,模型在每一步都知道自己在干什么,而不是靠猜。

3.5 可观测性:日志、指标与重试策略

生产级应用如果不知道模型每次想什么、花了多少钱、重试了几次,那基本就是盲人骑瞎马。PydanticAI的运行结果对象里含有很多可观测信息,但我在项目里还会包一层自己的统一入口函数来做日志。

每个Agent调用都会记录这些信息:请求ID、Agent名称、模型标识、输入文本长度、调用耗时、输出对象、重试次数和异常信息。下面是一段接近实践的伪代码:

import logging import time logger = logging.getLogger("agent") async def run_with_logging(agent, prompt, deps): start = time.monotonic() try: result = await agent.run(prompt, deps=deps) elapsed = time.monotonic() - start output = result.output logger.info( { "event": "agent_completed", "request_id": deps.request_id, "agent": getattr(agent, "name", "unknown"), "elapsed_ms": round(elapsed * 1000, 2), "output": ( output.model_dump() if hasattr(output, "model_dump") else str(output) ), } ) return result except Exception as exc: logger.error( { "event": "agent_failed", "request_id": deps.request_id, "error": str(exc), } ) raise

重试策略要单独说。max_retries参数虽然好用,但模型重试一次就是一次真实调用和真实费用。我通常把max_retries控制在2到3次,既不轻易放过一次侥幸成功,也不至于无限烧钱。对所有验证失败的请求记录失败原因,按原因归类统计,这些数据要反哺给提示词和结果模型的优化,而不是只停留在日志里。

3.6 测试策略:从模拟响应到影子回放

生产级系统得能测试。我分三个层级来测Agent,每个层级都不依赖真实模型调用,所以测试又快又稳。

第一层是契约测试。不调模型,直接用手写数据测试Pydantic模型的校验逻辑,确保枚举、范围、长度这些约束符合预期。这一层覆盖的是最坏情况,比如模型返回了超长的summary、负数置信度、枚举外的分类,看模型对象能不能把它们挡在门外。

第二层是集成测试。把工具函数替换成内存实现,用一段固定的模拟模型响应跑通Agent的完整链路。做法是给Agent注入一组预先准备好的消息,或者在工具层做好mock。因为输出是结构化对象,断言非常干脆:一句assert result.output.category == "账号安全"就能完成验证,不需要对一大段文本做模糊匹配。

第三层是回归测试。把线上真实的用户输入和模型输出录制下来,在提示词或代码改动后回放比对。这能有效发现“改了一句话导致整个输出风格变了”的问题。我在一次提示词微调后,就是靠回归测试发现某个分类的措辞变了,影响了下游的工单分组逻辑。

这三层测试要写进CI里。因为类型安全框架的存在,回放比对不需要复杂的语义相似度算法,直接对比模型输出对象的字段值即可,工程成本比我预想中低很多。

4. 常见问题与排查技巧实录

4.1 输出字段漂移与幻字段处理

现象:结果模型定义了四个字段,模型却返回了五个字段,多出来的字段叫recommendation。大多数情况下Pydantic校验时会忽略多余字段,但如果后续版本启用严格模式,就会直接报错。

处理方式要先问业务立场:多余字段允许吗?如果不允许,把Pydantic模型配置为严格模式,同时提示词里写明“不要输出任何额外字段”;如果允许,就在模型里显式声明一个可选的extra字段用于兜底,避免框架直接报错。

我个人的习惯是审计期允许extra字段存在。模型确实会脑补,你直接报错会导致重试次数暴涨,线上费用跟着涨。等输出稳定后再开启严格模式,反而更安全。这个先后顺序,比“一上来就追求最严”要务实得多。

4.2 工具参数解析失败的三种典型场景

最常见的问题就是Agent要调用工具,但模型生成的参数过不了校验。典型场景有三个。

第一种,工具参数名含义模糊。比如参数叫data,模型根本不知道要传什么。解决办法是把参数名改成行为指向明确的词,并在文档字符串里写清格式和示例。

第二种,嵌套类型过深。模型生成嵌套JSON时容易出错,比如List里套dict,dict里又套了多层。解决办法是工具参数尽量扁平化,能不嵌套就不嵌套。

第三种,必填参数太多,模型漏填。解决办法是把有默认值的参数全部赋默认值,只保留真正必填的参数,减少模型的负担。

排查这类问题,最有效的方式是看框架抛出的校验错误信息,它会明确指出哪个字段校验失败。不要急着改提示词,先看是不是工具签名设计得不合理。我见过太多人把锅甩给模型,实际上工具函数签名本身就是逼着模型犯错。

4.3 重试风暴与成本失控

现象:某天晚上突然收到告警,Agent请求量没变,但模型调用费用翻了三倍。排查后发现是模型输出连续校验失败,每个请求都自动重试了三次。这就是max_retries设置过大的典型事故。

我建议生产环境max_retries不超过3。对所有重试事件打指标,当某个Agent的重试率超过阈值就告警。如果重试率长时间很高,大概率是结果模型约束和实际业务不匹配,要重新设计结果模型,而不是靠重试硬扛。重试解决的是偶发性的格式问题,解决不了系统性的输出偏移。

另外,像ModelRetry这类主动要求模型重新生成的机制也要谨慎使用。能用一次判断解决的问题,别让它转两圈。每次主动重试都会增加模型总输出token,token就是成本。

4.4 依赖状态共享与并发安全

现象:上线后偶尔出现A用户的请求拿到了B用户的数据。排查代码后发现,工具函数里直接用了模块级全局变量保存当前账号,多并发请求时产生了串线。

生产级Agent跑在并发环境里,依赖注入必须遵循“请求级数据走请求级依赖”这个原则。全局单例只放线程安全的连接、配置和日志客户端。每个请求的账号、上下文、业务状态,一定要通过上下文对象挂在当前请求的依赖里。

我一般还会在依赖对象里放一个request_id,所有日志和外部调用都带它。这样问题一旦出现,很快能把整条调用链串起来,定位到是哪一个Agent、哪一个工具、哪一个用户的请求出了异常。

4.5 模型切换带来的兼容性问题

现象:测试环境用一个小模型跑得好好的,切到线上大模型后,工具调用格式反而不稳定。原因是不同模型对工具调用的实现和JSON模式的遵循程度不同。

处理方式是把模型标识收敛到一个配置组件,不要散落在代码里。切换模型时先跑一遍契约测试和回归测试,观察两个关键指标:工具调用成功率和输出校验通过率。如果大模型反而不如小模型稳定,别迷信“越贵越强”。要针对性地调整提示词或模型参数,甚至换回原来的模型,线上稳才是真的稳。

我把这类高频问题整理成一张速查表,排查时直接照着看:

症状可能原因处理方式
输出多字段或少字段模型没遵循提示词,校验策略过严严格模式+提示词兜底,或允许extra字段
工具参数解析失败工具签名复杂、参数说明不清扁平化参数、补文档示例、减少必填
重试次数飙升结果模型约束与实际输出差距大降低max_retries,重新设计结果模型
并发数据串线用全局变量存请求级状态依赖注入,请求数据放上下文对象
切换模型后稳定性下降模型工具调用能力差异统一配置模型标识,回归对比工具成功率

5. 从Demo到生产:部署演进的个人经验

5.1 配置治理与密钥管理

我见过不少项目把模型密钥直接写在代码里,或者把模型名散落在各个模块中。生产环境里,配置必须集中管理。我会用一个配置组件统一读取环境变量或配置中心,至少保证三件事:密钥和凭据不进代码仓库;模型标识、温度参数、max_retries这些运行时参数可调;开发、测试、生产每个环境有独立的配置。

配置这个东西,看起来不起眼,出事就是大事。有一次排查线上问题,发现测试环境的模型标识被误用到了生产环境,数据全乱了。从那之后我就在配置组件里加了一键校验环境标识的逻辑,环境不一致直接拒绝启动。

5.2 版本化提示词与模型灰度

系统提示词是业务逻辑的一部分,应该版本化。我习惯把每个Agent的系统提示词单独存成文件或配置项,带上版本号。改动后不是直接全量上线,而是先在新版本Agent上跑一批影子请求,对比新旧输出,确认没有劣化再灰度放量。

模型切换也一样。先小流量观察工具调用成功率和输出校验通过率,再逐步放量。这条经验是从一次事故里换来的:某次升级提示词后没有做灰度,结果所有Agent的输出风格突变,下游解析代码全部报警,只能连夜回滚。自那以后,灰度就成了我所有Agent项目的默认动作,省不掉。

5.3 最后一点私货建议

文章写到这里,方法论和代码都展示了。最后分享我在实际项目里的体会:不要把Agent当成魔法,要把它当成一个“会调用工具的异步函数”。

一旦你用这个视角看问题,很多决策就清晰了。该用类型安全输出就用,该加依赖注入就加,该上日志监控就上。模型本身会进步,但工程边界不会骗你。PydanticAI这套东西最大的价值,不是帮你写Prompt,而是逼着你把LLM的不可控输出,牢牢锁在类型系统的笼子里。

踩过几次坑之后,我现在新起一个Agent项目,第一件事永远是先定义结果模型和依赖类型,再写提示词。顺序反了,后面基本都要返工。这个习惯,可以说是整个项目五里我认为最有普适价值的一条经验了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询