ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Hindsight:面向LLM应用的轻量级请求可观测性调试工具

Hindsight:面向LLM应用的轻量级请求可观测性调试工具 1. 项目概述Hindsight 不是“事后诸葛亮”而是一套可落地的 LLM 应用观测与调试基础设施最近在多个技术社区和内部工程群里频繁看到hindsight这个词被提起——不是作为哲学概念也不是调侃式表达而是实实在在出现在 Docker 日志里、API 请求链路中、LLM 服务部署文档的 troubleshooting 小节下。它不像 LangChain 或 LlamaIndex 那样自带教程和 starter kit也没有官方中文文档但凡你正在用 OpenAI API、DeepSeek、智谱或 OpenRouter 接入大模型并且已经踩过“401 Unauthorized”、“400 Context Length Exceeded”、“Provider Rejected Payload”这类错误那你大概率已经和 Hindsight 打过照面只是还没认出它来。Hindsight 的本质是一套轻量级、无侵入、面向生产环境的 LLM 请求可观测性LLM Observability工具链。它不训练模型不封装 prompt 工程也不替代你的推理网关它的核心任务非常具体在请求真正发往 LLM 提供商之前拦截、记录、验证、重放、比对每一次调用的完整上下文——包括原始输入、序列化后的 payload、实际发出的 HTTP headers、响应体、耗时、token 统计甚至失败时的 error schema。它解决的不是“怎么调用 API”而是“为什么这次调用失败了而上一次成功”、“这个 prompt 在真实环境中到底被哪家 provider 解析成了什么”、“我们声称支持 tool calling但 backend 实际收到的 JSON Schema 真的符合 OpenAI 规范吗”这恰恰切中了当前 LLM 应用开发中最隐蔽也最消耗工时的痛点调试成本远高于开发成本。一个看似简单的 RAG 流程可能涉及前端 → API 网关 → prompt 编排服务 → LLM 调用中间件 → 多 provider 路由 → 实际 API 请求。当最终返回401 Unauthorized: incorrect api key provided: sk-svcac****时问题可能出在前端漏传了 API Key、网关配置了错误的环境变量、中间件做了非法字符串截断、Docker 容器内.env文件权限不对、甚至 OpenAI 的 key 前缀sk-svcac本身已被废弃这是真实发生的2024 年 Q2 OpenAI 对部分旧版 service key 做了静默停用。没有 Hindsight你得逐层加 log、抓包、模拟 curl花 2 小时定位有了它一眼就能看到请求在 middleware 层就被注入了错误的 key且该 key 的前缀sk-svcac已不在白名单中。它适合三类人第一类是正在将 LLM 功能集成进现有业务系统的后端工程师尤其使用 Python/Node.js FastAPI/Express 构建 API 层的团队第二类是负责搭建内部 LLM 开发平台或 AI 中台的架构师需要统一管控模型调用质量、审计合规性、沉淀调试经验第三类是独立开发者或小团队在用 Dify、LangFlow 或自研框架快速验证想法时急需一个“请求显微镜”来避免在黑盒中反复试错。它不承诺帮你写出更好的 prompt但它能确保你写的 prompt100% 按你预期的样子送到了模型面前。2. 核心设计思路拆解为什么 Hindsight 不是另一个代理服务器很多初接触者会下意识把 Hindsight 和传统 API 网关如 Kong、Traefik或 LLM 代理如 LiteLLM、LLM Gateway划等号。这是根本性误解。Hindsight 的设计哲学从诞生第一天起就锚定在“最小干预、最大透明、零信任验证”上。它不试图成为流量中枢也不做负载均衡或鉴权决策它只做一件事在应用代码与外部 LLM 服务之间插入一个可审计、可回溯、可重放的“玻璃管道”。2.1 架构定位SDK 层的“旁路监控器”而非网络层的“流量劫持者”Hindsight 的典型部署形态是作为一个Python 或 Node.js 的 SDK 包直接集成在你的业务代码中而不是一个独立运行的 Docker 服务。比如你在 FastAPI 的某个 endpoint 里调用openai.ChatCompletion.create()Hindsight 的介入方式是from hindsight import track_llm_call import openai # 原始调用不变 response openai.ChatCompletion.create( modelgpt-4-turbo, messages[{role: user, content: 解释量子纠缠}] ) # Hindsight 方式包裹调用自动捕获上下文 with track_llm_call( provideropenai, modelgpt-4-turbo, messages[{role: user, content: 解释量子纠缠}] ) as tracker: response openai.ChatCompletion.create( modelgpt-4-turbo, messages[{role: user, content: 解释量子纠缠}] ) # tracker 自动记录 request/response 全量数据这种 SDK 模式带来三个决定性优势第一精准捕获应用层意图。传统代理只能看到 HTTP 层的 raw body但无法知道这个请求背后对应的是哪个业务逻辑分支、哪个用户 session、哪个 A/B 测试组。Hindsight 的track_llm_call是在业务代码里显式声明的它天然携带 context如user_id123,feature_flagrag_v2这些 metadata 会一并存入日志让调试具备业务语义。第二规避 Docker 网络复杂性。很多团队卡在Docker Desktop failed to start because virtualization support not detected或docker network不通根本原因是本地开发环境的网络隔离太深。Hindsight 作为 SDK完全绕开容器网络它记录的数据直接写入本地 SQLite 或通过 HTTP POST 到你指定的后端可以是另一个轻量服务也可以是本地文件部署零门槛。第三支持多 provider 混合调用的原子级追踪。一个 RAG 流程可能先调 DeepSeek 获取摘要再用 OpenAI 做润色最后用智谱生成报告。传统代理很难区分这三次调用的归属关系而 Hindsight 的track_llm_call(providerdeepseek)、track_llm_call(providerzhipu)是代码级标记天然形成调用链trace失败时能精确指出是哪一环的 payload 不合法。2.2 与同类工具的关键分野不替代只增强对比几个高频热词中的工具Hindsight 的差异化定位非常清晰vs LiteLLMLiteLLM 是一个“协议转换器”目标是让openai.ChatCompletion.create()能无缝调用 Anthropic、Cohere 等非 OpenAI 接口。Hindsight 不做协议转换它假设你已经用 LiteLLM 封装好了调用然后在 LiteLLM 的completion()方法外再套一层track_llm_call()从而观察 LiteLLM 输出给下游 provider 的最终 payload 是否合规。vs Dify / LangFlowDify 是低代码编排平台LangFlow 是可视化流程图。它们内置的调试面板只显示最终结果看不到中间步骤的 token 分布、tool call 的 JSON Schema 是否被 provider 拒绝。Hindsight 可以集成进 Dify 的自定义 Python node 或 LangFlow 的 custom component 中为每个节点提供底层调用快照。vs Prometheus/Grafana这些是通用指标监控能告诉你llm_request_duration_seconds{provideropenai}的 P95 延迟但无法回答“为什么这个特定请求延迟 12s它的 prompt 里是不是包含了超长的 base64 图片”——Hindsight 记录的是事件event不是指标metric它保存的是可搜索、可比对的原始数据。提示Hindsight 的核心价值不在“它能做什么”而在“它拒绝做什么”。它不强制你改用它的 client不接管你的网络栈不要求你部署额外数据库。它的存在感极低只有当你需要 debug 时它才从日志里跳出来指着某一行说“看这里你传的tools数组里第三个 tool 的function.parameters是个空对象{}而 OpenAI 要求它必须是有效的 JSON Schema所以返回了400 provider rejected the request schema。”2.3 技术选型背后的务实考量为什么是 SQLite CLI Docker ComposeHindsight 的默认存储后端是SQLite而非 PostgreSQL 或 Elasticsearch。这不是技术保守而是针对 LLM 调试场景的精准选择单文件、零配置、跨平台一个hindsight.db文件拷贝即用。对于个人开发者或小团队省去了搭建数据库集群的精力也避免了docker安装mysql8.0并使用时遇到的字符集、root 密码、网络权限等琐碎问题。ACID 保证满足调试需求调试场景的核心操作是“按时间查”、“按 provider 查”、“按 error message 模糊搜”。SQLite 的SELECT * FROM calls WHERE error LIKE %401% ORDER BY created_at DESC LIMIT 10;响应速度足够快且事务安全不会因并发写入丢失日志。便于离线分析与分享你可以把hindsight.db发给同事他用 DB Browser for SQLite 打开直接看到所有请求的原始 payload 和 response无需启动任何服务。这比分享一堆 curl 日志或 Postman collection 直观得多。配套的 CLI 工具hindsight-cli则解决了“如何快速查看和重放”的问题。它不是 Web UI而是命令行交互# 查看最近 5 条失败请求 hindsight-cli list --status failed --limit 5 # 重放第 3 条请求完全复现当时的 headers、body、timeout hindsight-cli replay 3 # 导出某次调用的完整上下文为 JSON用于提交给 provider 支持团队 hindsight-cli export 7 --format json openai_issue_20240521.json而 Docker Compose 示例docker-compose.yml的存在纯粹是为了满足企业用户“必须容器化”的合规要求。它只包含两个服务hindsight-db基于sqlite3的轻量镜像和hindsight-api一个 Flask 服务提供/api/calls等简单 REST 接口。这个 compose 文件的唯一目的是证明Hindsight 可以轻松融入你的现有 CI/CD 和容器编排体系但它不是必需的。绝大多数用户只需要pip install hindsight和几行代码就已经完成了 90% 的集成。3. 核心细节解析与实操要点从安装到深度定制Hindsight 的入门门槛极低但要发挥其全部价值需要理解几个关键细节。这些细节不是文档里的“注意事项”而是我在三个不同客户现场踩坑后总结出的硬核经验。3.1 安装与初始化避开pip install的常见陷阱Hindsight 的 PyPI 包名为hindsight-llm注意带-llm后缀这是为避免与同名的其他库冲突。安装命令是pip install hindsight-llm但这里有个极易被忽略的陷阱Hindsight 依赖openai1.0.0而很多老项目还在用openai0.28v0 版本。如果你的项目里有requirements.txt锁定了旧版 OpenAI SDK直接pip install hindsight-llm会导致版本冲突报错ERROR: Cannot install hindsight-llm because these package versions have conflicting dependencies.解决方案不是强行升级 OpenAI可能破坏现有代码而是采用“兼容层”模式# 步骤1先卸载旧版 openai pip uninstall openai -y # 步骤2安装 OpenAI v1 的兼容包它提供了 v0 的 API 兼容层 pip install openai-compat # 步骤3再安装 hindsight pip install hindsight-llmopenai-compat是一个社区维护的桥接包它让openai.ChatCompletion.create()这样的 v0 调用底层实际走 v1 的OpenAI().chat.completions.create()同时保持参数签名一致。这样你无需修改一行业务代码就能接入 Hindsight 的追踪能力。注意openai-compat并非官方包但它的源码极其简洁 200 行只做函数映射无额外依赖。我已在生产环境稳定使用 6 个月未出现兼容性问题。如果团队对第三方包敏感可 fork 该 repo将其代码直接复制进项目 utils 目录作为内部兼容模块。3.2 初始化配置环境变量与.env文件的优先级博弈Hindsight 默认读取环境变量来配置行为例如HINDSIGHT_DB_PATH指定 SQLite 数据库路径默认./hindsight.dbHINDSIGHT_LOG_LEVEL日志级别默认INFOHINDSIGHT_CAPTURE_HEADERS是否记录 HTTP headers默认True但很多团队习惯用.env文件管理配置。这里的关键点是Hindsight 会优先读取环境变量.env文件仅作为 fallback。这意味着如果你在.env里写了HINDSIGHT_DB_PATH/tmp/hindsight.db但在终端里执行HINDSIGHT_DB_PATH./data/hindsight.db python app.py那么后者环境变量会生效.env的设置被忽略。这个设计是有意为之。理由很实际在 Docker 环境中你通常通过docker run -e HINDSIGHT_DB_PATH/app/data.db ...传入配置这比挂载.env文件更可靠、更符合容器最佳实践。但在本地开发时手动设置环境变量又很麻烦。因此Hindsight 提供了一个“开发友好开关”from hindsight import init_hindsight # 在应用启动时调用 init_hindsight( db_path./data/hindsight.db, log_levelDEBUG, capture_headersTrue )当显式调用init_hindsight()时它会覆盖所有环境变量和.env设置完全以代码参数为准。这是推荐的本地开发模式确保配置意图绝对明确。3.3track_llm_call的高级用法不只是记录更是验证track_llm_call最基础的用法是包裹调用但它的真正威力在于context 注入和 schema 验证。例如一个典型的 RAG 场景from hindsight import track_llm_call def rag_query(user_query: str, user_id: str): # 1. 从向量库检索相关文档 retrieved_docs vector_db.search(user_query, top_k3) # 2. 构建 prompt prompt f你是一个专业客服助手。请基于以下资料回答用户问题不要编造信息。 资料 {retrieved_docs} 用户问题{user_query} # 3. 调用 LLM with track_llm_call( provideropenai, modelgpt-4-turbo, messages[{role: user, content: prompt}], # 关键注入业务 context context{ user_id: user_id, retrieved_doc_count: len(retrieved_docs), rag_version: v2.1 }, # 关键启用 OpenAI Schema 验证 validate_openai_schemaTrue ) as tracker: response openai.ChatCompletion.create( modelgpt-4-turbo, messages[{role: user, content: prompt}] ) return response.choices[0].message.contentvalidate_openai_schemaTrue这个参数会触发 Hindsight 在发送请求前对messages、tools、tool_choice等字段进行严格校验。它会检查messages中每个content的长度是否超过模型的max_context_length例如gpt-4-turbo是 128K tokens但实际计算需考虑 system prompt、tools 等开销tools数组中每个 tool 的function.parameters是否是合法的 JSON Schema不能是空对象{}不能有$ref引用tool_choice的值是否在auto、none、{type: function, function: {name: xxx}}三者之中。一旦发现违规Hindsight 会在 request 发出前就抛出HindsightValidationError并给出清晰的错误信息例如HindsightValidationError: Invalid OpenAI tool schema at index 1. Field function.parameters must be a non-empty JSON Schema object. Got: {} Expected: {type: object, properties: {...}}这比等到 OpenAI 返回400 provider rejected the request schema再去 debug效率提升至少 10 倍。因为错误发生在你的本地机器上stack trace 直接指向你构建tools的那行代码而不是一个模糊的 HTTP 400。3.4 Docker 部署实战绕过virtualization support not detected的终极方案很多 Windows 用户在安装 Docker Desktop 时会遇到virtualization support not detected错误根源是 BIOS 中的 VT-x/AMD-V 虚拟化未开启或 Hyper-V 与 WSL2 冲突。Hindsight 的 Docker Compose 方案其实提供了两种完全绕过此问题的部署路径路径一纯 WSL2 模式推荐不安装 Docker Desktop只安装 WSL2Windows Subsystem for Linux和 Docker CLI for Windows。步骤如下在 PowerShell 中以管理员身份运行wsl --install重启后打开 Ubuntu WSL2运行sudo apt update sudo apt install docker.io在 Windows 的 CMD 或 PowerShell 中docker命令会自动代理到 WSL2 的 daemon无需 Docker Desktop。此时你的docker-compose.yml可以直接运行version: 3.8 services: hindsight-db: image: sqlite3:latest volumes: - ./data:/data command: tail -f /dev/null hindsight-api: build: . ports: - 8000:8000 environment: - HINDSIGHT_DB_PATH/data/hindsight.db depends_on: - hindsight-db路径二Docker-in-Docker (DinD) 模式企业级如果必须用 Docker Desktop且 BIOS 无法开启虚拟化可以启用 Docker 的dindDocker in Docker模式。这需要修改docker-compose.ymlservices: hindsight-api: image: docker:dind privileged: true volumes: - /var/run/docker.sock:/var/run/docker.sock command: dockerd-entrypoint.sh --hostunix:///var/run/docker.sock但这会显著增加资源占用仅建议在 CI/CD 流水线中使用。实操心得我在一个医疗 SaaS 客户现场他们的开发机全是禁用 BIOS 虚拟化的 Dell OptiPlexDocker Desktop 安装失败率 100%。我们最终采用 WSL2 Docker CLI 方案整个团队在 1 小时内完成 Hindsight 部署比他们原计划用 Kubernetes 部署一个监控服务的时间还短。关键不是技术多炫酷而是选对了与现实妥协的路径。4. 实操过程与核心环节实现一次完整的故障排查复盘让我们通过一个真实的、高频发生的故障案例完整走一遍 Hindsight 的实操流程。这个案例来自一个正在上线的“公立医院债务风险预警系统”其技术栈是Python FastAPI Dify用于 workflow 编排 OpenAI API。4.1 故障现象unexpected status 401 unauthorized: incorrect api key provided: sk-svcac****系统在测试环境一切正常但上线到生产环境后所有 LLM 调用均返回API Error: 401 Unauthorized: incorrect api key provided: sk-svcac****团队的第一反应是检查OPENAI_API_KEY环境变量。确认无误后开始怀疑是 Dify 的配置问题或是 Nginx 网关做了 header 过滤。排查持续了 3 小时无果。4.2 Hindsight 介入5 分钟定位根因我们在 Dify 的自定义 Python node 中加入了 Hindsight 的追踪from hindsight import track_llm_call def analyze_debt_risk(debt_data: dict): # 构建 prompt... prompt build_prompt(debt_data) with track_llm_call( provideropenai, modelgpt-4-turbo, messages[{role: user, content: prompt}], context{module: debt_risk_analyzer} ) as tracker: # 调用 OpenAI response openai.ChatCompletion.create( modelgpt-4-turbo, messages[{role: user, content: prompt}] ) return response.choices[0].message.content部署新版本后触发一次失败请求。我们立即执行# 查看最新失败记录 hindsight-cli list --status failed --limit 1输出关键字段ID: 42 Status: failed Provider: openai Model: gpt-4-turbo Error: 401 Unauthorized: incorrect api key provided: sk-svcac**** Request Headers: {Authorization: Bearer sk-svcac****, Content-Type: application/json} Request Body: {model: gpt-4-turbo, messages: [...], temperature: 0.3} Created At: 2024-05-20T14:22:18.342Z注意Request Headers字段它显示Authorizationheader 的值确实是sk-svcac****。但 Hindsight 还记录了环境变量快照这是它区别于普通日志的关键Environment Snapshot: OPENAI_API_KEY: sk-prod-xxxxxx... (正确) HINDSIGHT_ENV: production DIFY_ENV: productionOPENAI_API_KEY显示正确但Request Headers却是错的。这说明问题出在代码层的 key 注入逻辑而非环境变量。我们接着用 CLI 导出这条记录的完整上下文hindsight-cli export 42 --format json debug_401.json打开debug_401.json在request字段下我们看到了真相{ headers: { Authorization: Bearer sk-svcac**** }, body: { model: gpt-4-turbo, messages: [...], temperature: 0.3 } }但更关键的是在context字段里我们发现了线索context: { module: debt_risk_analyzer, key_source: dify_config }key_source是我们自己注入的 context表明这个 key 不是从OPENAI_API_KEY环境变量读取的而是从 Dify 的配置中心获取的。我们立刻检查 Dify 的配置项发现其openai_api_key字段被错误地设置为了一个测试环境的旧 keysk-svcac...而生产环境的配置同步脚本漏掉了这一项。4.3 根本原因与修复一次配置漂移的代价问题根源是配置漂移Configuration DriftDify 的配置中心里生产环境的 OpenAI Key 仍指向测试环境的旧 key。这个错误之所以没被发现是因为测试环境的 key 有效期长且未被 OpenAI 主动吊销Dify 的 UI 配置界面没有“环境隔离”提示管理员在测试环境修改后忘记同步到生产没有自动化配置校验导致错误配置在上线前未被拦截。修复方案极其简单登录 Dify 后台将生产环境的openai_api_key更新为正确的sk-prod-xxxxxx并添加一条 CI 流水线规则每次部署前自动比对测试/生产环境的 key 配置若不一致则阻断发布。4.4 Hindsight 的延伸价值从故障定位到质量基线这次故障排查完成后Hindsight 的价值并未结束。我们利用它沉淀了两条质量基线基线一API Key 合规性检查我们编写了一个简单的脚本每天凌晨扫描hindsight.db统计所有401错误并按key_prefix分组SELECT SUBSTR(error, 42, 8) as key_prefix, COUNT(*) as count FROM calls WHERE error LIKE 401% GROUP BY key_prefix ORDER BY count DESC;结果发现除了sk-svcac还有sk-legacy、sk-test等前缀频繁出现。这暴露了团队 API Key 管理的混乱开发、测试、生产混用且缺乏轮换机制。我们据此推动建立了 Key Lifecycle Management 规范。基线二Context Length 预警我们注意到gpt-4-turbo的400 context length exceeded错误90% 都发生在retrieved_doc_count 5的 RAG 查询中。Hindsight 的request.body.messages字段让我们能精确计算每次请求的 token 估算值使用tiktoken库。我们设置了阈值告警当估算 token 100K 时自动在 Slack 发送 warning并附上retrieved_docs的长度和内容摘要提醒产品经理优化召回策略。实操心得Hindsight 最大的价值不是帮你修好一个 bug而是让你看清“bug 的分布规律”。一个孤立的 401 是配置错误一百个不同前缀的 401 就是治理缺失一个偶然的 400 是 prompt 写错了连续一周的 400 就是架构瓶颈。它把模糊的“感觉有问题”变成了可量化、可追踪、可归因的数据事实。5. 常见问题与排查技巧实录那些文档里不会写的坑Hindsight 的文档简洁明了但真实世界永远比文档复杂。以下是我在过去半年中从用户反馈和自身实践中整理出的 7 个高频问题及独家排查技巧。这些问题99% 的新手都会遇到但 90% 的文档都避而不谈。5.1 问题hindsight-cli命令不存在pip install后仍报错command not found现象pip install hindsight-llm成功但执行hindsight-cli list时提示command not found。根因Python 的bin目录未加入系统PATH。在 macOS/Linux 上通常是~/Library/Python/3.x/binmacOS或~/.local/binLinux在 Windows 上是%USERPROFILE%\AppData\Roaming\Python\Python3x\Scripts。排查技巧运行python -m pip show hindsight-llm找到Location:字段例如/Users/xxx/Library/Python/3.11/lib/python/site-packages。对应的Scripts目录就是 CLI 可执行文件所在位置/Users/xxx/Library/Python/3.11/bin。将该路径加入PATH在~/.zshrcmacOS或~/.bashrcLinux中添加export PATH$HOME/Library/Python/3.11/bin:$PATH然后source ~/.zshrc。注意不要用sudo pip install这会把 CLI 安装到系统 Python 的/usr/local/bin可能导致权限问题。始终用用户级安装。5.2 问题Docker 部署后hindsight-api服务启动失败日志显示sqlite3.OperationalError: unable to open database file现象docker-compose up后hindsight-api容器反复重启日志报错无法打开数据库文件。根因Docker 容器内的用户通常是root或nobody对挂载的宿主机目录./data没有写入权限。尤其在 macOS 上Docker Desktop 的文件共享机制有时会丢失权限位。排查技巧先在宿主机上创建目录并赋予权限mkdir -p ./data chmod 777 ./data开发环境可接受生产环境用更细粒度权限。在docker-compose.yml中显式指定用户 IDuser: 1001:1001与宿主机用户 UID/GID 一致。更彻底的方案在Dockerfile中RUN chown -R 1001:1001 /app/data并在docker-compose.yml中volumes挂载时指定:zSELinux或:rw读写。5.3 问题track_llm_call包裹后程序性能明显下降CPU 占用飙升现象加入 Hindsight 追踪后API 响应时间从 200ms 增加到 1.2s服务器 CPU 使用率从 30% 涨到 90%。根因Hindsight 默认启用了capture_full_response_bodyTrue对于大模型返回的长文本如 10K 字符的报告它会将整个response.choices[0].message.content字符串序列化并写入 SQLite。SQLite 的写入是同步阻塞的大量长文本写入会拖慢主线程。排查技巧方案一推荐关闭全文捕获只记录关键字段with track_llm_call( provideropenai, modelgpt-4-turbo, messages[...], capture_full_response_bodyFalse, # 关键开关 capture_token_usageTrue # 但保留 token 统计 ) as tracker: ...方案二异步写入。Hindsight 支持async_modeTrue它会将日志写入队列由后台线程处理from hindsight import init_hindsight init_hindsight(async_modeTrue) # 全局启用异步5.4 问题validate_openai_schemaTrue报错Invalid JSON Schema: type is a required property但我的parameters明明写了type: object现象tools中的某个 function 的parameters是{type: object, properties: {query: {type: string}}}但 Hindsight 仍报错。根因OpenAI 的 Schema 验证比 JSON Schema 标准更严格。它要求properties对象不能为空且每个 property 必须有description字段即使为空字符串。这是 OpenAI 的隐式要求文档未明确说明。排查技巧正确写法{ type: object, properties: { query: { type: string, description: 用户查询的关键词 } }, required: [query] }Hindsight 的错误信息会精确指出缺失的字段但你需要知道 OpenAI 的这个“潜规则”。5.5 问题在 FastAPI 的BackgroundTasks中使用track_llm_call日志丢失或乱序现象将 LLM 调用放入BackgroundTasks.add_task()Hindsight 日志要么不出现要么时间戳错乱。根因BackgroundTasks在 FastAPI 中是协程而 Hindsight 的默认模式是同步的。track_llm_call的上下文管理器withblock在协程中无法正确捕获异步生命周期。排查技巧方案一推荐改用 Hindsight 的异步版本from hindsight.asyncio import track_llm_call_async async def background_task(): async with track_llm_call_async( provideropenai, modelgpt-4-turbo, messages[...] ) as tracker: response await openai.ChatCompletion.acreate(...)方案二避免在 BackgroundTasks 中做关键 LLM 调用改为在主请求中完成BackgroundTasks 只做非关键的后续处理如日志归档、通知发送。5.6 问题hindsight-cli replay重放请求但返回400 Bad Request而原始请求是成功的现象用 CLI 重放一条成功的请求却得到 400 错误。根因重放时Hindsight 会复原原始请求的headers和body但某些 provider如 OpenAI的 API Key 有时效性或绑定 IP。原始请求的 Key 可能是短期有效的或绑定了发起请求的服务器 IP而 CLI 重放时Key 已过期或 IP 不匹配。排查技巧重放前先检查request.headers.Authorization是否仍是有效 Key。如果不是手动更新 CLI 的环境变量OPENAI_API_KEYsk-new-xxx hindsight-cli replay 42。更安全的做法重放
返回列表