本文档与当前代码实现一致,描述 finrep-algo-agent(FastAPI)对外暴露的全部 HTTP 接口。
finrep-algo-agent(见 finrep_algo_agent.main:app)0.1.0(见 finrep_algo_agent.__version__)GET /openapi.json;交互式文档 GET /docs(Swagger UI)默认本地启动示例(端口以实际为准,README 中为 8002):
http://127.0.0.1:8002
所有配置以 FINREP_ 为前缀,可由环境变量或 algo/.env 注入(见 config/settings.py)。
与接口行为相关的常用项:
| 变量 | 说明 |
|---|---|
FINREP_STUB_SKILLS |
true 时:/v1/outline/*、/v1/section 不调用 LLM,返回占位数据;false 时走真实模型 |
FINREP_LLM_API_KEY |
文本生成密钥;Embedding 未单独配置时会回退使用该密钥 |
FINREP_LLM_BASE_URL / FINREP_LLM_MODEL / FINREP_LLM_TIMEOUT_SECONDS |
文本模型网关 |
FINREP_EMBEDDING_API_KEY |
向量模型密钥(可空,回退 FINREP_LLM_API_KEY) |
FINREP_EMBEDDING_BASE_URL / FINREP_EMBEDDING_MODEL / FINREP_EMBEDDING_TIMEOUT_SECONDS |
向量模型 |
FINREP_OCR_API_KEY |
OCR 密钥(可空,回退 FINREP_LLM_API_KEY) |
FINREP_OCR_BASE_URL / FINREP_OCR_MODEL / FINREP_OCR_TIMEOUT_SECONDS |
OCR 模型 |
FINREP_RAG_CHUNK_SIZE |
RAG 分块字符数近似上限 |
FINREP_RAG_CHUNK_OVERLAP |
分块重叠字符数 |
FINREP_RAG_DEFAULT_TOP_K |
检索默认 top_k(请求未传 top_k 时使用) |
FINREP_RAG_EMBEDDING_BATCH_SIZE |
单次向量化批大小 |
FINREP_SERVICE_TOKEN 已在配置中预留,当前路由层未做统一鉴权校验;若需服务间鉴权,由网关或后续中间件实现。
RAG 索引使用进程内 InMemoryRagStore(按 task_id 隔离)。服务重启后数据清空;多 Worker 各进程索引不共享。
Content-Type: application/jsonmultipart/form-data(见 /v1/rag/ingest-files)| 状态码 | 场景 |
|---|---|
| 200 | 成功 |
| 400 | 配置缺失(如未配置密钥) |
| 422 | 请求体验证失败,或业务侧 ValueError(大纲/段落技能、RAG 参数等) |
| 502 | RAG 向量化或检索过程中未捕获的下游异常,包装为业务可读 detail |
| 方法 | 路径 | 标签 / 说明 |
|---|---|---|
| GET | /health |
健康检查 |
| GET | /debug/runtime |
当前运行配置快照(非敏感) |
| GET | /debug/llm |
探测 LLM 连通性 |
| GET | /debug/embedding |
探测 Embedding 连通性 |
| GET | /debug/ocr |
探测 OCR(需 query image_url) |
| POST | /v1/outline/l1 |
一级大纲 |
| POST | /v1/outline/l2 |
二级 / 末级结构(单章) |
| POST | /v1/section |
单知识单元段落生成 |
| POST | /v1/rag/ingest-files |
上传文件 → 解析 → 分块 → 入库 |
| POST | /v1/rag/ingest |
纯文本文档入库 |
| POST | /v1/rag/retrieve |
向量相似度检索 |
| DELETE | /v1/rag/{task_id} |
删除某任务下 RAG 索引 |
GET /health响应体(application/json):
| 字段 | 类型 | 说明 |
|---|---|---|
status |
string | 固定为 ok |
service |
string | 固定为 finrep-algo-agent |
version |
string | 包版本,如 0.1.0 |
示例:{"status":"ok","service":"finrep-algo-agent","version":"0.1.0"}
GET /debug/runtime返回当前有效配置摘要(不含 API Key)。
| 字段 | 类型 | 说明 |
|---|---|---|
stub_skills |
boolean | 是否占位技能模式 |
llm_model |
string | 文本模型名 |
embedding_model |
string | 向量模型名 |
ocr_model |
string | OCR 模型名 |
rag_defaults |
object | chunk_size、chunk_overlap、top_k、embedding_batch_size |
GET /debug/llm调用一次短对话,验证 FINREP_LLM_API_KEY 与网关可用。
FINREP_LLM_API_KEY 未配置响应体:
| 字段 | 类型 | 说明 |
|---|---|---|
model |
string | 当前 LLM 模型名 |
base_url |
string | LLM base_url |
text_sample |
string | 模型回复截断至约 200 字符 |
GET /debug/embedding调用一次 Embedding,验证 FINREP_EMBEDDING_API_KEY 或 FINREP_LLM_API_KEY。
响应体:
| 字段 | 类型 | 说明 |
|---|---|---|
model |
string | 当前 embedding 模型名 |
base_url |
string | embedding base_url |
dim |
integer | 向量维度 |
head |
array | 向量前 8 维 |
GET /debug/ocrQuery 参数(必填):
| 参数 | 类型 | 说明 |
|---|---|---|
image_url |
string | 可公网或可访问的图片 URL |
验证 FINREP_OCR_API_KEY 或 FINREP_LLM_API_KEY。
响应体:
| 字段 | 类型 | 说明 |
|---|---|---|
model |
string | OCR 模型名 |
base_url |
string | OCR base_url |
text_sample |
string | 识别文本截断至约 400 字符 |
POST /v1/outline/l1Content-Type:application/json
请求体:OutlineL1Request
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
report_type |
string | 是 | 报告类型,如「项目融资」「资产管理」「并购重组」 |
task_id |
string | 否 | 任务 ID |
tenant_id |
string | 否 | 租户 ID |
agreement_amount |
number / string | 否 | 协议金额(Decimal,JSON 中可用数字或字符串) |
enterprise_type |
string | 否 | 企业类型 |
group_business_segments |
string[] | 否 | 集团板块名称列表 |
industry_type |
string | 否 | 行业类型 |
has_independent_report |
boolean | 否 | 是否存在独立调查报告 |
independent_report_types |
string[] | 否 | 独立报告类型列表 |
candidate_financing_tools |
string[] | 否 | 拟分析融资工具 |
recommended_financing_tools |
string[] | 否 | 拟最终推荐融资工具 |
other_requirements |
string | 否 | 其他要求 |
chapter_candidates |
object[] | 否 | 一级章节候选;非空时覆盖模板内嵌候选。每项至少含 chapter_id、chapter_name;允许任意扩展字段(原样进入提示词) |
chapter_candidates 每项结构(ChapterCandidate):
| 字段 | 类型 | 说明 |
|---|---|---|
chapter_id |
string | 章节 ID(须与模型输出一致,不可改写) |
chapter_name |
string | 章节名称(同上) |
| (其他键) | 任意 | 扩展属性,如重要性、适用条件等 |
响应体:OutlineL1Response
| 字段 | 类型 | 说明 |
|---|---|---|
chapter_results |
array | 与候选 数量、顺序一致(若请求传了非空 chapter_candidates);每项见下表 |
overall_logic |
string | 全篇结构逻辑说明 |
chapter_results 每项(ChapterL1Result):
| 字段 | 类型 | 说明 |
|---|---|---|
chapter_id |
string | 须与输入候选一致 |
chapter_name |
string | 须与输入候选一致 |
presentation_enum |
string | S1 独立呈现 / S2 不呈现 |
paragraph_count_enum |
string | P0~P4;S2 必须为 P1;S1 不可为 P0(服务端校验) |
reason |
string | 判断理由 |
业务校验(非空 chapter_candidates 时,见 skills/outline_l1/outline_l1.py):
len(chapter_results) 必须等于 len(chapter_candidates)chapter_id、chapter_name 必须与对应候选完全一致FINREP_STUB_SKILLS=true:不请求 LLM,返回固定占位结构。
POST /v1/outline/l2Content-Type:application/json
一次请求只生成 一个一级章 下的末级结构;完整报告需对多个一级章分别调用并由编排方合并。
请求体:OutlineL2Request
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
chapter_name |
string | 是 | 一级章名称 |
chapter_no |
string | 是 | 一级章编号(展示/排序用) |
l1_chapter_id |
string | 否 | L1 的 chapter_id,用于模板分支匹配内置末级清单 |
chapter_paragraph_count_enum |
string | 否 | L1 该章 paragraph_count_enum |
chapter_presentation_enum |
string | 否 | L1 该章 presentation_enum(S1/S2) |
chapter_reason |
string | 否 | L1 该章 reason |
overall_logic |
string | 否 | L1 返回的 overall_logic |
leaf_chapter_candidates |
object[] | 否 | 末级候选覆盖列表;空则走模板内置分支 |
l1_task_snapshot |
object | 否 | 与 OutlineL1Request 同结构 的快照,用于拼报告背景 |
report_type |
string | 否 | 可与 l1_task_snapshot 二选一或同时提供 |
agreement_amount 等 |
同 L1 扁平字段 | 否 | 无 l1_task_snapshot 时可用于拼背景 |
l1_context |
object | 否 | 额外上下文 |
响应体:OutlineL2Response
| 字段 | 类型 | 说明 |
|---|---|---|
chapter_name |
string | 须与请求一致(真实模式下模型若不一致会 422) |
chapter_no |
string | 须与请求一致 |
chapter_structure |
array | 末级节点列表(ChapterStructureNode) |
structure_logic |
string | 结构逻辑说明 |
ChapterStructureNode:
| 字段 | 类型 | 说明 |
|---|---|---|
node_id |
string | 节点 ID |
node_name |
string | 节点名称 |
node_no |
string | 编号 |
node_level |
integer | 层级 |
parent_node_id |
string / null | 父节点 ID |
source_type |
string / null | 来源类型 |
source_candidate_name |
string / null | 候选名 |
is_selected |
boolean | 默认 true |
chapter_presentation_enum = S2 时的服务端约束:
chapter_structure 非空,抛出 ValueError → 422S2 会直接返回 空 chapter_structureFINREP_STUB_SKILLS=true:不请求 LLM;S1 返回占位节点,S2 返回空结构。
POST /v1/sectionContent-Type:application/json
请求体:SectionRequest
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
knowledge_unit_id |
string | 是 | 知识单元 ID |
template_type |
string | 是 | info / analysis / metric / judgment(非法值 → 422) |
task_id |
string | 否 | RAG 召回、task_id 隔离用 |
tenant_id |
string | 否 | 租户 ID |
report_type |
string | 否 | 报告类型 |
paragraph_logic |
string | 否 | 撰写逻辑 |
paragraph_position |
string | 否 | 段落定位 |
overall_logic |
string | 否 | 全篇逻辑 |
chapter_logic |
string | 否 | 章逻辑 |
task_input |
object | 否 | 任务级输入 |
data_package |
object | 否 | 数据包(召回结果会合并进来) |
example |
string | 否 | 示例 |
notes |
string | 否 | 备注 |
rag_recall |
boolean | 否 | 默认 false;true 时需 task_id 且已配置 embedding/llm key |
rag_query |
string | 否 | 召回查询;空则拼接 paragraph_position、paragraph_logic、knowledge_unit_id |
rag_top_k |
integer | 否 | 传给 RAG;空则使用服务默认 rag_default_top_k |
rag_min_score |
number | 否 | 相似度下限,低于则过滤 |
响应体:SectionResponse
| 字段 | 类型 | 说明 |
|---|---|---|
generated_text |
string | 生成正文 |
usage |
object | TokenUsage:prompt_tokens、completion_tokens(当前实现多为 0) |
rag_recall=true 时:先 retrieve,将结果写入 data_package["rag_recall"](含 query、hits、formatted_context),再渲染模板并调用 LLM。
FINREP_STUB_SKILLS=true:不请求 LLM,返回占位正文。
基路径:/v1/rag(路由前缀见 main.py)
入库与检索均需 FINREP_EMBEDDING_API_KEY 或 FINREP_LLM_API_KEY;否则对应接口 400。
POST /v1/rag/ingest-filesContent-Type:multipart/form-data
| 表单字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id |
string | 是 | 任务 ID,索引按任务隔离 |
replace |
boolean | 否 | 默认 true;true 时替换该任务已有块;false 时在原索引上追加 |
files |
file[] | 是 | 至少一个文件;支持常见文本及 PDF(见 rag/ingestion/file_extract.py) |
行为概要:逐文件读 bytes → 抽取文本 → 有文本的合并为 RagDocumentIn → 调用与 /ingest 相同的分块与向量化逻辑。
files 为空;或全部文件无有效文本响应体:RagIngestFilesResponse
| 字段 | 类型 | 说明 |
|---|---|---|
task_id |
string | 任务 ID |
document_count |
integer | 成功参与入库的文档数 |
chunk_count |
integer | 写入的向量块数量 |
files |
array | 每文件处理结果 RagFileProcessResult |
RagFileProcessResult:
| 字段 | 类型 | 说明 |
|---|---|---|
filename |
string | 文件名 |
doc_id |
string | 派生文档 ID |
characters |
integer | 抽取字符数 |
skipped |
boolean | 无有效文本时为 true |
warning |
string / null | 解析警告 |
POST /v1/rag/ingestContent-Type:application/json
请求体:RagIngestRequest
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id |
string | 是 | 任务 ID |
tenant_id |
string | 否 | 租户(预留) |
documents |
array | 是 | 至少 1 条 RagDocumentIn |
replace |
boolean | 否 | true 覆盖任务索引,false 追加 |
RagDocumentIn:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
doc_id |
string | 是 | 任务内文档唯一标识 |
title |
string | 否 | 标题 |
text |
string | 是 | 待切分全文 |
source_label |
string | 否 | 来源展示名 |
page_start |
integer | 否 | 起始页 |
page_end |
integer | 否 | 结束页 |
若所有文档切分后无块且 replace=true,仍会清空该任务索引并返回 chunk_count=0(见 RagService.ingest)。
响应体:RagIngestResponse
| 字段 | 类型 | 说明 |
|---|---|---|
task_id |
string | 任务 ID |
document_count |
integer | 文档条数 |
chunk_count |
integer | 块数量 |
POST /v1/rag/retrieveContent-Type:application/json
请求体:RagRetrieveRequest
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_id |
string | 是 | 任务 ID |
tenant_id |
string | 否 | 租户(预留) |
query |
string | 是 | 查询句,最小长度 1 |
top_k |
integer | 否 | 返回条数上限;未传时使用 FINREP_RAG_DEFAULT_TOP_K,且服务端会将 k 约束为 ≥1 |
min_score |
number | 否 | 最小相似度;未传则不过滤 |
响应体:RagRetrieveResponse
| 字段 | 类型 | 说明 |
|---|---|---|
hits |
array | RagHit 列表 |
formatted_context |
string | 拼接后的引用上下文文本 |
RagHit:
| 字段 | 类型 | 说明 |
|---|---|---|
chunk_id |
string | 块 ID |
text |
string | 块文本 |
score |
number | 余弦相似度 |
doc_id |
string | 文档 ID |
title |
string | 标题 |
source_label |
string | 来源 |
chunk_index |
integer | 块序号 |
page_start / page_end |
integer / null | 页码 |
extra |
object | 扩展 |
任务无索引时返回 空 hits 与空的 formatted_context(不报错)。
502:检索或 embedding 异常。
DELETE /v1/rag/{task_id}路径参数:task_id — 要删除索引的任务 ID。
响应体:RagDeleteResponse
| 字段 | 类型 | 说明 |
|---|---|---|
task_id |
string | 与路径一致 |
deleted |
boolean | 删除前该任务是否已有块;无数据时为 false |
若接口或 Schema 发生变更,请同步更新:
algo/docs/API.md/openapi.json 为准(由 FastAPI 自 Pydantic 模型生成)