1. 评论甄别智能体到底解决什么问题
电商后台每天涌进来几千条评论,运营同学一条条翻,翻到第 200 条眼睛就花了。真正有价值的差评(比如“红烧肉咸得发苦,配的米饭还是夹生的”)被淹没在“好评”“还行”“物流快”这类无信息量的短评里。评论甄别智能体要做的事情很具体:给一条评论文本,判断它是否包含可参考的信息,并输出结构化的判定结果。
这个智能体适合谁?适合正在做 AI 应用工程化、想跑通第一个可运行智能体闭环的开发者。它不需要你从零手写复杂逻辑,但需要你能看懂 AI 生成的代码、能判断对错、能在出问题时指挥它改。核心检索词就三个:AI 智能体、Claude Code、comment_agent.py。整条链路是 Python 脚本调用大模型 API,用 TaoToken 统一 Key 和 API 通道接入,避免在多个模型供应商之间来回切换配置。
最小可运行闭环包含四个部分:一份 Prompt 模板定义判定标准,一个 Python 脚本封装调用逻辑,一套统一的错误返回结构保证不崩溃,一次真实评论样本的验证动作确认输出符合预期。跑通之后你会得到一个能直接复用的 comment_agent.py,后续换 Prompt 就能改行为,不用动代码。
我试过把这套骨架直接搬到商品问答、工单分类场景,改的只是 Prompt 和字段名,脚本结构基本不动。这就是工程化的价值:一次搭好,多处复用。
2. 前置准备:用 TaoToken 统一 Key 和 API 通道
在写代码之前,先把 API 通道理顺。很多同学卡在第一步:Anthropic 官方 Key 申请流程长、额度管理麻烦,换模型又要重新配一套环境变量。TaoToken 的思路是提供一个统一的 API 入口,一个 Key 走通模型对话、编码计划、控制台管理。
你需要做三件事:
第一,注册并拿到 API Key。访问官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 完成注册,然后进控制台 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 创建 Key。Key 只在创建时完整显示一次,复制保存好。
第二,确认 API 基地址。TaoToken 的 API 入口是 https://taotoken.net/api,注意这个地址不带 UTM 参数,直接用于代码里的 base_url 配置。
第三,把 Key 写进 .env 文件,不要硬编码在脚本里。项目根目录建一个 .env:
# .env TAOTOKEN_API_KEY=sk-你的实际Key TAOTOKEN_BASE_URL=https://taotoken.net/api同时建 .gitignore,把 .env 排除掉:
# .gitignore .env __pycache__/ *.pyc依赖安装两条命令搞定:
pip install anthropic python-dotenv这里有个容易踩的坑:anthropic 库默认会去连官方地址,如果你不显式传 base_url,请求会走错通道导致鉴权失败。所以初始化客户端时必须带上 base_url 参数,下一节的代码里会体现。
如果你更习惯用 Claude Code 这类编码工具来生成和调试脚本,TaoToken 的 Coding Plan 页面 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 有对应的接入说明,长期做 Agent 开发的话可以关注。模型对话能力可以在 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 先手动验证一下通道是否通。
3. 可复制配置:config.toml 与 comment_agent.py
3.1 config.toml 统一管理参数
把模型名、超时、截断长度这些可变参数抽到配置文件,改行为不用动代码:
# config.toml [api] base_url = "https://taotoken.net/api" model = "claude-sonnet-4-20250514" timeout = 30 max_retries = 2 [agent] max_input_chars = 2000 temperature = 0.0 prompt_file = "prompt_template.txt"读取配置用 Python 3.11+ 自带的 tomllib,不用额外装包:
import tomllib def load_config(path: str = "config.toml") -> dict: with open(path, "rb") as f: return tomllib.load(f)3.2 prompt_template.txt 判定标准
Prompt 决定智能体的行为边界。这份模板定义了四个判定维度和严格的 JSON 输出格式:
你是一个专业的用户评论质量审核员,擅长从海量评论中甄别出真正有参考价值的评论。 任务:判断给定评论是否有效,依据以下四个维度综合判断: 1. 具体性:是否包含具体的人、事、物、场景描述 2. 可验证性:描述是否可被其他用户验证或复现 3. 相关性:内容是否与商品/服务本身相关 4. 信息密度:是否提供了超出常识的有效信息 输出格式:必须严格输出以下 JSON,不包含任何其他文字、引导语或 Markdown 代码块标记: { "valid": true 或 false, "reason": "判定理由,中文,不超过80字", "details": { "specificity": true 或 false, "verifiability": true 或 false, "relevance": true 或 false, "information_density": true 或 false } } 边界规则: - 空输入、纯空格:valid 为 false,reason 为"输入为空" - 纯表情、纯符号、纯数字:valid 为 false,reason 为"无有效文本内容" - 非中文内容:valid 为 false,reason 为"非中文内容,暂不支持" - 仅有情绪表达无事实(如"太难吃了!垃圾!"):valid 为 false,reason 为"仅有情绪表达,无具体事实"3.3 comment_agent.py 核心脚本
脚本的关键设计是:所有错误路径返回与正常输出结构一致的字典,valid 为 false,details 四个维度全 false。这样调用方永远拿到统一结构,不用写一堆 if 判断。
"""评论甄别智能体:输入评论文本,输出结构化判定结果。""" import os import re import json import tomllib from typing import Any from dotenv import load_dotenv from anthropic import Anthropic load_dotenv() def load_config(path: str = "config.toml") -> dict: with open(path, "rb") as f: return tomllib.load(f) CONFIG = load_config() CLIENT = Anthropic( api_key=os.getenv("TAOTOKEN_API_KEY"), base_url=os.getenv("TAOTOKEN_BASE_URL", CONFIG["api"]["base_url"]), ) def _error_result(reason: str) -> dict: """构造统一结构的错误返回。""" return { "valid": False, "reason": reason, "details": { "specificity": False, "verifiability": False, "relevance": False, "information_density": False, }, } def _load_prompt() -> str: with open(CONFIG["agent"]["prompt_file"], "r", encoding="utf-8") as f: return f.read() def _parse_output(text: str) -> dict: """解析模型输出,先尝试直接 json.loads,失败则正则提取花括号内容。""" try: return json.loads(text) except json.JSONDecodeError: match = re.search(r"\{.*\}", text, re.DOTALL) if match: try: return json.loads(match.group()) except json.JSONDecodeError: pass return _error_result("模型输出解析失败") def analyze_comment(comment_text: str, model: str | None = None) -> dict: """分析单条评论,返回结构化判定结果。 Args: comment_text: 待分析的评论文本。 model: 可选,覆盖配置中的模型名。 Returns: 包含 valid、reason、details 的字典。 """ if comment_text is None: return _error_result("输入为空") if not isinstance(comment_text, str): return _error_result("输入类型错误,需为字符串") if not comment_text.strip(): return _error_result("输入为空") max_chars = CONFIG["agent"]["max_input_chars"] truncated = False if len(comment_text) > max_chars: comment_text = comment_text[:max_chars] truncated = True try: resp = CLIENT.messages.create( model=model or CONFIG["api"]["model"], max_tokens=512, temperature=CONFIG["agent"]["temperature"], system=_load_prompt(), messages=[{"role": "user", "content": comment_text}], ) raw = resp.content[0].text result = _parse_output(raw) if truncated: result["reason"] = result.get("reason", "") + "(评论过长,已截断)" return result except Exception as e: return _error_result(f"API调用异常:{type(e).__name__}") if __name__ == "__main__": samples = [ "", " ", "还行吧", "红烧肉软烂入味,肥而不腻,配的米饭粒粒分明,分量足,两个人吃刚好,就是上菜等了25分钟。", "太难吃了!垃圾!", ] for i, s in enumerate(samples, 1): print(f"--- 测试 {i} ---") print(f"输入: {s[:30]!r}") print(f"结果: {json.dumps(analyze_comment(s), ensure_ascii=False)}")注意 _error_result 这个辅助函数,它保证了空输入、类型错误、解析失败、API 异常四条路径返回的结构完全一致。这是工程化里最容易被忽略但最影响下游调用的细节。
4. 验证请求与成功结果
4.1 先验证 API 通道
在跑完整脚本前,先用最小请求确认 TaoToken 通道是通的:
from anthropic import Anthropic import os from dotenv import load_dotenv load_dotenv() client = Anthropic( api_key=os.getenv("TAOTOKEN_API_KEY"), base_url="https://taotoken.net/api", ) resp = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=64, messages=[{"role": "user", "content": "回复两个字:通了"}], ) print(resp.content[0].text)如果这里报鉴权错误,先检查 Key 是否复制完整、base_url 是否写对。通道通了再跑主脚本。
4.2 运行 comment_agent.py
python comment_agent.py预期输出(实际 reason 措辞可能略有差异):
--- 测试 1 --- 输入: '' 结果: {"valid": false, "reason": "输入为空", "details": {"specificity": false, "verifiability": false, "relevance": false, "information_density": false}} --- 测试 2 --- 输入: ' ' 结果: {"valid": false, "reason": "输入为空", "details": {...}} --- 测试 3 --- 输入: '还行吧' 结果: {"valid": false, "reason": "缺少具体描述,信息密度不足", "details": {...}} --- 测试 4 --- 输入: '红烧肉软烂入味,肥而不腻...' 结果: {"valid": true, "reason": "包含具体菜品描述和口感细节", "details": {"specificity": true, "verifiability": true, "relevance": true, "information_density": true}} --- 测试 5 --- 输入: '太难吃了!垃圾!' 结果: {"valid": false, "reason": "仅有情绪表达,无具体事实", "details": {...}}4.3 真实样本验证动作
拿一条真实评论做端到端验证,观察四个维度是否被正确拆解:
from comment_agent import analyze_comment sample = "买了三天,屏幕右上角出现一条竖线,重启没用,联系客服说要寄回检测,来回运费谁出没说清楚。" result = analyze_comment(sample) print(result)预期 valid 为 true,specificity 和 verifiability 为 true,因为描述了具体故障现象和时间线。如果 details 里 relevance 被判 false,说明 Prompt 对“相关性”的定义需要收紧——这类偏差先记录,不要立刻改,等积累一批样本再统一调。
验证成功的标准很简单:脚本不崩溃、输出是合法 JSON、空输入被拦截且没调用 API、详细评论被判有效、情绪发泄被判无效。做到这四点,最小闭环就跑通了。
5. 本篇常见错排查
5.1 鉴权失败 401
最常见的原因是 base_url 没传或传错。anthropic 库不传 base_url 会走官方地址,你的 TaoToken Key 在那边不认。检查初始化代码里 base_url 是否为 https://taotoken.net/api。另一个原因是 .env 没被加载,确认 load_dotenv() 在读取环境变量之前调用。
5.2 模型输出带引导语导致解析失败
有时候模型会返回“好的,以下是判定结果:{...}”。脚本里的正则回退能兜住大部分情况,但如果引导语里也含花括号就会误匹配。解决办法是在 Prompt 里强调“不包含任何其他文字、引导语或 Markdown 代码块标记”,并在 _parse_output 里优先匹配最后一个完整 JSON 对象。
5.3 空输入仍然调用了 API
检查 analyze_comment 里的三个前置判断顺序:None 检查、类型检查、strip 后空检查。如果漏了 isinstance 检查,传入数字会走到 API 调用报错。可以在空输入分支加一行 print 确认没走网络请求。
5.4 超长评论截断后 reason 没提示
截断逻辑里 truncated 标志位要在解析成功后才拼接提示。如果模型返回解析失败走了 _error_result,截断提示就丢了。这是可接受的,因为错误结果的 reason 已经说明了失败原因。
5.5 异常处理返回 None
AI 生成的代码有时会在 except 块里写 return None 或只 print。这会导致调用方拿到 None 后崩溃。必须改成返回 _error_result(...),保持结构一致。发现这种情况直接改代码,或者让 Claude Code 重新生成异常处理段。
5.6 依赖版本冲突
anthropic 库版本更新较快,旧版本的 messages.create 参数名可能不同。如果报 TypeError 说参数不认识,先 pip show anthropic 看版本,必要时 pip install -U anthropic 升级。python-dotenv 一般不会有问题。
6. 下一步:把 Key 和通道固定下来
跑通这个闭环之后,你手里有了一个能复用的骨架:config.toml 管参数,prompt_template.txt 管行为,comment_agent.py 管逻辑,TaoToken 统一 Key 管通道。后续换场景只需要改 Prompt 和字段名,脚本结构不动。
如果你要长期做编码类 Agent 开发,建议把 API Key 和接入文档放在手边:API Keys 管理页 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 用来创建和轮换 Key,接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 有各语言的调用示例。想先在网页上手动验证模型输出格式,可以用模型对话 https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 快速试。长期跑 Agent 任务、需要稳定额度的,看 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite。
一个实用技巧:把 config.toml 里的 temperature 设成 0.0 做判定类任务,输出更稳定;做创意类任务再调到 0.7 以上。这个参数改一行就能生效,不用动脚本。